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

refactor(lib/sync): introduce fullsync strategy #4114

Merged
merged 92 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
01b7bec
feat: implement in-memory-trie iterator and prefixed iterator
EclesioMeloJunior Jul 5, 2024
d3004f9
chore: adjustment to fn replacement
EclesioMeloJunior Jul 5, 2024
1bb4eda
chore: add license and fix test
EclesioMeloJunior Jul 5, 2024
ef53a1f
chore: fix lint issues
EclesioMeloJunior Jul 5, 2024
396b873
feat: remove usage of `sorted keys`
EclesioMeloJunior Jul 5, 2024
53288b3
chore: remove unneeded logger
EclesioMeloJunior Jul 6, 2024
c8da583
wip sync
EclesioMeloJunior Jul 7, 2024
a591076
chore: strategies does not report or block peers
EclesioMeloJunior Jul 25, 2024
e9d1bcc
wip: fullsync strategy working, need to polish the libsync servic
EclesioMeloJunior Jul 29, 2024
93aca34
Merge branch 'development' into eclesio/sync-strategy
EclesioMeloJunior Jul 29, 2024
41dde9d
chore: bring sync status
EclesioMeloJunior Jul 29, 2024
88b7d3b
chore: removing panics
EclesioMeloJunior Jul 29, 2024
996baaa
chore: removing unneeded code
EclesioMeloJunior Jul 29, 2024
c1e43c8
chore: add test `TestFullSyncIsFinished`
EclesioMeloJunior Aug 6, 2024
9622544
chore: use yaml file for test data
EclesioMeloJunior Aug 6, 2024
316214a
chore: remove old sync package
EclesioMeloJunior Aug 6, 2024
1aa68d4
Merge branch 'development' into eclesio/sync-strategy
EclesioMeloJunior Aug 7, 2024
959769c
chore: create `unready_blocks.go`
EclesioMeloJunior Aug 7, 2024
b950cda
chore: fix lint
EclesioMeloJunior Aug 7, 2024
8479f23
chore: ignore forks when ancestor is behind highest finalized block
EclesioMeloJunior Aug 7, 2024
124aca8
Merge branch 'eclesio/sync-strategy' of github.com:ChainSafe/gossamer…
EclesioMeloJunior Aug 7, 2024
ec88b94
chore: small updts
EclesioMeloJunior Aug 7, 2024
f291705
chore: listening for stop channel on `runSyncEngine`
EclesioMeloJunior Aug 12, 2024
66f8412
chore: address comments
EclesioMeloJunior Aug 23, 2024
e73bf16
Merge branch 'development' into eclesio/sync-strategy
EclesioMeloJunior Aug 26, 2024
a3fc14e
chore: resolve lll warn
EclesioMeloJunior Aug 26, 2024
0ff9ec9
chore: make license
EclesioMeloJunior Aug 26, 2024
f59e7f2
chore: solve invalid block number type while encoding block request m…
EclesioMeloJunior Aug 27, 2024
2acf762
chore: update the ci to use `lib/sync`
EclesioMeloJunior Aug 27, 2024
eb0ca27
chore: simplify the message construction to use just uint32
EclesioMeloJunior Aug 27, 2024
1d4295f
chore: re-add sync block response handler
EclesioMeloJunior Aug 28, 2024
2048a9e
chore: implement `HighestBlock` and `IsSynced`
EclesioMeloJunior Aug 28, 2024
3467611
Merge branch 'development' into eclesio/sync-strategy
EclesioMeloJunior Aug 28, 2024
625f00e
chore: fix lint warns
EclesioMeloJunior Aug 28, 2024
e533c36
Merge branch 'eclesio/sync-strategy' of github.com:ChainSafe/gossamer…
EclesioMeloJunior Aug 28, 2024
f4615e4
chore: remove unneeded code
EclesioMeloJunior Aug 28, 2024
43eef82
chore: remove unneeded comment
EclesioMeloJunior Aug 29, 2024
c22065f
chore: introduce concurrency and perpetual tip sync chase
EclesioMeloJunior Aug 30, 2024
2f0b3a0
while reporting, create a node in peerset
EclesioMeloJunior Aug 31, 2024
31b9252
Merge branch 'development' into eclesio/sync-strategy
P1sar Sep 4, 2024
d339546
Merge branch 'development' into eclesio/sync-strategy
EclesioMeloJunior Sep 9, 2024
195a9be
chore: propagate block announce
EclesioMeloJunior Sep 10, 2024
ec384c7
wip: remove wrong mtx Lock, remove neighbors message
EclesioMeloJunior Sep 12, 2024
a54572f
chore: remove unneeded log level
EclesioMeloJunior Sep 12, 2024
8546176
chore: if ahead of target dont ask for more blocks
EclesioMeloJunior Sep 13, 2024
8f63325
chore: remove unneeded goto
EclesioMeloJunior Sep 13, 2024
1f48f65
chore: adjust on block announce
EclesioMeloJunior Sep 13, 2024
399eb9b
chore: rollback integration tests to use /dot/sync
EclesioMeloJunior Sep 13, 2024
e554d3f
chore: rollback changes on core pkg
EclesioMeloJunior Sep 13, 2024
f233d05
chore: TODO(#2931)
EclesioMeloJunior Sep 13, 2024
330444c
chore: fix `removeIrrelevantFragments` out of bounds panic
EclesioMeloJunior Sep 13, 2024
2eda142
Merge branch 'development' into eclesio/sync-strategy
EclesioMeloJunior Sep 13, 2024
b3434ec
add license
EclesioMeloJunior Sep 13, 2024
1b94210
chore: solve mocks mismatch and full block importer
EclesioMeloJunior Sep 13, 2024
d905e7d
chore: use snake case on testing names
EclesioMeloJunior Sep 13, 2024
8f86d9b
chore: TestBuildRequestMessage
EclesioMeloJunior Sep 13, 2024
ed6c755
chore: fix sync test
EclesioMeloJunior Sep 13, 2024
9dff75a
chore: address comments and lint
EclesioMeloJunior Sep 17, 2024
c8dcb15
Merge branch 'development' into eclesio/sync-strategy
EclesioMeloJunior Sep 17, 2024
cc71723
chore: use `GossipSuccessValue` to good block announced received
EclesioMeloJunior Sep 17, 2024
6e38bdc
Merge branch 'eclesio/sync-strategy' of github.com:ChainSafe/gossamer…
EclesioMeloJunior Sep 17, 2024
1422414
improve test suite
EclesioMeloJunior Sep 19, 2024
2c11956
chore: remove target calculation using mean
EclesioMeloJunior Sep 19, 2024
b6a0b9d
chore: resolve lll
EclesioMeloJunior Sep 19, 2024
d3920d1
Update dot/sync/peer_view.go
EclesioMeloJunior Sep 19, 2024
793295c
Update dot/sync/fullsync_handle_block.go
EclesioMeloJunior Sep 19, 2024
b3e6bf4
chore: fix `TestHandleBlockAnnounceMessage`
EclesioMeloJunior Sep 19, 2024
04540d1
chore: fix `TestFullSyncIsFinished`
EclesioMeloJunior Sep 19, 2024
7f08a97
Merge branch 'development' into eclesio/sync-strategy
EclesioMeloJunior Sep 23, 2024
3263911
chore: resolve all conflicts
EclesioMeloJunior Sep 23, 2024
2ad6b37
chore: rename `IsFinished -> Process` and add named returns
EclesioMeloJunior Sep 23, 2024
75a30cd
chore: fix small lint err
EclesioMeloJunior Sep 23, 2024
dff8a08
chore: fix `TestService_CreateBlockResponse`
EclesioMeloJunior Sep 23, 2024
50c4594
chore: fix test `TestFullSyncNextActions`
EclesioMeloJunior Sep 23, 2024
ee3380b
chore: fix test `TestCreateNotificationsMessageHandler_BlockAnnounceH…
EclesioMeloJunior Sep 23, 2024
51e281c
chore: solve discovery test problem
EclesioMeloJunior Sep 23, 2024
f68623d
chore: fix `TestFullSyncBlockAnnounce`
EclesioMeloJunior Sep 23, 2024
c7fc7b3
chore: `TestFullSyncBlockAnnounce`
EclesioMeloJunior Sep 24, 2024
fc201d2
chore: remove unneeded file
EclesioMeloJunior Sep 24, 2024
2f4a242
Merge branch 'development' into eclesio/sync-strategy
EclesioMeloJunior Sep 25, 2024
6da0e74
chore: fix deepsource
EclesioMeloJunior Sep 25, 2024
a8b7889
Merge branch 'eclesio/sync-strategy' of github.com:ChainSafe/gossamer…
EclesioMeloJunior Sep 25, 2024
2f5c469
chore: define min peers to 1
EclesioMeloJunior Sep 25, 2024
266d147
chore: fix retrieveFirstNonOriginBlockSlot when hash is not imported yet
EclesioMeloJunior Sep 25, 2024
109ec03
chore: bring sync promo gauge back
EclesioMeloJunior Sep 26, 2024
248c1ee
Merge branch 'development' into eclesio/sync-strategy
EclesioMeloJunior Sep 26, 2024
8dd8014
Merge branch 'development' into eclesio/sync-strategy
EclesioMeloJunior Sep 26, 2024
8457d45
Merge branch 'development' into eclesio/sync-strategy
EclesioMeloJunior Sep 26, 2024
87af0f8
Merge branch 'eclesio/sync-strategy' of github.com:ChainSafe/gossamer…
EclesioMeloJunior Sep 26, 2024
29b6a0a
chore: address comments
EclesioMeloJunior Sep 26, 2024
294dfe2
chore: fix lint
EclesioMeloJunior Sep 26, 2024
4cbbb97
chore: nits
EclesioMeloJunior Sep 30, 2024
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
89 changes: 81 additions & 8 deletions dot/core/service_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (

"github.com/ChainSafe/gossamer/dot/network"
"github.com/ChainSafe/gossamer/dot/state"
"github.com/ChainSafe/gossamer/dot/sync"
"github.com/ChainSafe/gossamer/dot/types"
"github.com/ChainSafe/gossamer/lib/babe/inherents"
"github.com/ChainSafe/gossamer/lib/common"
Expand Down Expand Up @@ -222,32 +221,32 @@ func TestHandleChainReorg_WithReorg_Trans(t *testing.T) {
rt, err := s.blockState.GetRuntime(bestBlockHash)
require.NoError(t, err)

block1 := sync.BuildBlock(t, rt, parent, nil)
block1 := BuildBlock(t, rt, parent, nil)
bs.StoreRuntime(block1.Header.Hash(), rt)
err = bs.AddBlock(block1)
require.NoError(t, err)

block2 := sync.BuildBlock(t, rt, &block1.Header, nil)
block2 := BuildBlock(t, rt, &block1.Header, nil)
bs.StoreRuntime(block2.Header.Hash(), rt)
err = bs.AddBlock(block2)
require.NoError(t, err)

block3 := sync.BuildBlock(t, rt, &block2.Header, nil)
block3 := BuildBlock(t, rt, &block2.Header, nil)
bs.StoreRuntime(block3.Header.Hash(), rt)
err = bs.AddBlock(block3)
require.NoError(t, err)

block4 := sync.BuildBlock(t, rt, &block3.Header, nil)
block4 := BuildBlock(t, rt, &block3.Header, nil)
bs.StoreRuntime(block4.Header.Hash(), rt)
err = bs.AddBlock(block4)
require.NoError(t, err)

block5 := sync.BuildBlock(t, rt, &block4.Header, nil)
block5 := BuildBlock(t, rt, &block4.Header, nil)
bs.StoreRuntime(block5.Header.Hash(), rt)
err = bs.AddBlock(block5)
require.NoError(t, err)

block31 := sync.BuildBlock(t, rt, &block2.Header, nil)
block31 := BuildBlock(t, rt, &block2.Header, nil)
bs.StoreRuntime(block31.Header.Hash(), rt)
err = bs.AddBlock(block31)
require.NoError(t, err)
Expand All @@ -257,7 +256,7 @@ func TestHandleChainReorg_WithReorg_Trans(t *testing.T) {
// Add extrinsic to block `block41`
ext := createExtrinsic(t, rt, bs.(*state.BlockState).GenesisHash(), nonce)

block41 := sync.BuildBlock(t, rt, &block31.Header, ext)
block41 := BuildBlock(t, rt, &block31.Header, ext)
bs.StoreRuntime(block41.Header.Hash(), rt)
err = bs.AddBlock(block41)
require.NoError(t, err)
Expand All @@ -269,6 +268,80 @@ func TestHandleChainReorg_WithReorg_Trans(t *testing.T) {
require.Equal(t, 1, len(pending))
}

func BuildBlock(t *testing.T, instance runtime.Instance, parent *types.Header, ext types.Extrinsic) *types.Block {
digest := types.NewDigest()
prd, err := types.NewBabeSecondaryPlainPreDigest(0, 1).ToPreRuntimeDigest()
require.NoError(t, err)
err = digest.Add(*prd)
require.NoError(t, err)
header := &types.Header{
ParentHash: parent.Hash(),
Number: parent.Number + 1,
Digest: digest,
}

err = instance.InitializeBlock(header)
require.NoError(t, err)

idata := types.NewInherentData()
err = idata.SetInherent(types.Timstap0, uint64(time.Now().Unix()))
require.NoError(t, err)

err = idata.SetInherent(types.Babeslot, uint64(1))
require.NoError(t, err)

ienc, err := idata.Encode()
require.NoError(t, err)

// Call BlockBuilder_inherent_extrinsics which returns the inherents as encoded extrinsics
inherentExts, err := instance.InherentExtrinsics(ienc)
require.NoError(t, err)

// decode inherent extrinsics
cp := make([]byte, len(inherentExts))
copy(cp, inherentExts)
var inExts [][]byte
err = scale.Unmarshal(cp, &inExts)
require.NoError(t, err)

// apply each inherent extrinsic
for _, inherent := range inExts {
in, err := scale.Marshal(inherent)
require.NoError(t, err)

ret, err := instance.ApplyExtrinsic(in)
require.NoError(t, err)
require.Equal(t, ret, []byte{0, 0})
}

body := types.Body(types.BytesArrayToExtrinsics(inExts))

if ext != nil {
// validate and apply extrinsic
var ret []byte

externalExt := types.Extrinsic(append([]byte{byte(types.TxnExternal)}, ext...))
_, err = instance.ValidateTransaction(externalExt)
require.NoError(t, err)

ret, err = instance.ApplyExtrinsic(ext)
require.NoError(t, err)
require.Equal(t, ret, []byte{0, 0})

body = append(body, ext)
}

res, err := instance.FinalizeBlock()
require.NoError(t, err)
res.Number = header.Number
res.Hash()

return &types.Block{
Header: *res,
Body: body,
}
}

func TestHandleChainReorg_WithReorg_NoTransactions(t *testing.T) {
s := NewTestService(t, nil)
const height = 5
Expand Down
4 changes: 2 additions & 2 deletions dot/mock_node_builder_test.go

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

23 changes: 4 additions & 19 deletions dot/network/block_announce.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

"github.com/ChainSafe/gossamer/dot/peerset"
"github.com/ChainSafe/gossamer/dot/types"
"github.com/ChainSafe/gossamer/lib/blocktree"
"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/pkg/scale"

Expand Down Expand Up @@ -186,33 +185,19 @@ func (s *Service) validateBlockAnnounceHandshake(from peer.ID, hs Handshake) err
np.peersData.setInboundHandshakeData(from, data)
}

// if peer has higher best block than us, begin syncing
latestHeader, err := s.blockState.BestBlockHeader()
if err != nil {
return err
}

// check if peer block number is greater than host block number
if latestHeader.Number >= uint(bhs.BestBlockNumber) {
return nil
}

return s.syncer.HandleBlockAnnounceHandshake(from, bhs)
}

// handleBlockAnnounceMessage handles BlockAnnounce messages
// if some more blocks are required to sync the announced block, the node will open a sync stream
// with its peer and send a BlockRequest message
func (s *Service) handleBlockAnnounceMessage(from peer.ID, msg NotificationsMessage) (propagate bool, err error) {
func (s *Service) handleBlockAnnounceMessage(from peer.ID, msg NotificationsMessage) (bool, error) {
bam, ok := msg.(*BlockAnnounceMessage)
if !ok {
return false, errors.New("invalid message")
}

err = s.syncer.HandleBlockAnnounce(from, bam)
if errors.Is(err, blocktree.ErrBlockExists) {
return true, nil
}

return false, err
err := s.syncer.HandleBlockAnnounce(from, bam)
shouldPropagate := err == nil
return shouldPropagate, err
}
34 changes: 24 additions & 10 deletions dot/network/block_announce_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
package network

import (
"errors"
"testing"

"github.com/ChainSafe/gossamer/dot/types"
"github.com/ChainSafe/gossamer/lib/blocktree"
"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/pkg/scale"
gomock "go.uber.org/mock/gomock"
Expand Down Expand Up @@ -131,22 +131,33 @@ func TestHandleBlockAnnounceMessage(t *testing.T) {
t.Parallel()

testCases := map[string]struct {
propagate bool
mockSyncer func(*testing.T, peer.ID, *BlockAnnounceMessage) Syncer
propagate bool
expectError bool
mockSyncer func(*testing.T, peer.ID, *BlockAnnounceMessage) Syncer
}{
"block_already_exists": {
"should_propagate": {
mockSyncer: func(t *testing.T, peer peer.ID, blockAnnounceMessage *BlockAnnounceMessage) Syncer {
ctrl := gomock.NewController(t)
syncer := NewMockSyncer(ctrl)
syncer.EXPECT().
HandleBlockAnnounce(peer, blockAnnounceMessage).
Return(blocktree.ErrBlockExists)
Return(nil)
return syncer
},
propagate: true,
expectError: false,
propagate: true,
},
"block_does_not_exists": {
propagate: false,
"should_not_propagate": {
mockSyncer: func(t *testing.T, peer peer.ID, blockAnnounceMessage *BlockAnnounceMessage) Syncer {
ctrl := gomock.NewController(t)
syncer := NewMockSyncer(ctrl)
syncer.EXPECT().
HandleBlockAnnounce(peer, blockAnnounceMessage).
Return(errors.New("mocked error"))
return syncer
},
expectError: true,
propagate: false,
},
}

Expand Down Expand Up @@ -175,8 +186,11 @@ func TestHandleBlockAnnounceMessage(t *testing.T) {

service := createTestService(t, config)
gotPropagate, err := service.handleBlockAnnounceMessage(peerID, msg)

require.NoError(t, err)
if tt.expectError {
require.Error(t, err)
} else {
require.NoError(t, err)
}
require.Equal(t, tt.propagate, gotPropagate)
})
}
Expand Down
6 changes: 5 additions & 1 deletion dot/network/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (s *testStreamHandler) handleMessage(stream libp2pnetwork.Stream, msg messa
return s.writeToStream(stream, announceHandshake)
}

func (s *testStreamHandler) writeToStream(stream libp2pnetwork.Stream, msg messages.P2PMessage) error {
func (*testStreamHandler) writeToStream(stream libp2pnetwork.Stream, msg messages.P2PMessage) error {
encMsg, err := msg.Encode()
if err != nil {
return err
Expand Down Expand Up @@ -257,6 +257,10 @@ func createTestService(t *testing.T, cfg *Config) (srvc *Service) {
CreateBlockResponse(gomock.Any(), gomock.Any()).
Return(newTestBlockResponseMessage(t), nil).AnyTimes()

syncer.EXPECT().
OnConnectionClosed(gomock.AssignableToTypeOf(peer.ID(string("")))).
AnyTimes()

syncer.EXPECT().IsSynced().Return(false).AnyTimes()
cfg.Syncer = syncer
}
Expand Down
4 changes: 4 additions & 0 deletions dot/network/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ func (h *host) writeToStream(s network.Stream, msg messages.P2PMessage) error {
return err
}

if len(encMsg) != sent {
logger.Errorf("full message not sent: sent %d, message size %d", sent, len(encMsg))
}

h.bwc.LogSentMessage(int64(sent))

return nil
Expand Down
4 changes: 2 additions & 2 deletions dot/network/message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,6 @@ func TestAscendingBlockRequest(t *testing.T) {
},
},
},

"requesting_4_chunks_of_128_plus_3_blocks": {
startNumber: 1,
targetNumber: (128 * 4) + 3,
Expand Down Expand Up @@ -433,7 +432,8 @@ func TestAscendingBlockRequest(t *testing.T) {
tt := tt

t.Run(tname, func(t *testing.T) {
requests := messages.NewAscendingBlockRequests(tt.startNumber, tt.targetNumber, messages.BootstrapRequestData)
requests := messages.NewAscendingBlockRequests(tt.startNumber, tt.targetNumber,
messages.BootstrapRequestData)
require.Equal(t, tt.expectedBlockRequestMessage, requests)

acc := uint32(0)
Expand Down
Loading
Loading