Skip to content

Commit d72e501

Browse files
committed
Merge branch 'master' into leo/refactor-storage-collections-for-an
2 parents 208fb81 + 3ef1eed commit d72e501

File tree

361 files changed

+12215
-4260
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

361 files changed

+12215
-4260
lines changed

.github/workflows/flaky-test-monitor.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ jobs:
5555
matrix:
5656
targets: ${{ fromJSON(needs.create-dynamic-test-matrix.outputs.dynamic-matrix)}}
5757
# need to set image explicitly due to GitHub logging issue as described in https://github.com/onflow/flow-go/pull/3087#issuecomment-1234383202
58-
runs-on: ubuntu-20.04
58+
runs-on: ubuntu-latest
5959
steps:
6060
- name: Checkout repo
6161
uses: actions/checkout@v4

access/api.go

+11-4
Original file line numberDiff line numberDiff line change
@@ -314,10 +314,17 @@ type CompatibleRange struct {
314314

315315
// NodeVersionInfo contains information about node, such as semver, commit, sporkID, protocolVersion, etc
316316
type NodeVersionInfo struct {
317-
Semver string
318-
Commit string
319-
SporkId flow.Identifier
320-
ProtocolVersion uint64
317+
Semver string
318+
Commit string
319+
SporkId flow.Identifier
320+
// ProtocolVersion is the deprecated protocol version number.
321+
// Deprecated: Previously this referred to the major software version as of the most recent spork.
322+
// Replaced by protocol_state_version.
323+
ProtocolVersion uint64
324+
// ProtocolStateVersion is the Protocol State version as of the latest finalized block.
325+
// This tracks the schema version of the Protocol State and is used to coordinate breaking changes in the Protocol.
326+
// Version numbers are monotonically increasing.
327+
ProtocolStateVersion uint64
321328
SporkRootBlockHeight uint64
322329
NodeRootBlockHeight uint64
323330
CompatibleRange *CompatibleRange

access/handler.go

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ func (h *Handler) GetNodeVersionInfo(
9898
Commit: nodeVersionInfo.Commit,
9999
SporkId: nodeVersionInfo.SporkId[:],
100100
ProtocolVersion: nodeVersionInfo.ProtocolVersion,
101+
ProtocolStateVersion: nodeVersionInfo.ProtocolStateVersion,
101102
SporkRootBlockHeight: nodeVersionInfo.SporkRootBlockHeight,
102103
NodeRootBlockHeight: nodeVersionInfo.NodeRootBlockHeight,
103104
CompatibleRange: CompatibleRangeToMessage(nodeVersionInfo.CompatibleRange),

admin/README.md

+5
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,8 @@ curl localhost:9002/admin/run_command -H 'Content-Type: application/json' -d '{"
120120
```
121121
curl localhost:9002/admin/run_command -H 'Content-Type: application/json' -d '{"commandName": "backfill-tx-error-messages", "data": { "start-height": 340, "end-height": 343, "execution-node-ids":["ec7b934df29248d574ae1cc33ae77f22f0fcf96a79e009224c46374d1837824e", "8cbdc8d24a28899a33140cb68d4146cd6f2f6c18c57f54c299f26351d126919e"] }}'
122122
```
123+
124+
### Trigger chunk data pack pebble database checkpoint
125+
```
126+
curl localhost:9002/admin/run_command -H 'Content-Type: application/json' -d '{"commandName": "create-chunk-data-packs-checkpoint" }'
127+
```

admin/commands/storage/backfill_tx_error_messages.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"github.com/onflow/flow-go/admin"
88
"github.com/onflow/flow-go/admin/commands"
99
"github.com/onflow/flow-go/engine/access/ingestion/tx_error_messages"
10-
commonrpc "github.com/onflow/flow-go/engine/common/rpc"
1110
"github.com/onflow/flow-go/model/flow"
1211
"github.com/onflow/flow-go/model/flow/filter"
1312
"github.com/onflow/flow-go/state/protocol"
@@ -177,7 +176,7 @@ func (b *BackfillTxErrorMessagesCommand) parseExecutionNodeIds(executionNodeIdsI
177176
if len(executionNodeIds) == 0 {
178177
return nil, admin.NewInvalidAdminReqParameterError("execution-node-ids", "must be a non empty list of strings", executionNodeIdsIn)
179178
}
180-
requestedENIdentifiers, err := commonrpc.IdentifierList(executionNodeIds)
179+
requestedENIdentifiers, err := flow.IdentifierListFromHex(executionNodeIds)
181180
if err != nil {
182181
return nil, admin.NewInvalidAdminReqParameterError("execution-node-ids", err.Error(), executionNodeIdsIn)
183182
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package storage
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"path"
7+
"time"
8+
9+
"github.com/cockroachdb/pebble"
10+
"github.com/rs/zerolog/log"
11+
12+
"github.com/onflow/flow-go/admin"
13+
"github.com/onflow/flow-go/admin/commands"
14+
)
15+
16+
var _ commands.AdminCommand = (*ChunksCheckpointCommand)(nil)
17+
18+
// ChunksCheckpointCommand creates a checkpoint for pebble database for querying the data
19+
// while keeping the node alive.
20+
type ChunksCheckpointCommand struct {
21+
checkpointDir string
22+
chunkDataPacks *pebble.DB
23+
}
24+
25+
func NewChunksCheckpointCommand(dir string, chunkDataPacks *pebble.DB) commands.AdminCommand {
26+
return &ChunksCheckpointCommand{
27+
checkpointDir: dir,
28+
chunkDataPacks: chunkDataPacks,
29+
}
30+
}
31+
32+
func (c *ChunksCheckpointCommand) Handler(ctx context.Context, req *admin.CommandRequest) (interface{}, error) {
33+
log.Info().Msgf("admintool: creating chunkDataPacks database checkpoint")
34+
35+
targetDir := nextTmpFolder(c.checkpointDir)
36+
37+
log.Info().Msgf("admintool: creating chunkDataPacks database checkpoint at: %v", targetDir)
38+
39+
err := c.chunkDataPacks.Checkpoint(targetDir)
40+
if err != nil {
41+
return nil, admin.NewInvalidAdminReqErrorf("failed to create checkpoint at %v: %w", targetDir, err)
42+
}
43+
44+
log.Info().Msgf("admintool: successfully created chunkDataPacks database checkpoint at: %v", targetDir)
45+
46+
return fmt.Sprintf("successfully created chunkDataPacks db checkpoint at %v", targetDir), nil
47+
}
48+
49+
func (c *ChunksCheckpointCommand) Validator(req *admin.CommandRequest) error {
50+
return nil
51+
}
52+
53+
func nextTmpFolder(dir string) string {
54+
// use timestamp as folder name
55+
folderName := time.Now().Format("2006-01-02_15-04-05")
56+
return path.Join(dir, folderName)
57+
}

cmd/access/node_builder/access_node_builder.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -2020,12 +2020,12 @@ func (builder *FlowAccessNodeBuilder) Build() (cmd.Node, error) {
20202020

20212021
}
20222022

2023-
preferredENIdentifiers, err := commonrpc.IdentifierList(backendConfig.PreferredExecutionNodeIDs)
2023+
preferredENIdentifiers, err := flow.IdentifierListFromHex(backendConfig.PreferredExecutionNodeIDs)
20242024
if err != nil {
20252025
return nil, fmt.Errorf("failed to convert node id string to Flow Identifier for preferred EN map: %w", err)
20262026
}
20272027

2028-
fixedENIdentifiers, err := commonrpc.IdentifierList(backendConfig.FixedExecutionNodeIDs)
2028+
fixedENIdentifiers, err := flow.IdentifierListFromHex(backendConfig.FixedExecutionNodeIDs)
20292029
if err != nil {
20302030
return nil, fmt.Errorf("failed to convert node id string to Flow Identifier for fixed EN map: %w", err)
20312031
}

cmd/bootstrap/cmd/block.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ func constructRootEpochEvents(
4242
participants flow.IdentityList,
4343
assignments flow.AssignmentList,
4444
clusterQCs []*flow.QuorumCertificate,
45-
dkgData dkg.DKGData) (*flow.EpochSetup, *flow.EpochCommit) {
45+
dkgData dkg.ThresholdKeySet,
46+
dkgIndexMap flow.DKGIndexMap,
47+
) (*flow.EpochSetup, *flow.EpochCommit) {
48+
4649
epochSetup := &flow.EpochSetup{
4750
Counter: flagEpochCounter,
4851
FirstView: firstView,
@@ -77,6 +80,7 @@ func constructRootEpochEvents(
7780
ClusterQCs: flow.ClusterQCVoteDatasFromQCs(qcsWithSignerIDs),
7881
DKGGroupKey: dkgData.PubGroupKey,
7982
DKGParticipantKeys: dkgData.PubKeyShares,
83+
DKGIndexMap: dkgIndexMap,
8084
}
8185
return epochSetup, epochCommit
8286
}

cmd/bootstrap/cmd/dkg.go

+19-18
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,31 @@ import (
1010
model "github.com/onflow/flow-go/model/bootstrap"
1111
"github.com/onflow/flow-go/model/dkg"
1212
"github.com/onflow/flow-go/model/encodable"
13+
"github.com/onflow/flow-go/model/flow"
1314
"github.com/onflow/flow-go/state/protocol/inmem"
1415
)
1516

16-
func runBeaconKG(nodes []model.NodeInfo) dkg.DKGData {
17+
func runBeaconKG(nodes []model.NodeInfo) (dkg.ThresholdKeySet, flow.DKGIndexMap) {
1718
n := len(nodes)
18-
1919
log.Info().Msgf("read %v node infos for DKG", n)
2020

2121
log.Debug().Msgf("will run DKG")
22-
var dkgData dkg.DKGData
23-
var err error
24-
dkgData, err = bootstrapDKG.RandomBeaconKG(n, GenerateRandomSeed(crypto.KeyGenSeedMinLen))
22+
randomBeaconData, err := bootstrapDKG.RandomBeaconKG(n, GenerateRandomSeed(crypto.KeyGenSeedMinLen))
2523
if err != nil {
2624
log.Fatal().Err(err).Msg("error running DKG")
2725
}
2826
log.Info().Msgf("finished running DKG")
2927

30-
pubKeyShares := make([]encodable.RandomBeaconPubKey, 0, len(dkgData.PubKeyShares))
31-
for _, pubKey := range dkgData.PubKeyShares {
32-
pubKeyShares = append(pubKeyShares, encodable.RandomBeaconPubKey{PublicKey: pubKey})
33-
}
34-
35-
privKeyShares := make([]encodable.RandomBeaconPrivKey, 0, len(dkgData.PrivKeyShares))
36-
for i, privKey := range dkgData.PrivKeyShares {
28+
encodableParticipants := make([]inmem.ThresholdParticipant, 0, len(nodes))
29+
for i, privKey := range randomBeaconData.PrivKeyShares {
3730
nodeID := nodes[i].NodeID
3831

3932
encKey := encodable.RandomBeaconPrivKey{PrivateKey: privKey}
40-
privKeyShares = append(privKeyShares, encKey)
33+
encodableParticipants = append(encodableParticipants, inmem.ThresholdParticipant{
34+
PrivKeyShare: encKey,
35+
PubKeyShare: encodable.RandomBeaconPubKey{PublicKey: randomBeaconData.PubKeyShares[i]},
36+
NodeID: nodeID,
37+
})
4138

4239
err = common.WriteJSON(fmt.Sprintf(model.PathRandomBeaconPriv, nodeID), flagOutdir, encKey)
4340
if err != nil {
@@ -46,18 +43,22 @@ func runBeaconKG(nodes []model.NodeInfo) dkg.DKGData {
4643
log.Info().Msgf("wrote file %s/%s", flagOutdir, fmt.Sprintf(model.PathRandomBeaconPriv, nodeID))
4744
}
4845

46+
indexMap := make(flow.DKGIndexMap, len(nodes))
47+
for i, node := range nodes {
48+
indexMap[node.NodeID] = i
49+
}
50+
4951
// write full DKG info that will be used to construct QC
50-
err = common.WriteJSON(model.PathRootDKGData, flagOutdir, inmem.EncodableFullDKG{
52+
err = common.WriteJSON(model.PathRootDKGData, flagOutdir, inmem.ThresholdKeySet{
5153
GroupKey: encodable.RandomBeaconPubKey{
52-
PublicKey: dkgData.PubGroupKey,
54+
PublicKey: randomBeaconData.PubGroupKey,
5355
},
54-
PubKeyShares: pubKeyShares,
55-
PrivKeyShares: privKeyShares,
56+
Participants: encodableParticipants,
5657
})
5758
if err != nil {
5859
log.Fatal().Err(err).Msg("failed to write json")
5960
}
6061
log.Info().Msgf("wrote file %s/%s", flagOutdir, model.PathRootDKGData)
6162

62-
return dkgData
63+
return randomBeaconData, indexMap
6364
}

cmd/bootstrap/cmd/finalize.go

+14-16
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ func finalize(cmd *cobra.Command, args []string) {
152152
log.Info().Msgf("received votes total: %v", len(votes))
153153

154154
log.Info().Msg("reading dkg data")
155-
dkgData := readDKGData()
155+
dkgData, _ := readRandomBeaconKeys()
156156
log.Info().Msg("")
157157

158158
log.Info().Msg("reading intermediary bootstrapping data")
@@ -189,10 +189,9 @@ func finalize(cmd *cobra.Command, args []string) {
189189
result,
190190
seal,
191191
rootQC,
192-
intermediaryData.ProtocolVersion,
193192
func(epochStateID flow.Identifier) (protocol_state.KVStoreAPI, error) {
194193
return kvstore.NewDefaultKVStore(
195-
intermediaryData.EpochCommitSafetyThreshold,
194+
intermediaryData.FinalizationSafetyThreshold,
196195
intermediaryData.EpochExtensionViewCount,
197196
epochStateID)
198197
},
@@ -352,29 +351,28 @@ func readRootBlock() *flow.Block {
352351
return rootBlock
353352
}
354353

355-
// readDKGData reads DKG data from disc, this file needs to be prepared with
356-
// rootblock command
357-
func readDKGData() dkg.DKGData {
358-
encodableDKG, err := utils.ReadData[inmem.EncodableFullDKG](flagDKGDataPath)
354+
// readRandomBeaconKeys reads the threshold key data from disc.
355+
// This file needs to be prepared with rootblock command
356+
func readRandomBeaconKeys() (dkg.ThresholdKeySet, flow.DKGIndexMap) {
357+
encodableDKG, err := utils.ReadData[inmem.ThresholdKeySet](flagDKGDataPath)
359358
if err != nil {
360-
log.Fatal().Err(err).Msg("could not read DKG data")
359+
log.Fatal().Err(err).Msg("loading threshold key data for Random Beacon failed")
361360
}
362361

363-
dkgData := dkg.DKGData{
362+
dkgData := dkg.ThresholdKeySet{
364363
PrivKeyShares: nil,
365364
PubGroupKey: encodableDKG.GroupKey.PublicKey,
366365
PubKeyShares: nil,
367366
}
368367

369-
for _, pubKey := range encodableDKG.PubKeyShares {
370-
dkgData.PubKeyShares = append(dkgData.PubKeyShares, pubKey.PublicKey)
371-
}
372-
373-
for _, privKey := range encodableDKG.PrivKeyShares {
374-
dkgData.PrivKeyShares = append(dkgData.PrivKeyShares, privKey.PrivateKey)
368+
indexMap := make(flow.DKGIndexMap, len(encodableDKG.Participants))
369+
for i, participant := range encodableDKG.Participants {
370+
dkgData.PubKeyShares = append(dkgData.PubKeyShares, participant.PubKeyShare.PublicKey)
371+
dkgData.PrivKeyShares = append(dkgData.PrivKeyShares, participant.PrivKeyShare.PrivateKey)
372+
indexMap[participant.NodeID] = i
375373
}
376374

377-
return dkgData
375+
return dkgData, indexMap
378376
}
379377

380378
// Validation utility methods ------------------------------------------------

cmd/bootstrap/cmd/finalize_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func TestFinalize_HappyPath(t *testing.T) {
7474
flagNumViewsInEpoch = 100_000
7575
flagNumViewsInStakingAuction = 50_000
7676
flagNumViewsInDKGPhase = 2_000
77-
flagEpochCommitSafetyThreshold = 1_000
77+
flagFinalizationSafetyThreshold = 1_000
7878
flagEpochExtensionViewCount = 100_000
7979
flagUseDefaultEpochTargetEndTime = true
8080
flagEpochTimingRefCounter = 0

cmd/bootstrap/cmd/intermediary.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ type IntermediaryBootstrappingData struct {
1818
// like the root block).
1919
// This is used to pass data between the rootblock command and the finalize command.
2020
type IntermediaryParamsData struct {
21-
ProtocolVersion uint
22-
EpochCommitSafetyThreshold uint64
23-
EpochExtensionViewCount uint64
21+
FinalizationSafetyThreshold uint64
22+
EpochExtensionViewCount uint64
2423
}
2524

2625
// IntermediaryEpochData stores the root epoch and the epoch config for the execution state

cmd/bootstrap/cmd/qc.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ import (
1313
)
1414

1515
// constructRootQC constructs root QC based on root block, votes and dkg info
16-
func constructRootQC(block *flow.Block, votes []*model.Vote, allNodes, internalNodes []bootstrap.NodeInfo, dkgData dkg.DKGData) *flow.QuorumCertificate {
16+
func constructRootQC(block *flow.Block, votes []*model.Vote, allNodes, internalNodes []bootstrap.NodeInfo, randomBeaconData dkg.ThresholdKeySet) *flow.QuorumCertificate {
1717

1818
identities := bootstrap.ToIdentityList(allNodes)
19-
participantData, err := run.GenerateQCParticipantData(allNodes, internalNodes, dkgData)
19+
participantData, err := run.GenerateQCParticipantData(allNodes, internalNodes, randomBeaconData)
2020
if err != nil {
2121
log.Fatal().Err(err).Msg("failed to generate QC participant data")
2222
}
@@ -36,8 +36,8 @@ func constructRootQC(block *flow.Block, votes []*model.Vote, allNodes, internalN
3636
}
3737

3838
// NOTE: allNodes must be in the same order as when generating the DKG
39-
func constructRootVotes(block *flow.Block, allNodes, internalNodes []bootstrap.NodeInfo, dkgData dkg.DKGData) {
40-
participantData, err := run.GenerateQCParticipantData(allNodes, internalNodes, dkgData)
39+
func constructRootVotes(block *flow.Block, allNodes, internalNodes []bootstrap.NodeInfo, randomBeaconData dkg.ThresholdKeySet) {
40+
participantData, err := run.GenerateQCParticipantData(allNodes, internalNodes, randomBeaconData)
4141
if err != nil {
4242
log.Fatal().Err(err).Msg("failed to generate QC participant data")
4343
}

0 commit comments

Comments
 (0)