Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEATURE: Serializable Snapshots #209

Merged
merged 235 commits into from
Mar 16, 2021
Merged
Show file tree
Hide file tree
Changes from 222 commits
Commits
Show all changes
235 commits
Select commit Hold shift + click to select a range
f86eb20
add QuorumCertificate method to Snapshot
jordanschalm Dec 2, 2020
963cf20
update snapshot test
jordanschalm Dec 2, 2020
d797193
update snapshot tests for quorum certificate method
jordanschalm Dec 2, 2020
495e910
add serializable models for snapshot
jordanschalm Dec 2, 2020
807d325
Merge branch 'master' into jordan/4889-serializable-snapshot
jordanschalm Dec 2, 2020
b76ccdf
complete implementation of protocol interfaces
jordanschalm Dec 2, 2020
69e35da
add encodable models for protocol snapshot
jordanschalm Dec 3, 2020
516ba76
use encodable models as base of in-memory snapshot
jordanschalm Dec 3, 2020
19850e7
Merge branch 'feature/serializable-snapshots' into jordan/4889-qc-in-…
jordanschalm Dec 3, 2020
2286e8a
Merge branch 'jordan/4889-qc-in-snapshot' into jordan/4889-serializab…
jordanschalm Dec 3, 2020
410eee3
rename package to inmem
jordanschalm Dec 3, 2020
4a06296
godocs
jordanschalm Dec 3, 2020
fae3a2e
expose RandomSource in epoch
jordanschalm Dec 3, 2020
bc46fab
add conversion to in-memory snapshot
jordanschalm Dec 3, 2020
514332a
move encodable models to inmem package
jordanschalm Dec 3, 2020
2b57e06
add smoke test for snapshot conversion
jordanschalm Dec 3, 2020
4f9313e
add sentinel error for un-committed epochs
jordanschalm Dec 3, 2020
93521fa
mark blocks valid in epoch builder mock
jordanschalm Dec 3, 2020
0f60336
update mocks
jordanschalm Dec 3, 2020
540b023
improved snapshot conversion tests
jordanschalm Dec 3, 2020
615f0fc
Merge branch 'feature/serializable-snapshots' into jordan/4889-qc-in-…
jordanschalm Dec 3, 2020
45ba186
Merge branch 'jordan/4889-qc-in-snapshot' into jordan/4889-serializab…
jordanschalm Dec 3, 2020
11a2244
test qc view
jordanschalm Dec 3, 2020
56af544
Merge branch 'jordan/4889-qc-in-snapshot' into jordan/4889-serializab…
jordanschalm Dec 3, 2020
26c4cd8
move invalid types to invalid package
jordanschalm Dec 3, 2020
6ce812b
use inmem models for dkg/cluster
jordanschalm Dec 3, 2020
360c02b
make current epoch non-nullable in encodable model
jordanschalm Dec 3, 2020
7f38363
add sanity check for child when getting QC
jordanschalm Dec 4, 2020
8f5992e
improve QC godoc
jordanschalm Dec 4, 2020
f3ca5f1
compare to root block using ID rather than Height
jordanschalm Dec 4, 2020
8ebbb8c
include sentinel in godoc for validChild
jordanschalm Dec 4, 2020
a490ba8
check for sentinel error type in test
jordanschalm Dec 4, 2020
ff6f97c
remove unecessary check from validChild
jordanschalm Dec 4, 2020
baae1f4
Merge pull request #201 from onflow/jordan/4889-qc-in-snapshot
jordanschalm Dec 4, 2020
ffed878
Merge branch 'feature/serializable-snapshots' into jordan/4889-serial…
jordanschalm Dec 4, 2020
bfbacca
Merge branch 'feature/serializable-snapshots' of github.com:onflow/fl…
jordanschalm Dec 4, 2020
9f69385
Merge branch 'feature/serializable-snapshots' into jordan/4889-serial…
jordanschalm Dec 4, 2020
9009ba7
update error string wording
jordanschalm Dec 9, 2020
444c0d1
use NoError in epoch builder
jordanschalm Dec 9, 2020
50210b4
wrap all errors in snapshot conversion
jordanschalm Dec 9, 2020
fae28e5
use godoc convention for test functions
jordanschalm Dec 9, 2020
9d59fbb
use NoError over Nil in convert_test.go
jordanschalm Dec 9, 2020
4812a9c
update encodable type names
jordanschalm Dec 9, 2020
2c7c16c
use non-pointer receiver for inmem.Snapshot
jordanschalm Dec 9, 2020
1e3c5c3
Merge pull request #204 from onflow/jordan/4889-serializable-snapshot
jordanschalm Dec 9, 2020
3e4e1c1
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Dec 9, 2020
8a5ef1a
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Dec 10, 2020
5a8d06f
lint
jordanschalm Dec 10, 2020
d1e1acc
Merge branch 'master' into jordan/4890-bootstrap-from-snapshot
jordanschalm Jan 8, 2021
8471c3e
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Jan 8, 2021
8fabd62
Merge branch 'feature/serializable-snapshots' into jordan/4890-bootst…
jordanschalm Jan 8, 2021
7df4760
update inmem snapshot to use state root
jordanschalm Jan 9, 2021
e9c2991
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Jan 12, 2021
7683f7f
Merge branch 'feature/serializable-snapshots' into jordan/4890-bootst…
jordanschalm Jan 12, 2021
2695068
adds requirements for bootstrapping to protocol.Snapshot
jordanschalm Jan 12, 2021
41942bd
implement additional protocol methods
jordanschalm Jan 12, 2021
6860bcc
update invalid snapshot
jordanschalm Jan 12, 2021
20d4af1
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Jan 12, 2021
b6065d9
Merge branch 'feature/serializable-snapshots' into jordan/4890-bootst…
jordanschalm Jan 12, 2021
9d62ad5
update inmem snapshot with new methods
jordanschalm Jan 12, 2021
d07c8bc
add cluster.Assignments method
jordanschalm Jan 13, 2021
677209d
add previous epoch to epoch status
jordanschalm Jan 13, 2021
c914364
add conversion from protocol.Epoch to service event
jordanschalm Jan 13, 2021
5c950d6
update snapshot to use previous epoch instead of first block
jordanschalm Jan 13, 2021
d5e0b6d
bootstrap from protocol.Snapshot rather than state root
jordanschalm Jan 13, 2021
41d7eb8
update inmem conversion
jordanschalm Jan 14, 2021
615c266
add conversion from root bootstrap state to snapshot
jordanschalm Jan 14, 2021
3575454
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Jan 15, 2021
5ce6bb8
Merge branch 'feature/serializable-snapshots' into jordan/4890-bootst…
jordanschalm Jan 15, 2021
71af008
temporarily copy epoch model to inmem
jordanschalm Jan 15, 2021
1a53b6a
add PreviousEpochs to fixture
jordanschalm Jan 15, 2021
9a6022a
update cluster state tests
jordanschalm Jan 15, 2021
f247d36
update protocol state tests
jordanschalm Jan 15, 2021
dc150f4
add test for cluster assignment conversion
jordanschalm Jan 15, 2021
493f2ff
remove empty result.go file
jordanschalm Jan 15, 2021
21ba6f4
use root snapshot in scaffold
jordanschalm Jan 15, 2021
9717d7e
add docs for epoch bootstrapping
jordanschalm Jan 15, 2021
0f1fcc8
document setupEpoch/committedEpoch as conversion layer
jordanschalm Jan 15, 2021
7482af8
remove usages of badger.{Setup,Committed}Epoch
jordanschalm Jan 16, 2021
3e6ecc7
remove badger epoch models
jordanschalm Jan 16, 2021
6ec0a39
remove unused validate method
jordanschalm Jan 16, 2021
9bfc912
error handling and docs in service event <-> Epoch conversion
jordanschalm Jan 16, 2021
a439bd9
add godoc
jordanschalm Jan 20, 2021
a3ea0f0
review pt. 1 - code style
jordanschalm Jan 20, 2021
1d40ac5
Merge branch 'master' into jordan/4890-bootstrap-from-snapshot
jordanschalm Jan 20, 2021
f4e1578
add helper for traversing chain segment
jordanschalm Jan 21, 2021
de2ede9
update sealing segment to use traverse helper
jordanschalm Jan 21, 2021
bfcd24c
Merge pull request #272 from onflow/jordan/4890-bootstrap-from-snapshot
jordanschalm Jan 22, 2021
a97b7c3
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Jan 22, 2021
ae8d392
add results to state constructors
jordanschalm Jan 22, 2021
42f2be5
add root snapshot fixture
jordanschalm Jan 22, 2021
fd50104
make first view a standard field of EpochSetup
jordanschalm Jan 22, 2021
28af2af
use root snapshot in protocol test methods
jordanschalm Jan 22, 2021
ceaddd2
update scaffold with OpenState change
jordanschalm Jan 22, 2021
3a7c87a
update consensus tests
jordanschalm Jan 22, 2021
8fb84dd
update engine node testutil
jordanschalm Jan 22, 2021
0eceb7b
update collector builder
jordanschalm Jan 22, 2021
d45eff7
udpate cluster state tests
jordanschalm Jan 22, 2021
c620091
update inmem snapshot conversion
jordanschalm Jan 22, 2021
e3f7442
move validity tests to validity_test
jordanschalm Jan 22, 2021
e3595e5
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Feb 2, 2021
5b4caae
Merge branch 'feature/serializable-snapshots' into jordan/4890-bootst…
jordanschalm Feb 2, 2021
ad96884
update protocol/mutator tests
jordanschalm Feb 3, 2021
92d4b59
update validity tests pt 1
jordanschalm Feb 3, 2021
6188b0a
update validity test
jordanschalm Feb 4, 2021
ead8494
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Feb 4, 2021
6bc77e9
Merge branch 'feature/serializable-snapshots' into jordan/4890-bootst…
jordanschalm Feb 4, 2021
638e8d0
update validity tests
jordanschalm Feb 4, 2021
284eaac
update snapshot tests
jordanschalm Feb 4, 2021
66be8e9
add storage method for root qc
jordanschalm Feb 4, 2021
5cbc865
store root qc on bootstrap
jordanschalm Feb 4, 2021
1b6ffe4
remove epoch test
jordanschalm Feb 5, 2021
301936c
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Feb 5, 2021
e76faf8
Merge branch 'feature/serializable-snapshots' into jordan/4890-bootst…
jordanschalm Feb 5, 2021
42b80d4
set FirstView in root seal generated during bootstrapping
jordanschalm Feb 5, 2021
bbd9024
remove computing of FirstView field in mutator
jordanschalm Feb 5, 2021
6bac705
adjust checks of setup event views
jordanschalm Feb 5, 2021
f84d477
Add Access API endpoints and bump `onflow/flow` -> v0.1.9
danukumanan Feb 5, 2021
05a783f
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Feb 5, 2021
4e74762
Merge branch 'feature/serializable-snapshots' into jordan/4890-bootst…
jordanschalm Feb 5, 2021
0130321
use correct value for random source min length
jordanschalm Feb 5, 2021
eb919a6
check equality of random source
jordanschalm Feb 5, 2021
090a6a8
improve docs on sealing segment
jordanschalm Feb 5, 2021
b163ea9
use correct random source length in fixture
jordanschalm Feb 5, 2021
7f265ff
fix tests manually setting first view
jordanschalm Feb 5, 2021
b13d932
Merge branch 'jordan/4890-bootstrap-pt2' into jordan/4890-pt3
jordanschalm Feb 5, 2021
8b35d4e
add sealing segment tests for post-spork cases
jordanschalm Feb 5, 2021
f07b3a5
skeleton of seal/result tests
jordanschalm Feb 6, 2021
b0e28d7
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Feb 8, 2021
59a4fec
Merge branch 'feature/serializable-snapshots' into jordan/4890-bootst…
jordanschalm Feb 8, 2021
9dbcc39
Merge branch 'jordan/4890-bootstrap-pt2' into jordan/4890-pt3
jordanschalm Feb 8, 2021
33dd989
rename validity functions
jordanschalm Feb 8, 2021
962fa0d
Merge pull request #312 from onflow/jordan/4890-bootstrap-pt2
jordanschalm Feb 8, 2021
a0ee6dc
consolidate Latest seal and result in protocol.Snapshot
jordanschalm Feb 8, 2021
f26d672
update to SealedResult in Snapshot implementations
jordanschalm Feb 8, 2021
21e0956
update snapshot mock
jordanschalm Feb 8, 2021
795ced5
use new SealedResult API
jordanschalm Feb 8, 2021
59a4822
SealedResult tests
jordanschalm Feb 8, 2021
182a079
check root snapshot qc block ID
jordanschalm Feb 8, 2021
ddb5344
use correct random source in bootstrap/testnet
jordanschalm Feb 9, 2021
0109fc0
include receipts in sealing segment test
jordanschalm Feb 9, 2021
d081fdd
move bootstrap tests to state_test
jordanschalm Feb 9, 2021
b51930d
begin adding non-root bootstrapping
jordanschalm Feb 9, 2021
cdd40c2
fix bootstrapping
jordanschalm Feb 9, 2021
da89d0b
Add tests and move methods to convert
danukumanan Feb 9, 2021
fa567c6
Revert bump of flow-go-sdk
danukumanan Feb 9, 2021
300e1b2
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Feb 9, 2021
812ce6f
Merge branch 'feature/serializable-snapshots' into jordan/4890-pt3
jordanschalm Feb 9, 2021
c9322ca
generate clusters based on final participants
jordanschalm Feb 9, 2021
34b4e2f
bootstrapping tests
jordanschalm Feb 9, 2021
ddaa844
fix bug with converting clustering in setup epochs
jordanschalm Feb 9, 2021
8f4fe26
fix access/ingestion tests
jordanschalm Feb 9, 2021
bccdd6d
fix payload test to compare literal
jordanschalm Feb 9, 2021
e2a9396
return EpochBuilder for easier call chaining
jordanschalm Feb 9, 2021
02aaecc
avoid empty slices in encode/decode tests
jordanschalm Feb 10, 2021
a512cd2
explicitly add guarantees to mocked block
jordanschalm Feb 10, 2021
a583118
fix QC fixture
jordanschalm Feb 10, 2021
88f8709
add note on order to SealingSegment doc
jordanschalm Feb 10, 2021
a83b9a1
use valid qc in bootstrapping tests
jordanschalm Feb 10, 2021
73d83ba
refactor Bootstrap to use helper functions
jordanschalm Feb 10, 2021
5d2beee
tests for non-root snapshots
jordanschalm Feb 10, 2021
c7738bf
bad sealing segment, qc, seal/result test cases
jordanschalm Feb 10, 2021
b87ba77
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Feb 10, 2021
fd4938c
Merge branch 'feature/serializable-snapshots' into jordan/4890-pt3
jordanschalm Feb 10, 2021
9d23d1f
update service event -related models
jordanschalm Feb 10, 2021
98efc08
convert service events upon execution
jordanschalm Feb 10, 2021
49fdba6
temp
danukumanan Feb 11, 2021
d669734
Update engine/common/rpc/convert/convert.go
danukumanan Feb 11, 2021
63d39eb
Merge branch 'feature/serializable-snapshots' into danu/4891-access-a…
danukumanan Feb 11, 2021
791f768
Fix tests
danukumanan Feb 11, 2021
33f05ad
Merge pull request #377 from onflow/danu/4891-access-api-serializable…
jordanschalm Feb 11, 2021
d3c2af2
Apply suggestions from code review
jordanschalm Feb 25, 2021
301d10b
remove unneeded error check
jordanschalm Feb 25, 2021
fb13096
Merge pull request #374 from onflow/jordan/4890-pt3
jordanschalm Feb 25, 2021
d9728d9
[Transit] Download Protocol State Snapshot Command (#392)
danukumanan Feb 26, 2021
76d8c41
[Transit] Pull and Push Root Snapshot (#474)
danukumanan Mar 4, 2021
9c8a9ce
Remove Transit push RootSnapshotFile
danukumanan Mar 4, 2021
ccee8da
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Mar 5, 2021
f7ca833
Merge branch 'feature/serializable-snapshots' into jordan/4866-handle…
jordanschalm Mar 5, 2021
ec4ed9f
remove dupe method from merge
jordanschalm Mar 5, 2021
5f72d36
enforce consistent json marshalling for block payload
jordanschalm Mar 5, 2021
250055d
use the canonical ordering in unit test util
jordanschalm Mar 5, 2021
5997ca5
fix bootstrap test
jordanschalm Mar 5, 2021
26e3ee6
lint
jordanschalm Mar 5, 2021
5b61f8c
fix conversion function
jordanschalm Mar 5, 2021
f3c22aa
Merge branch 'feature/serializable-snapshots' into jordan/4866-handle…
jordanschalm Mar 5, 2021
8d41059
go mod tidy
jordanschalm Mar 5, 2021
f3dfffd
go mod tidy
jordanschalm Mar 5, 2021
0f2caf3
generate service events in root results in bootstrapping
jordanschalm Mar 5, 2021
308b090
update usage of service events in test utils
jordanschalm Mar 5, 2021
e7e9a77
update tests using Seal.WithServiceEvents
jordanschalm Mar 6, 2021
85e1ca3
update protocol/cluster tests
jordanschalm Mar 6, 2021
19bbd57
update integration tests
jordanschalm Mar 6, 2021
7fc94c0
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Mar 9, 2021
4180c94
Merge branch 'feature/serializable-snapshots' into jordan/4866-handle…
jordanschalm Mar 9, 2021
ba7b27d
check validity when querying protocol state
jordanschalm Mar 9, 2021
83dd6ad
add feature branch to CI
jordanschalm Mar 9, 2021
187255f
Merge branch 'feature/serializable-snapshots' into jordan/4866-handle…
jordanschalm Mar 9, 2021
b78c981
use result service events in finalizar
jordanschalm Mar 9, 2021
9c91dc2
apply service event when processing parent of sealing block
jordanschalm Mar 9, 2021
faeaf12
lint
jordanschalm Mar 9, 2021
16e4f13
revert requirement that blocks be marked valid for querying
jordanschalm Mar 11, 2021
f0cd379
revert addition of unvalidatedquery error
jordanschalm Mar 11, 2021
49ac03b
update epoch builder
jordanschalm Mar 11, 2021
de930a8
use correct result ID
jordanschalm Mar 11, 2021
da1ae76
use correct result id in cluster mutator test
jordanschalm Mar 11, 2021
764aa05
update full epoch transition test
jordanschalm Mar 11, 2021
aba506e
fix conflicting epoch tests
jordanschalm Mar 11, 2021
22ee465
use NoError over Nil
jordanschalm Mar 11, 2021
e0977e3
fix invalid epoch setup tests
jordanschalm Mar 12, 2021
93ea3f4
fix invalid epoch commit tests
jordanschalm Mar 12, 2021
9454b46
fix TestClusters
jordanschalm Mar 12, 2021
a9d2b0e
fix epoch query tests
jordanschalm Mar 12, 2021
63fb60c
fix first view test
jordanschalm Mar 12, 2021
0c0b206
fix cross-epoch identities test
jordanschalm Mar 12, 2021
6be784d
fix Sealed test
jordanschalm Mar 12, 2021
132e243
allow duplicate service events
jordanschalm Mar 12, 2021
9e5bdaa
add test for conflicting, duplicate service events
jordanschalm Mar 12, 2021
e7ea4fd
fix comment
jordanschalm Mar 15, 2021
933295e
Merge pull request #399 from onflow/jordan/4866-handle-service-events
jordanschalm Mar 15, 2021
5f82a42
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Mar 16, 2021
684642b
Finalize command now writes only the root protocol state snapshot
danukumanan Feb 18, 2021
0ddcddb
Change scaffold to read directly from snapshot
danukumanan Feb 25, 2021
d11a181
Fix linting error and update localnet/integration to use root procoto…
danukumanan Feb 25, 2021
9b6bc74
write encodable struct to file
jordanschalm Mar 16, 2021
681dd73
populate NodeBuilder from root snapshot
jordanschalm Mar 16, 2021
e0ad314
go mod tidy
jordanschalm Mar 16, 2021
7e70fa4
go mod tidy
jordanschalm Mar 16, 2021
1844ba8
go mod tidy
jordanschalm Mar 16, 2021
ecd894e
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Mar 16, 2021
c13cb55
use last block of sealing segment as root
jordanschalm Mar 16, 2021
75c78f0
Merge pull request #527 from onflow/jordan/5286-bootstrap-snapshot
jordanschalm Mar 16, 2021
f595307
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Mar 16, 2021
89eae5d
remove this feature branch from CI prior to merge
jordanschalm Mar 16, 2021
bda7a57
Merge branch 'master' into feature/serializable-snapshots
jordanschalm Mar 16, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ on:
push:
branches:
- master
- feature/serializable-snapshots
pull_request:
branches:
- master
- feature/serializable-snapshots

jobs:
golangci:
Expand Down
2 changes: 2 additions & 0 deletions access/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ type API interface {

GetEventsForHeightRange(ctx context.Context, eventType string, startHeight, endHeight uint64) ([]flow.BlockEvents, error)
GetEventsForBlockIDs(ctx context.Context, eventType string, blockIDs []flow.Identifier) ([]flow.BlockEvents, error)

GetLatestProtocolStateSnapshot(ctx context.Context) ([]byte, error)
}

// TODO: Combine this with flow.TransactionResult?
Expand Down
18 changes: 12 additions & 6 deletions access/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package access

import (
"context"
"fmt"

"github.com/golang/protobuf/ptypes"
"github.com/onflow/flow/protobuf/go/flow/access"
Expand Down Expand Up @@ -36,11 +35,6 @@ func (h *Handler) Ping(ctx context.Context, _ *access.PingRequest) (*access.Ping
return &access.PingResponse{}, nil
}

func (h *Handler) GetLatestProtocolStateSnapshot(_ context.Context,
_ *access.GetLatestProtocolStateSnapshotRequest) (*access.ProtocolStateSnapshotResponse, error) {
return nil, fmt.Errorf("unimplemented method")
}

func (h *Handler) GetNetworkParameters(
ctx context.Context,
_ *access.GetNetworkParametersRequest,
Expand Down Expand Up @@ -411,6 +405,18 @@ func (h *Handler) GetEventsForBlockIDs(
}, nil
}

// GetLatestProtocolStateSnapshot returns the latest serializable Snapshot
func (h *Handler) GetLatestProtocolStateSnapshot(ctx context.Context, req *access.GetLatestProtocolStateSnapshotRequest) (*access.ProtocolStateSnapshotResponse, error) {
snapshot, err := h.api.GetLatestProtocolStateSnapshot(ctx)
if err != nil {
return nil, err
}

return &access.ProtocolStateSnapshotResponse{
SerializedSnapshot: snapshot,
}, nil
}

func blockResponse(block *flow.Block) (*access.BlockResponse, error) {
msg, err := convert.BlockToMessage(block)
if err != nil {
Expand Down
15 changes: 11 additions & 4 deletions cmd/bootstrap/cmd/seal.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"crypto/rand"
"encoding/hex"

"github.com/onflow/flow-go/cmd/bootstrap/run"
Expand All @@ -24,14 +25,20 @@ func constructRootResultAndSeal(
}

participants := model.ToIdentityList(participantNodes)
blockID := block.ID()

randomSource := make([]byte, flow.EpochSetupRandomSourceLength)
_, err = rand.Read(randomSource)
if err != nil {
log.Fatal().Err(err).Msg("could not generate random source for epoch setup event")
}

epochSetup := &flow.EpochSetup{
Counter: flagEpochCounter,
FirstView: block.Header.View,
FinalView: block.Header.View + leader.EstimatedSixMonthOfViews,
Participants: participants,
Assignments: assignments,
RandomSource: blockID[:],
RandomSource: randomSource,
}

dkgLookup := model.ToDKGLookup(dkgData, participants)
Expand All @@ -43,8 +50,8 @@ func constructRootResultAndSeal(
DKGParticipants: dkgLookup,
}

result := run.GenerateRootResult(block, stateCommit)
seal := run.GenerateRootSeal(result, epochSetup, epochCommit)
result := run.GenerateRootResult(block, stateCommit, epochSetup, epochCommit)
seal := run.GenerateRootSeal(result)

writeJSON(model.PathRootResult, result)
writeJSON(model.PathRootSeal, seal)
Expand Down
9 changes: 8 additions & 1 deletion cmd/bootstrap/run/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,18 @@ import (
"github.com/onflow/flow-go/model/flow"
)

func GenerateRootResult(block *flow.Block, commit flow.StateCommitment) *flow.ExecutionResult {
func GenerateRootResult(
block *flow.Block,
commit flow.StateCommitment,
epochSetup *flow.EpochSetup,
epochCommit *flow.EpochCommit,
) *flow.ExecutionResult {

result := &flow.ExecutionResult{
PreviousResultID: flow.ZeroID,
BlockID: block.ID(),
Chunks: chunks.ChunkListFromCommit(commit),
ServiceEvents: []flow.ServiceEvent{epochSetup.ServiceEvent(), epochCommit.ServiceEvent()},
}
return result
}
9 changes: 4 additions & 5 deletions cmd/bootstrap/run/seal.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import (
"github.com/onflow/flow-go/model/flow"
)

func GenerateRootSeal(result *flow.ExecutionResult, setup *flow.EpochSetup, commit *flow.EpochCommit) *flow.Seal {
func GenerateRootSeal(result *flow.ExecutionResult) *flow.Seal {
finalState, _ := result.FinalStateCommitment()
seal := &flow.Seal{
BlockID: result.BlockID,
ResultID: result.ID(),
FinalState: finalState,
ServiceEvents: []flow.ServiceEvent{setup.ServiceEvent(), commit.ServiceEvent()},
BlockID: result.BlockID,
ResultID: result.ID(),
FinalState: finalState,
}
return seal
}
130 changes: 101 additions & 29 deletions cmd/bootstrap/transit/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ import (
"golang.org/x/crypto/nacl/box"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
"google.golang.org/grpc"

"github.com/onflow/flow-go-sdk/client"
"github.com/onflow/flow-go/cmd/bootstrap/build"
"github.com/onflow/flow-go/engine/common/rpc/convert"
"github.com/onflow/flow-go/ledger/complete/wal"
"github.com/onflow/flow-go/model/bootstrap"
"github.com/onflow/flow-go/model/flow"
Expand Down Expand Up @@ -55,18 +58,21 @@ var (

func main() {

var bootDir, keyDir, wrapID, role string
var version, pull, push, prepare bool
var bootDir, keyDir, wrapID, role, accessAddress string
var version, pull, push, prepare, downloadSnapshot bool

flag.BoolVar(&version, "v", false, "View version and commit information")
flag.StringVar(&bootDir, "d", "~/bootstrap", "The bootstrap directory containing your node-info files")
flag.StringVar(&keyDir, "t", "", "Token provided by the Flow team to access the transit server")
flag.BoolVar(&pull, "pull", false, "Fetch keys and metadata from the transit server")
flag.BoolVar(&downloadSnapshot, "download-snapshot", false, "Download the latest protocol state snapshot from an access node and write to disk")
flag.BoolVar(&push, "push", false, "Upload public keys to the transit server")
flag.BoolVar(&prepare, "prepare", false, "Generate transit keys for push step")
flag.StringVar(&role, "role", "", `node role (can be "collection", "consensus", "execution", "verification" or "access")`)
flag.StringVar(&wrapID, "x-server-wrap", "", "(Flow Team Use), wrap response keys for consensus node")
flag.StringVar(&accessAddress, "access-address", "", "The address of an access node")
flag.StringVar(&flowBucket, "flow-bucket", "flow-genesis-bootstrap", "Storage for the transit server")

flag.Parse()

// always print version information
Expand Down Expand Up @@ -96,16 +102,21 @@ func main() {
return
}

if optionsSelected(pull, push, prepare) != 1 {
if optionsSelected(pull, push, prepare, downloadSnapshot) != 1 {
flag.Usage()
log.Fatal("Exactly one of -pull, -push, or -prepare must be specified\n")
log.Fatal("Exactly one of -pull, -push, -download-snapshot, or -prepare must be specified\n")
}

if !prepare && keyDir == "" {
if (push || pull) && keyDir == "" {
flag.Usage()
log.Fatal("Access key, '-t', required for push and pull commands")
}

if downloadSnapshot && accessAddress == "" {
flag.Usage()
log.Fatal("Access address, '-access-address', required to download latest protocl snapshot")
}

nodeID, err := fetchNodeID(bootDir)
if err != nil {
log.Fatalf("Could not determine node ID: %s\n", err)
Expand All @@ -130,6 +141,11 @@ func main() {
runPrepare(bootDir, nodeID, flowRole)
return
}

if prepare {
runDownloadSnapshot(ctx, bootDir, nodeID, "")
return
}
}

// Read the NodeID file to build other paths from
Expand Down Expand Up @@ -161,11 +177,11 @@ func printVersion() {
// Run the push process
// - create transit keypair (if the role type is Consensus)
// - upload files to GCS bucket
func runPush(ctx context.Context, bootDir, token, nodeId string, role flow.Role) {
func runPush(ctx context.Context, bootDir, token, nodeID string, role flow.Role) {
log.Println("Running push")

if role == flow.RoleConsensus {
err := generateKeys(bootDir, nodeId)
err := generateKeys(bootDir, nodeID)
if err != nil {
log.Fatalf("Failed to push: %s", err)
}
Expand All @@ -174,18 +190,18 @@ func runPush(ctx context.Context, bootDir, token, nodeId string, role flow.Role)
files := getFilesToUpload(role)

for _, file := range files {
err := bucketUpload(ctx, bootDir, fmt.Sprintf(file, nodeId), token)
err := bucketUpload(ctx, bootDir, fmt.Sprintf(file, nodeID), token)
if err != nil {
log.Fatalf("Failed to push: %s", err)
}
}
}

func runPull(ctx context.Context, bootDir, token, nodeId string, role flow.Role) {
func runPull(ctx context.Context, bootDir, token, nodeID string, role flow.Role) {

log.Println("Running pull")

extraFiles := getAdditionalFilesToDownload(role, nodeId)
extraFiles := getAdditionalFilesToDownload(role, nodeID)

var err error

Expand Down Expand Up @@ -213,26 +229,26 @@ func runPull(ctx context.Context, bootDir, token, nodeId string, role flow.Role)
}

if role == flow.RoleConsensus {
err = unwrapFile(bootDir, nodeId)
err = unwrapFile(bootDir, nodeID)
if err != nil {
log.Fatalf("Failed to pull: %s", err)
}
}

rootFile := filepath.Join(bootDir, bootstrap.PathRootBlock)
rootFile := filepath.Join(bootDir, bootstrap.PathRootProtocolStateSnapshot)
rootMD5, err := getFileMD5(rootFile)
if err != nil {
log.Fatalf("Failed to calculate md5 of %s: %v", rootFile, err)
}
log.Printf("MD5 of the root block is: %s\n", rootMD5)
log.Printf("MD5 of the root protocol snapshot is: %s\n", rootMD5)
}

// Run the prepare process
// - create transit keypair (if the role type is Consensus)
func runPrepare(bootdir, nodeId string, role flow.Role) {
func runPrepare(bootdir, nodeID string, role flow.Role) {
if role == flow.RoleConsensus {
log.Println("creating transit-keys")
err := generateKeys(bootdir, nodeId)
err := generateKeys(bootdir, nodeID)
if err != nil {
log.Fatalf("Failed to prepare: %s", err)
}
Expand All @@ -241,11 +257,67 @@ func runPrepare(bootdir, nodeId string, role flow.Role) {
log.Printf("no preparation needed for role: %s", role.String())
}

// runDownloadSnapshot fetches the latest protocol snapshot from an access node and
// writes it to the `root-protocol-snapshot.json` file
func runDownloadSnapshot(ctx context.Context, bootDir, nodeIDHex, accessAddress string) {

// convert the nodeID string to `flow.Identifier`
nodeID, err := flow.HexStringToIdentifier(nodeIDHex)
if err != nil {
log.Fatal("could not convert node id to identifier")
}

// create a flow client with given access address
flowClient, err := client.New(accessAddress, grpc.WithInsecure())
if err != nil {
log.Fatalf("could not create flow client: %v", err)
}

// get latest snapshot bytes encoded as JSON
bytes, err := flowClient.GetLatestProtocolStateSnapshot(ctx)
if err != nil {
log.Fatal("could not get latest protocol snapshot from access node")
}

// unmarshal bytes to snapshot
snapshot, err := convert.BytesToInmemSnapshot(bytes)
if err != nil {
log.Fatalf("could not convert array of bytes to snapshot: %v", err)
}

// check if given NodeID is part of the current or next epoch
currentIdentities, err := snapshot.Epochs().Current().InitialIdentities()
if err != nil {
log.Fatal("could not get initial identities from current epoch")
}
if _, exists := currentIdentities.ByNodeID(nodeID); exists {
err := utilsio.WriteFile(filepath.Join(bootDir, bootstrap.PathRootProtocolStateSnapshot), bytes)
if err != nil {
log.Fatalf("could not write snapshot to disk: %v", err)
}
return
}

nextIdentities, err := snapshot.Epochs().Next().InitialIdentities()
if err != nil {
log.Fatal("could not get initial identities from next epoch")
}
if _, exists := nextIdentities.ByNodeID(nodeID); exists {
err := utilsio.WriteFile(filepath.Join(bootDir, bootstrap.PathRootProtocolStateSnapshot), bytes)
if err != nil {
log.Fatalf("could not write snapshot to disk: %v", err)
}
return
}

log.Fatalf("could not write snapshot, given node ID does not belong to current or next epoch: %v", nodeID)
}

// generateKeys creates the transit keypair and writes them to disk for later
func generateKeys(bootDir, nodeId string) error {
func generateKeys(bootDir, nodeID string) error {

privPath := filepath.Join(bootDir, fmt.Sprintf(FilenameTransitKeyPriv, nodeId))
pubPath := filepath.Join(bootDir, fmt.Sprintf(FilenameTransitKeyPub, nodeId))
privPath := filepath.Join(bootDir, fmt.Sprintf(FilenameTransitKeyPriv, nodeID))
pubPath := filepath.Join(bootDir, fmt.Sprintf(FilenameTransitKeyPub, nodeID))

if utilsio.FileExists(privPath) && utilsio.FileExists(pubPath) {
log.Print("transit-key-path priv & pub both exist, exiting")
Expand Down Expand Up @@ -275,14 +347,14 @@ func generateKeys(bootDir, nodeId string) error {
return nil
}

func unwrapFile(bootDir, nodeId string) error {
func unwrapFile(bootDir, nodeID string) error {

log.Print("Decrypting Random Beacon key")

pubKeyPath := filepath.Join(bootDir, fmt.Sprintf(FilenameTransitKeyPub, nodeId))
privKeyPath := filepath.Join(bootDir, fmt.Sprintf(FilenameTransitKeyPriv, nodeId))
ciphertextPath := filepath.Join(bootDir, fmt.Sprintf(FilenameRandomBeaconCipher, nodeId))
plaintextPath := filepath.Join(bootDir, fmt.Sprintf(bootstrap.PathRandomBeaconPriv, nodeId))
pubKeyPath := filepath.Join(bootDir, fmt.Sprintf(FilenameTransitKeyPub, nodeID))
privKeyPath := filepath.Join(bootDir, fmt.Sprintf(FilenameTransitKeyPriv, nodeID))
ciphertextPath := filepath.Join(bootDir, fmt.Sprintf(FilenameRandomBeaconCipher, nodeID))
plaintextPath := filepath.Join(bootDir, fmt.Sprintf(bootstrap.PathRandomBeaconPriv, nodeID))

ciphertext, err := utilsio.ReadFile(ciphertextPath)
if err != nil {
Expand Down Expand Up @@ -318,10 +390,10 @@ func unwrapFile(bootDir, nodeId string) error {
return nil
}

func wrapFile(bootDir, nodeId string) error {
pubKeyPath := filepath.Join(bootDir, fmt.Sprintf(FilenameTransitKeyPub, nodeId))
plaintextPath := filepath.Join(bootDir, fmt.Sprintf(bootstrap.PathRandomBeaconPriv, nodeId))
ciphertextPath := filepath.Join(bootDir, fmt.Sprintf(FilenameRandomBeaconCipher, nodeId))
func wrapFile(bootDir, nodeID string) error {
pubKeyPath := filepath.Join(bootDir, fmt.Sprintf(FilenameTransitKeyPub, nodeID))
plaintextPath := filepath.Join(bootDir, fmt.Sprintf(bootstrap.PathRandomBeaconPriv, nodeID))
ciphertextPath := filepath.Join(bootDir, fmt.Sprintf(FilenameRandomBeaconCipher, nodeID))

plaintext, err := utilsio.ReadFile(plaintextPath)
if err != nil {
Expand Down Expand Up @@ -461,10 +533,10 @@ func getFilesToUpload(role flow.Role) []string {
}
}

func getAdditionalFilesToDownload(role flow.Role, nodeId string) []string {
func getAdditionalFilesToDownload(role flow.Role, nodeID string) []string {
switch role {
case flow.RoleConsensus:
return []string{fmt.Sprintf(filesToDownloadConsensus, nodeId)}
return []string{fmt.Sprintf(filesToDownloadConsensus, nodeID)}
}
return make([]string, 0)
}
Expand Down
Loading