Skip to content

Commit 3b2b9a6

Browse files
network: integrate state sync module with blockfetcher
Close #3574 Signed-off-by: Ekaterina Pavlova <[email protected]>
1 parent 4af6927 commit 3b2b9a6

File tree

8 files changed

+78
-32
lines changed

8 files changed

+78
-32
lines changed

Diff for: internal/fakechain/fakechain.go

+5
Original file line numberDiff line numberDiff line change
@@ -469,3 +469,8 @@ func (s *FakeStateSync) Traverse(root util.Uint256, process func(node mpt.Node,
469469
func (s *FakeStateSync) GetUnknownMPTNodesBatch(limit int) []util.Uint256 {
470470
panic("TODO")
471471
}
472+
473+
// GetConfig implements the StateSync interface.
474+
func (s *FakeStateSync) GetConfig() config.Blockchain {
475+
panic("TODO")
476+
}

Diff for: pkg/config/blockfetcher_config.go

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type NeoFSBlockFetcher struct {
2121
BQueueSize int `yaml:"BQueueSize"`
2222
SkipIndexFilesSearch bool `yaml:"SkipIndexFilesSearch"`
2323
IndexFileSize uint32 `yaml:"IndexFileSize"`
24+
BlocksOnly bool `yaml:"BlocksOnly"`
2425
}
2526

2627
// Validate checks NeoFSBlockFetcher for internal consistency and ensures

Diff for: pkg/core/blockchain.go

-3
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,6 @@ func NewBlockchain(s storage.Store, cfg config.Blockchain, log *zap.Logger) (*Bl
285285
zap.Uint32("MaxValidUntilBlockIncrement", cfg.MaxValidUntilBlockIncrement))
286286
}
287287
if cfg.P2PStateExchangeExtensions {
288-
if !cfg.StateRootInHeader {
289-
return nil, errors.New("P2PStatesExchangeExtensions are enabled, but StateRootInHeader is off")
290-
}
291288
if cfg.KeepOnlyLatestState && !cfg.RemoveUntraceableBlocks {
292289
return nil, errors.New("P2PStateExchangeExtensions can be enabled either on MPT-complete node (KeepOnlyLatestState=false) or on light GC-enabled node (RemoveUntraceableBlocks=true)")
293290
}

Diff for: pkg/core/statesync/module.go

+5
Original file line numberDiff line numberDiff line change
@@ -516,3 +516,8 @@ func (s *Module) GetUnknownMPTNodesBatch(limit int) []util.Uint256 {
516516

517517
return s.mptpool.GetBatch(limit)
518518
}
519+
520+
// GetConfig returns current blockchain configuration.
521+
func (s *Module) GetConfig() config.Blockchain {
522+
return s.bc.GetConfig()
523+
}

Diff for: pkg/network/server.go

+35-18
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ type (
109109
notaryRequestPool *mempool.Pool
110110
extensiblePool *extpool.Pool
111111
notaryFeer NotaryFeer
112+
headerFetcher *blockfetcher.Service
112113
blockFetcher *blockfetcher.Service
113114

114115
serviceLock sync.RWMutex
@@ -227,10 +228,17 @@ func newServerFromConstructors(config ServerConfig, chain Ledger, stSync StateSy
227228
if s.NeoFSBlockFetcherCfg.BQueueSize <= 0 {
228229
s.NeoFSBlockFetcherCfg.BQueueSize = blockfetcher.DefaultQueueCacheSize
229230
}
230-
s.bFetcherQueue = bqueue.New(chain, log, nil, s.NeoFSBlockFetcherCfg.BQueueSize, updateBlockQueueLenMetric, bqueue.Blocking)
231+
s.bFetcherQueue = bqueue.New(s.stateSync, log, nil, s.NeoFSBlockFetcherCfg.BQueueSize, updateBlockQueueLenMetric, bqueue.Blocking)
231232
var err error
232-
s.blockFetcher, err = blockfetcher.New(chain, s.NeoFSBlockFetcherCfg, log, s.bFetcherQueue.PutBlock,
233-
sync.OnceFunc(func() { close(s.blockFetcherFin) }))
233+
s.headerFetcher, err = blockfetcher.New(s.stateSync, s.NeoFSBlockFetcherCfg, log, s.bFetcherQueue.PutBlock, s.bFetcherQueue.PutHeader,
234+
func() {
235+
s.log.Info("NeoFS BlockFetcher finished headers")
236+
})
237+
if err != nil {
238+
return nil, fmt.Errorf("failed to create NeoFS BlockFetcher: %w", err)
239+
}
240+
s.NeoFSBlockFetcherCfg.BlocksOnly = true
241+
s.blockFetcher, err = blockfetcher.New(s.stateSync, s.NeoFSBlockFetcherCfg, log, s.bFetcherQueue.PutBlock, s.bFetcherQueue.PutHeader, sync.OnceFunc(func() { close(s.blockFetcherFin) }))
234242
if err != nil {
235243
return nil, fmt.Errorf("failed to create NeoFS BlockFetcher: %w", err)
236244
}
@@ -311,12 +319,6 @@ func (s *Server) Start() {
311319
go s.bQueue.Run()
312320
go s.bSyncQueue.Run()
313321
go s.bFetcherQueue.Run()
314-
if s.ServerConfig.NeoFSBlockFetcherCfg.Enabled {
315-
err := s.blockFetcher.Start()
316-
if err != nil {
317-
s.log.Error("skipping NeoFS BlockFetcher", zap.Error(err))
318-
}
319-
}
320322
for _, tr := range s.transports {
321323
go tr.Accept()
322324
}
@@ -333,6 +335,7 @@ func (s *Server) Shutdown() {
333335
s.log.Info("shutting down server", zap.Int("peers", s.PeerCount()))
334336
if s.ServerConfig.NeoFSBlockFetcherCfg.Enabled {
335337
s.bFetcherQueue.Discard()
338+
s.headerFetcher.Shutdown()
336339
s.blockFetcher.Shutdown()
337340
}
338341
for _, tr := range s.transports {
@@ -732,7 +735,7 @@ func (s *Server) IsInSync() bool {
732735
var peersNumber int
733736
var notHigher int
734737

735-
if s.stateSync.IsActive() || s.blockFetcher.IsActive() {
738+
if s.stateSync.IsActive() || s.headerFetcher.IsActive() || s.blockFetcher.IsActive() {
736739
return false
737740
}
738741

@@ -792,7 +795,7 @@ func (s *Server) handleVersionCmd(p Peer, version *payload.Version) error {
792795

793796
// handleBlockCmd processes the block received from its peer.
794797
func (s *Server) handleBlockCmd(p Peer, block *block.Block) error {
795-
if s.blockFetcher.IsActive() {
798+
if s.headerFetcher.IsActive() || s.blockFetcher.IsActive() {
796799
return nil
797800
}
798801
if s.stateSync.IsActive() {
@@ -815,15 +818,20 @@ func (s *Server) handlePing(p Peer, ping *payload.Ping) error {
815818
}
816819

817820
func (s *Server) requestBlocksOrHeaders(p Peer) error {
818-
if s.blockFetcher.IsActive() {
819-
return nil
820-
}
821821
if s.stateSync.NeedHeaders() {
822822
if s.chain.HeaderHeight() < p.LastBlockIndex() {
823823
return s.requestHeaders(p)
824824
}
825825
return nil
826826
}
827+
s.headerFetcher.Shutdown()
828+
if s.ServerConfig.NeoFSBlockFetcherCfg.Enabled {
829+
err := s.blockFetcher.Start()
830+
if err != nil {
831+
s.log.Error("skipping NeoFS BlockFetcher", zap.Error(err))
832+
}
833+
}
834+
827835
var (
828836
bq bqueue.Blockqueuer = s.chain
829837
requestMPTNodes bool
@@ -847,6 +855,15 @@ func (s *Server) requestBlocksOrHeaders(p Peer) error {
847855

848856
// requestHeaders sends a CMDGetHeaders message to the peer to sync up in headers.
849857
func (s *Server) requestHeaders(p Peer) error {
858+
if s.ServerConfig.NeoFSBlockFetcherCfg.Enabled {
859+
err := s.headerFetcher.Start()
860+
if err != nil {
861+
s.log.Error("skipping NeoFS BlockFetcher", zap.Error(err))
862+
}
863+
}
864+
if s.headerFetcher.IsActive() {
865+
return nil
866+
}
850867
pl := getRequestBlocksPayload(p, s.chain.HeaderHeight(), &s.lastRequestedHeader)
851868
return p.EnqueueP2PMessage(NewMessage(CMDGetHeaders, pl))
852869
}
@@ -1136,7 +1153,7 @@ func (s *Server) handleGetHeadersCmd(p Peer, gh *payload.GetBlockByIndex) error
11361153

11371154
// handleHeadersCmd processes headers payload.
11381155
func (s *Server) handleHeadersCmd(p Peer, h *payload.Headers) error {
1139-
if s.blockFetcher.IsActive() {
1156+
if s.headerFetcher.IsActive() {
11401157
return nil
11411158
}
11421159
return s.stateSync.AddHeaders(h.Hdrs...)
@@ -1335,6 +1352,9 @@ func (s *Server) handleGetAddrCmd(p Peer) error {
13351352
// 2. Send requests for chunk in increasing order.
13361353
// 3. After all requests have been sent, request random height.
13371354
func (s *Server) requestBlocks(bq bqueue.Blockqueuer, p Peer) error {
1355+
if s.blockFetcher.IsActive() {
1356+
return nil
1357+
}
13381358
pl := getRequestBlocksPayload(p, bq.BlockHeight(), &s.lastRequestedBlock)
13391359
lq, capLeft := s.bQueue.LastQueued()
13401360
if capLeft == 0 {
@@ -1468,9 +1488,6 @@ func (s *Server) handleMessage(peer Peer, msg *Message) error {
14681488
}
14691489

14701490
func (s *Server) tryInitStateSync() {
1471-
if s.blockFetcher.IsActive() {
1472-
return
1473-
}
14741491
if !s.stateSync.IsActive() {
14751492
s.bSyncQueue.Discard()
14761493
return

Diff for: pkg/network/state_sync.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package network
22

33
import (
4+
"github.com/nspcc-dev/neo-go/pkg/config"
45
"github.com/nspcc-dev/neo-go/pkg/core/mpt"
56
"github.com/nspcc-dev/neo-go/pkg/network/bqueue"
67
"github.com/nspcc-dev/neo-go/pkg/util"
@@ -17,4 +18,5 @@ type StateSync interface {
1718
NeedHeaders() bool
1819
NeedMPTNodes() bool
1920
Traverse(root util.Uint256, process func(node mpt.Node, nodeBytes []byte) bool) error
21+
GetConfig() config.Blockchain
2022
}

Diff for: pkg/services/blockfetcher/blockfetcher.go

+16-6
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const (
3636
type Ledger interface {
3737
GetConfig() config.Blockchain
3838
BlockHeight() uint32
39+
HeaderHeight() uint32
3940
}
4041

4142
// poolWrapper wraps a NeoFS pool to adapt its Close method to return an error.
@@ -57,10 +58,11 @@ type Service struct {
5758
cfg config.NeoFSBlockFetcher
5859
stateRootInHeader bool
5960

60-
chain Ledger
61-
pool poolWrapper
62-
enqueueBlock func(*block.Block) error
63-
account *wallet.Account
61+
chain Ledger
62+
pool poolWrapper
63+
enqueueBlock func(*block.Block) error
64+
enqueueHeader func(*block.Header) error
65+
account *wallet.Account
6466

6567
oidsCh chan oid.ID
6668
// wg is a wait group for block downloaders.
@@ -81,7 +83,7 @@ type Service struct {
8183
}
8284

8385
// New creates a new BlockFetcher Service.
84-
func New(chain Ledger, cfg config.NeoFSBlockFetcher, logger *zap.Logger, putBlock func(*block.Block) error, shutdownCallback func()) (*Service, error) {
86+
func New(chain Ledger, cfg config.NeoFSBlockFetcher, logger *zap.Logger, putBlock func(*block.Block) error, putHeader func(*block.Header) error, shutdownCallback func()) (*Service, error) {
8587
var (
8688
account *wallet.Account
8789
err error
@@ -143,6 +145,7 @@ func New(chain Ledger, cfg config.NeoFSBlockFetcher, logger *zap.Logger, putBloc
143145
cfg: cfg,
144146

145147
enqueueBlock: putBlock,
148+
enqueueHeader: putHeader,
146149
account: account,
147150
stateRootInHeader: chain.GetConfig().StateRootInHeader,
148151
shutdownCallback: shutdownCallback,
@@ -262,7 +265,11 @@ func (bfs *Service) blockDownloader() {
262265
case <-bfs.ctx.Done():
263266
return
264267
default:
265-
err = bfs.enqueueBlock(b)
268+
if !bfs.cfg.BlocksOnly {
269+
err = bfs.enqueueHeader(&b.Header)
270+
} else {
271+
err = bfs.enqueueBlock(b)
272+
}
266273
if err != nil {
267274
bfs.log.Error("failed to enqueue block", zap.Uint32("index", b.Index), zap.Error(err))
268275
bfs.stopService(true)
@@ -275,6 +282,9 @@ func (bfs *Service) blockDownloader() {
275282
// fetchOIDsFromIndexFiles fetches block OIDs from NeoFS by searching index files first.
276283
func (bfs *Service) fetchOIDsFromIndexFiles() error {
277284
h := bfs.chain.BlockHeight()
285+
if !bfs.cfg.BlocksOnly {
286+
h = bfs.chain.HeaderHeight()
287+
}
278288
startIndex := h / bfs.cfg.IndexFileSize
279289
skip := h % bfs.cfg.IndexFileSize
280290

Diff for: pkg/services/blockfetcher/blockfetcher_test.go

+14-5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ type mockLedger struct {
1414
height uint32
1515
}
1616

17+
func (m *mockLedger) HeaderHeight() uint32 {
18+
return m.height
19+
}
20+
1721
func (m *mockLedger) GetConfig() config.Blockchain {
1822
return config.Blockchain{}
1923
}
@@ -31,6 +35,11 @@ func (m *mockPutBlockFunc) putBlock(b *block.Block) error {
3135
return nil
3236
}
3337

38+
func (m *mockPutBlockFunc) putHead(h *block.Header) error {
39+
m.putCalled = true
40+
return nil
41+
}
42+
3443
func TestServiceConstructor(t *testing.T) {
3544
logger := zap.NewNop()
3645
ledger := &mockLedger{height: 10}
@@ -46,7 +55,7 @@ func TestServiceConstructor(t *testing.T) {
4655
OIDBatchSize: 0,
4756
DownloaderWorkersCount: 0,
4857
}
49-
_, err := New(ledger, cfg, logger, mockPut.putBlock, shutdownCallback)
58+
_, err := New(ledger, cfg, logger, mockPut.putBlock, mockPut.putHead, shutdownCallback)
5059
require.Error(t, err)
5160
})
5261

@@ -57,7 +66,7 @@ func TestServiceConstructor(t *testing.T) {
5766
},
5867
Addresses: []string{},
5968
}
60-
_, err := New(ledger, cfg, logger, mockPut.putBlock, shutdownCallback)
69+
_, err := New(ledger, cfg, logger, mockPut.putBlock, mockPut.putHead, shutdownCallback)
6170
require.Error(t, err)
6271
})
6372

@@ -69,7 +78,7 @@ func TestServiceConstructor(t *testing.T) {
6978
Addresses: []string{"localhost:8080"},
7079
BQueueSize: DefaultQueueCacheSize,
7180
}
72-
service, err := New(ledger, cfg, logger, mockPut.putBlock, shutdownCallback)
81+
service, err := New(ledger, cfg, logger, mockPut.putBlock, mockPut.putHead, shutdownCallback)
7382
require.NoError(t, err)
7483
require.NotNil(t, service)
7584

@@ -87,7 +96,7 @@ func TestServiceConstructor(t *testing.T) {
8796
},
8897
Addresses: []string{"localhost:1"},
8998
}
90-
service, err := New(ledger, cfg, logger, mockPut.putBlock, shutdownCallback)
99+
service, err := New(ledger, cfg, logger, mockPut.putBlock, mockPut.putHead, shutdownCallback)
91100
require.NoError(t, err)
92101
err = service.Start()
93102
require.Error(t, err)
@@ -106,7 +115,7 @@ func TestServiceConstructor(t *testing.T) {
106115
},
107116
},
108117
}
109-
_, err := New(ledger, cfg, logger, mockPut.putBlock, shutdownCallback)
118+
_, err := New(ledger, cfg, logger, mockPut.putBlock, mockPut.putHead, shutdownCallback)
110119
require.Error(t, err)
111120
require.Contains(t, err.Error(), "open wallet: open invalid/path/to/wallet.json:")
112121
})

0 commit comments

Comments
 (0)