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

feat(dot/sync): Resume full sync after warp sync is finished #4518

Open
wants to merge 60 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
09f5a68
feat(dot/sync): Implement warp sync strategy
dimartiro Oct 22, 2024
883bc28
Add block announce handshake tests
dimartiro Oct 28, 2024
2c8a507
Change comment
dimartiro Oct 28, 2024
3eced2d
Add CLI flag for sync mode
dimartiro Oct 29, 2024
795d6e5
Lint
dimartiro Oct 29, 2024
33b96bc
Add warp sync message decode test
dimartiro Oct 31, 2024
da6de95
Add missing license
dimartiro Oct 31, 2024
dfa2618
Remove import
dimartiro Oct 31, 2024
b6d7085
Use right justification number for generic
dimartiro Nov 1, 2024
b2a0b98
Disable linting lll
dimartiro Nov 1, 2024
c76a316
Small fixes
dimartiro Nov 1, 2024
2ae9bd4
Create warp sync provider interface
dimartiro Nov 1, 2024
59f6e31
Remove unnecesary logs
dimartiro Nov 1, 2024
d3b66b4
Remove TODO
dimartiro Nov 4, 2024
ab2df6c
Fix findScheduledChange
dimartiro Nov 4, 2024
a01fae2
Improve logs and remove tests
dimartiro Nov 4, 2024
82dff61
Improve logs
dimartiro Nov 4, 2024
bbc147e
Add warp sync proof fixture
dimartiro Dec 5, 2024
f0c4baa
Move types to warpsync package
dimartiro Dec 5, 2024
cce7604
Fix findScheduledChange
dimartiro Nov 4, 2024
e59328d
Small changes
dimartiro Nov 11, 2024
cb74ae3
Retrieve state and store it in in memory trie
dimartiro Dec 11, 2024
ae0c498
Store state in our db
dimartiro Dec 12, 2024
1382081
Implement show metrics for state sync
dimartiro Dec 12, 2024
5fa49e8
Implement StateRequestProvider as part of sync package
dimartiro Dec 16, 2024
82719cc
Replace retrieve state script provider with the one in sync pkg
dimartiro Dec 16, 2024
013ad7c
Create and switch to state sync strategy
dimartiro Dec 19, 2024
9d788a7
Fix response type
dimartiro Dec 19, 2024
a803074
Remove log
dimartiro Dec 19, 2024
b28d9c5
Add unit tests for StateRequestProvider
dimartiro Dec 19, 2024
bfce0e7
Remove TODO
dimartiro Dec 19, 2024
1ab4515
Improve sync service config and creation
dimartiro Dec 19, 2024
204fb5d
Improve logs
dimartiro Jan 8, 2025
99c0b20
Fix lint
dimartiro Jan 8, 2025
31825f1
Fix tests
dimartiro Jan 8, 2025
c7fc609
Fix lint
dimartiro Jan 8, 2025
a15f5e7
Simplify full sync switch
dimartiro Jan 20, 2025
54baad5
Add issue to comments
dimartiro Jan 20, 2025
c28c6cb
Export error
dimartiro Jan 20, 2025
50b62af
Fix typo
dimartiro Jan 20, 2025
4a83579
Remove unnecesary compact proof structure
dimartiro Jan 29, 2025
0d8a5d2
Fix license
dimartiro Jan 29, 2025
527803f
Fix mocks
dimartiro Jan 29, 2025
c866006
Continue syncing from warp sync
dimartiro Jan 30, 2025
83e9254
Fix mocks
dimartiro Jan 31, 2025
fb49ebf
Revert proto
dimartiro Jan 31, 2025
144f56b
Merge branch 'development' of https://github.com/ChainSafe/gossamer i…
dimartiro Feb 5, 2025
0436421
Finalize last block retrieved from state sync
dimartiro Feb 7, 2025
9498268
Merge branch 'development' of https://github.com/ChainSafe/gossamer i…
dimartiro Feb 7, 2025
0e867ae
Update grandpa authorities
dimartiro Feb 7, 2025
a8962fc
Add todo
dimartiro Feb 7, 2025
95bf634
Remove target block phase from warp sync
dimartiro Feb 7, 2025
23afc23
Store justification bytes
dimartiro Feb 7, 2025
d034ad2
Handle header digests
dimartiro Feb 7, 2025
3996b42
Update mocks
dimartiro Feb 8, 2025
fc04406
Merge branch 'development' of https://github.com/ChainSafe/gossamer i…
dimartiro Feb 10, 2025
a47470b
Merge branch 'development' of https://github.com/ChainSafe/gossamer i…
dimartiro Feb 11, 2025
87f71c5
Add babe epoch data
dimartiro Feb 12, 2025
04215e3
Add warning message
dimartiro Feb 18, 2025
e7d36f6
Simplify check
dimartiro Feb 18, 2025
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
29 changes: 29 additions & 0 deletions dot/core/mock_runtime_instance_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions dot/core/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ func (s *Service) StorageRoot() (common.Hash, error) {
return stateTrieVersion.Hash(ts.Trie())
}

func (s *Service) HandleDigests(header *types.Header) error {
return s.onBlockImport.HandleDigests(header)
}

// HandleBlockImport handles a block that was imported via the network
func (s *Service) HandleBlockImport(block *types.Block, state *rtstorage.TrieState, announce bool) error {
parentHash := block.Header.ParentHash
Expand Down
4 changes: 2 additions & 2 deletions dot/digest/digest_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func TestHandler_GrandpaScheduledChange(t *testing.T) {
// create 4 blocks and finalize only blocks 0, 1, 2
headers, _ := state.AddBlocksToState(t, handler.blockState.(*state.BlockState), 4, false)
for i, h := range headers[:3] {
err := handler.blockState.(*state.BlockState).SetFinalisedHash(h.Hash(), uint64(i), 0)
err := handler.blockState.(*state.BlockState).SetFinalisedHash(h.Hash(), uint64(i), 0, true)
require.NoError(t, err)
}

Expand Down Expand Up @@ -98,7 +98,7 @@ func TestHandler_GrandpaScheduledChange(t *testing.T) {
require.NoError(t, err)

// finalize block of number 3
err = handler.blockState.(*state.BlockState).SetFinalisedHash(headers[3].Hash(), 3, 0)
err = handler.blockState.(*state.BlockState).SetFinalisedHash(headers[3].Hash(), 3, 0, true)
require.NoError(t, err)

time.Sleep(time.Millisecond * 500)
Expand Down
2 changes: 1 addition & 1 deletion dot/rpc/modules/chain_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ func TestChainGetFinalizedHeadByRound(t *testing.T) {
require.NoError(t, err)

testhash := header.Hash()
err = state.Block.SetFinalisedHash(testhash, 77, 1)
err = state.Block.SetFinalisedHash(testhash, 77, 1, true)
require.NoError(t, err)

req = ChainFinalizedHeadRequest{77, 1}
Expand Down
1 change: 1 addition & 0 deletions dot/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ func (nodeBuilder) newSyncService(config *cfg.Config, st *state.Service, fg sync
sync.WithBlockState(st.Block),
sync.WithGrandpaState(st.Grandpa),
sync.WithStorageState(st.Storage),
sync.WithEpochState(st.Epoch),
sync.WithFinalityGadget(fg),
sync.WithBabeVerifier(verifier),
sync.WithBlockImportHandler(cs),
Expand Down
11 changes: 9 additions & 2 deletions dot/state/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func NewBlockStateFromGenesis(db database.Database, trs *Tries, header *types.He
}

// set the latest finalised head to the genesis header
if err := bs.SetFinalisedHash(bs.genesisHash, 0, 0); err != nil {
if err := bs.SetFinalisedHash(bs.genesisHash, 0, 0, true); err != nil {
return nil, err
}

Expand Down Expand Up @@ -481,7 +481,7 @@ func (bs *BlockState) SetBlockBody(hash common.Hash, body *types.Body) error {
}

// SetFirstNonOriginSlotNumber saves the first non-origin slot number into the DB
func (bs *BlockState) setFirstNonOriginSlotNumber(slotNumber uint64) error {
func (bs *BlockState) SetFirstNonOriginSlotNumber(slotNumber uint64) error {
buf := make([]byte, 8)
binary.LittleEndian.PutUint64(buf, slotNumber)
return bs.db.Put(firstSlotNumberKey, buf)
Expand Down Expand Up @@ -960,3 +960,10 @@ func (bs *BlockState) StoreRuntime(hash common.Hash, rt runtime.Instance) {
func (bs *BlockState) GetNonFinalisedBlocks() []common.Hash {
return bs.bt.GetAllBlocks()
}

// SetBlockTree sets the blocktree for the block state
// WARN: this should be used only when state sync finishes and we need to set the new state to resume the node using a
// specific blocktree
func (bs *BlockState) SetBlockTree(blocktree *blocktree.BlockTree) {
dimartiro marked this conversation as resolved.
Show resolved Hide resolved
bs.bt = blocktree
}
10 changes: 6 additions & 4 deletions dot/state/block_finalisation.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func (bs *BlockState) GetHighestFinalisedHeader() (*types.Header, error) {
}

// SetFinalisedHash sets the latest finalised block hash
func (bs *BlockState) SetFinalisedHash(hash common.Hash, round, setID uint64) error {
func (bs *BlockState) SetFinalisedHash(hash common.Hash, round, setID uint64, finalizeAncestors bool) error {
bs.lock.Lock()
defer bs.lock.Unlock()

Expand All @@ -139,8 +139,10 @@ func (bs *BlockState) SetFinalisedHash(hash common.Hash, round, setID uint64) er
return fmt.Errorf("cannot finalise unknown block %s", hash)
}

if err := bs.handleFinalisedBlock(hash); err != nil {
return fmt.Errorf("failed to set finalised subchain in db on finalisation: %w", err)
if finalizeAncestors {
if err := bs.handleFinalisedBlock(hash); err != nil {
return fmt.Errorf("failed to set finalised subchain in db on finalisation: %w", err)
}
}

if err := bs.db.Put(finalisedHashKey(round, setID), hash[:]); err != nil {
Expand Down Expand Up @@ -243,7 +245,7 @@ func (bs *BlockState) handleFinalisedBlock(currentFinalizedHash common.Hash) err
return err
}

if err = bs.setFirstNonOriginSlotNumber(slotNumber); err != nil {
if err = bs.SetFirstNonOriginSlotNumber(slotNumber); err != nil {
return err
}
}
Expand Down
4 changes: 2 additions & 2 deletions dot/state/block_finalisation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func TestBlockState_SetFinalisedHash(t *testing.T) {
// set tries with some state root
bs.tries.softSet(someStateRoot, inmemory_trie.NewEmptyTrie())

err = bs.SetFinalisedHash(testhash, 1, 1)
err = bs.SetFinalisedHash(testhash, 1, 1, true)
require.NoError(t, err)

h, err = bs.GetFinalisedHash(1, 1)
Expand Down Expand Up @@ -148,7 +148,7 @@ func TestSetFinalisedHash_retrieveBlockNumber1SlotNumber(t *testing.T) {
})
require.NoError(t, err)

err = bs.SetFinalisedHash(header2.Hash(), 1, 1)
err = bs.SetFinalisedHash(header2.Hash(), 1, 1, true)
require.NoError(t, err)
require.Equal(t, header2.Hash(), bs.lastFinalised)

Expand Down
4 changes: 2 additions & 2 deletions dot/state/block_notify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestFinalizedChannel(t *testing.T) {
chain, _ := AddBlocksToState(t, bs, 3, false)

for _, b := range chain {
bs.SetFinalisedHash(b.Hash(), 1, 0)
bs.SetFinalisedHash(b.Hash(), 1, 0, true)
}

for i := 0; i < 1; i++ {
Expand Down Expand Up @@ -124,7 +124,7 @@ func TestFinalizedChannel_Multi(t *testing.T) {
}

time.Sleep(time.Millisecond * 10)
bs.SetFinalisedHash(chain[0].Hash(), 1, 0)
bs.SetFinalisedHash(chain[0].Hash(), 1, 0, true)
wg.Wait()

for _, ch := range chs {
Expand Down
10 changes: 5 additions & 5 deletions dot/state/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ func TestGetAllDescendants(t *testing.T) {
err = bs.AddBlockWithArrivalTime(block2, time.Now())
require.NoError(t, err)

err = bs.SetFinalisedHash(block2.Header.Hash(), 1, 1)
err = bs.SetFinalisedHash(block2.Header.Hash(), 1, 1, true)
require.NoError(t, err)

// can't fetch given block's descendants since the given block get removed from memory after
Expand Down Expand Up @@ -455,7 +455,7 @@ func TestFinalization_DeleteBlock(t *testing.T) {

// pick block to finalise
fin := leaves[len(leaves)-1]
err := bs.SetFinalisedHash(fin, 1, 1)
err := bs.SetFinalisedHash(fin, 1, 1, true)
require.NoError(t, err)

after := bs.bt.GetAllBlocks()
Expand Down Expand Up @@ -683,7 +683,7 @@ func TestNumberIsFinalised(t *testing.T) {
Body: types.Body{},
})
require.NoError(t, err)
err = bs.SetFinalisedHash(header2.Hash(), 1, 1)
err = bs.SetFinalisedHash(header2.Hash(), 1, 1, true)
require.NoError(t, err)

fin, err = bs.NumberIsFinalised(0)
Expand Down Expand Up @@ -1023,7 +1023,7 @@ func TestRange(t *testing.T) {
hashIndexToSetAsFinalized := tt.blocksToPersistAtDisk - 1
selectedHash := hashesCreated[hashIndexToSetAsFinalized]

err := blockState.SetFinalisedHash(selectedHash, 0, 0)
err := blockState.SetFinalisedHash(selectedHash, 0, 0, true)
require.NoError(t, err)
}

Expand Down Expand Up @@ -1093,7 +1093,7 @@ func Test_GetRuntime_StoreRuntime(t *testing.T) {
}

lastElementOnChain := chain[len(chain)-1]
err = blockState.SetFinalisedHash(lastElementOnChain.Hash(), 1, 0)
err = blockState.SetFinalisedHash(lastElementOnChain.Hash(), 1, 0, true)
require.NoError(t, err)

sameRuntimeOnDiffHash, err := blockState.GetRuntime(lastElementOnChain.Hash())
Expand Down
6 changes: 3 additions & 3 deletions dot/state/epoch.go
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ func (s *EpochState) HandleBABEDigest(header *types.Header, digest types.BabeCon
}

nextEpoch := currEpoch + 1
s.storeBABENextEpochData(nextEpoch, headerHash, val)
s.StoreBABENextEpochData(nextEpoch, headerHash, val)

if err = s.setBABENextEpochDataInDB(nextEpoch, headerHash, val); err != nil {
return fmt.Errorf("setting next epoch data in db: %w", err)
Expand Down Expand Up @@ -912,7 +912,7 @@ func (s *EpochState) SkipVerify(header *types.Header) (bool, error) {
}

// StoreBABENextEpochData stores the types.NextEpochData under epoch and hash keys
func (s *EpochState) storeBABENextEpochData(epoch uint64, hash common.Hash, nextEpochData types.NextEpochData) {
func (s *EpochState) StoreBABENextEpochData(epoch uint64, hash common.Hash, nextEpochData types.NextEpochData) {
s.nextEpochDataLock.Lock()
defer s.nextEpochDataLock.Unlock()

Expand Down Expand Up @@ -1001,7 +1001,7 @@ func (s *EpochState) FinalizeBABENextEpochData(finalizedHeader *types.Header) er

finalizedNextEpochData, err := findFinalizedHeaderForEpoch(s.nextEpochData, s, nextEpoch)
if err != nil {
return fmt.Errorf("cannot find next epoch data: %w", err)
return fmt.Errorf("cannot find next epoch data for epoch %d: %w", nextEpoch, err)
}

err = s.SetEpochDataRaw(nextEpoch, finalizedNextEpochData.ToEpochDataRaw())
Expand Down
2 changes: 1 addition & 1 deletion dot/state/epoch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ func TestStoreAndFinalizeBabeNextEpochData(t *testing.T) {

for _, e := range tt.inMemoryEpoch {
for i, hash := range e.hashes {
epochState.storeBABENextEpochData(e.epoch, hash, e.nextData[i])
epochState.StoreBABENextEpochData(e.epoch, hash, e.nextData[i])
}
}

Expand Down
12 changes: 6 additions & 6 deletions dot/state/grandpa.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func NewGrandpaStateFromGenesis(db database.Database, bs *BlockState,
return nil, fmt.Errorf("cannot set latest round: %w", err)
}

if err := s.setAuthorities(genesisSetID, genesisAuthorities); err != nil {
if err := s.SetAuthorities(genesisSetID, genesisAuthorities); err != nil {
return nil, fmt.Errorf("cannot set authorities: %w", err)
}

Expand Down Expand Up @@ -187,7 +187,7 @@ func (s *GrandpaState) ApplyScheduledChanges(finalizedHeader *types.Header) erro
}

grandpaVotersAuthorities := types.NewGrandpaVotersFromAuthorities(changeToApply.change.nextAuthorities)
err = s.setAuthorities(newSetID, grandpaVotersAuthorities)
err = s.SetAuthorities(newSetID, grandpaVotersAuthorities)
if err != nil {
return fmt.Errorf("cannot set authorities: %w", err)
}
Expand Down Expand Up @@ -259,7 +259,7 @@ func (s *GrandpaState) ApplyForcedChanges(importedBlockHeader *types.Header) err
}

grandpaVotersAuthorities := types.NewGrandpaVotersFromAuthorities(forcedChange.nextAuthorities)
err = s.setAuthorities(newSetID, grandpaVotersAuthorities)
err = s.SetAuthorities(newSetID, grandpaVotersAuthorities)
if err != nil {
return fmt.Errorf("cannot set authorities: %w", err)
}
Expand Down Expand Up @@ -334,8 +334,8 @@ func setIDChangeKey(setID uint64) []byte {
return append(setIDChangePrefix, buf...)
}

// setAuthorities sets the authorities for a given setID
func (s *GrandpaState) setAuthorities(setID uint64, authorities []types.GrandpaVoter) error {
// SetAuthorities sets the authorities for a given setID
func (s *GrandpaState) SetAuthorities(setID uint64, authorities []types.GrandpaVoter) error {
enc, err := types.EncodeGrandpaVoters(authorities)
if err != nil {
return err
Expand Down Expand Up @@ -407,7 +407,7 @@ func (s *GrandpaState) SetNextChange(authorities []types.GrandpaVoter, number ui
}

nextSetID := currSetID + 1
err = s.setAuthorities(nextSetID, authorities)
err = s.SetAuthorities(nextSetID, authorities)
if err != nil {
return err
}
Expand Down
29 changes: 29 additions & 0 deletions dot/state/mocks_runtime_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dot/state/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ func (s *Service) Rewind(toBlock uint) error {
// TODO: this is broken, it needs to set the latest finalised header after
// rewinding to some block number, but there is no reverse lookup function
// for block -> (round, setID) where it was finalised (#1859)
err = s.Block.SetFinalisedHash(header.Hash(), 0, 0)
err = s.Block.SetFinalisedHash(header.Hash(), 0, 0, true)
if err != nil {
return err
}
Expand Down
Loading