From 0e0b55350a72ab7053344d5dca34cb1499f4d72c Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Wed, 25 Aug 2021 16:24:20 +0300 Subject: [PATCH] core: convert (*Blockchain).JumpToState to a callback We don't need this method to be exposed, the only its user is the StateSync module. At the same time StateSync module manages its state by itself which guarantees that (*Blockchain).jumpToState will be called with proper StateSync stage. --- internal/fakechain/fakechain.go | 10 ---------- pkg/core/blockchain.go | 10 +++------- pkg/core/blockchainer/blockchainer.go | 1 - pkg/core/blockchainer/state_sync.go | 1 - pkg/core/statesync/module.go | 18 ++++++------------ 5 files changed, 9 insertions(+), 31 deletions(-) diff --git a/internal/fakechain/fakechain.go b/internal/fakechain/fakechain.go index 2d7297349..49b876c06 100644 --- a/internal/fakechain/fakechain.go +++ b/internal/fakechain/fakechain.go @@ -307,11 +307,6 @@ func (chain *FakeChain) GetStateSyncModule() blockchainer.StateSync { return &FakeStateSync{} } -// JumpToState implements Blockchainer interface. -func (chain *FakeChain) JumpToState(module blockchainer.StateSync) error { - panic("TODO") -} - // GetStorageItem implements Blockchainer interface. func (chain *FakeChain) GetStorageItem(id int32, key []byte) state.StorageItem { panic("TODO") @@ -504,11 +499,6 @@ func (s *FakeStateSync) Traverse(root util.Uint256, process func(node mpt.Node, panic("TODO") } -// GetJumpHeight implements StateSync interface. -func (s *FakeStateSync) GetJumpHeight() (uint32, error) { - panic("TODO") -} - // GetUnknownMPTNodesBatch implements StateSync interface. func (s *FakeStateSync) GetUnknownMPTNodesBatch(limit int) []util.Uint256 { panic("TODO") diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 2e844950c..2e1374e65 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -411,17 +411,13 @@ func (bc *Blockchain) init() error { return bc.updateExtensibleWhitelist(bHeight) } -// JumpToState is an atomic operation that changes Blockchain state to the one +// jumpToState is an atomic operation that changes Blockchain state to the one // specified by the state sync point p. All the data needed for the jump must be // collected by the state sync module. -func (bc *Blockchain) JumpToState(module blockchainer.StateSync) error { +func (bc *Blockchain) jumpToState(p uint32) error { bc.lock.Lock() defer bc.lock.Unlock() - p, err := module.GetJumpHeight() - if err != nil { - return fmt.Errorf("failed to get jump height: %w", err) - } if p+1 >= uint32(len(bc.headerHashes)) { return fmt.Errorf("invalid state sync point") } @@ -792,7 +788,7 @@ func (bc *Blockchain) GetStateModule() blockchainer.StateRoot { // GetStateSyncModule returns new state sync service instance. func (bc *Blockchain) GetStateSyncModule() blockchainer.StateSync { - return statesync.NewModule(bc, bc.log, bc.dao) + return statesync.NewModule(bc, bc.log, bc.dao, bc.jumpToState) } // storeBlock performs chain update using the block given, it executes all diff --git a/pkg/core/blockchainer/blockchainer.go b/pkg/core/blockchainer/blockchainer.go index 9f9ae4e03..998b8a846 100644 --- a/pkg/core/blockchainer/blockchainer.go +++ b/pkg/core/blockchainer/blockchainer.go @@ -60,7 +60,6 @@ type Blockchainer interface { GetStorageItems(id int32) (map[string]state.StorageItem, error) GetTestVM(t trigger.Type, tx *transaction.Transaction, b *block.Block) *vm.VM GetTransaction(util.Uint256) (*transaction.Transaction, uint32, error) - JumpToState(module StateSync) error SetOracle(service services.Oracle) mempool.Feer // fee interface ManagementContractHash() util.Uint160 diff --git a/pkg/core/blockchainer/state_sync.go b/pkg/core/blockchainer/state_sync.go index 9c2161853..a8ff919d9 100644 --- a/pkg/core/blockchainer/state_sync.go +++ b/pkg/core/blockchainer/state_sync.go @@ -12,7 +12,6 @@ type StateSync interface { Init(currChainHeight uint32) error IsActive() bool IsInitialized() bool - GetJumpHeight() (uint32, error) GetUnknownMPTNodesBatch(limit int) []util.Uint256 NeedHeaders() bool NeedMPTNodes() bool diff --git a/pkg/core/statesync/module.go b/pkg/core/statesync/module.go index 80939de1c..fb775c388 100644 --- a/pkg/core/statesync/module.go +++ b/pkg/core/statesync/module.go @@ -79,10 +79,12 @@ type Module struct { mptpool *Pool billet *mpt.Billet + + jumpCallback func(p uint32) error } // NewModule returns new instance of statesync module. -func NewModule(bc blockchainer.Blockchainer, log *zap.Logger, s *dao.Simple) *Module { +func NewModule(bc blockchainer.Blockchainer, log *zap.Logger, s *dao.Simple, jumpCallback func(p uint32) error) *Module { if !(bc.GetConfig().P2PStateExchangeExtensions && bc.GetConfig().RemoveUntraceableBlocks) { return &Module{ dao: s, @@ -97,6 +99,7 @@ func NewModule(bc blockchainer.Blockchainer, log *zap.Logger, s *dao.Simple) *Mo syncInterval: uint32(bc.GetConfig().StateSyncInterval), mptpool: NewPool(), syncStage: none, + jumpCallback: jumpCallback, } } @@ -141,7 +144,7 @@ func (s *Module) Init(currChainHeight uint32) error { // We've reached this point, so chain has genesis block only. As far as we can't ruin // current chain's state until new state is completely fetched, outdated state-related data - // will be removed from storage during (*Blockchain).JumpToState(...) execution. + // will be removed from storage during (*Blockchain).jumpToState(...) execution. // All we need to do right now is to remove genesis-related MPT nodes. err = s.bc.GetStateModule().CleanStorage() if err != nil { @@ -401,7 +404,7 @@ func (s *Module) checkSyncIsCompleted() { } s.log.Info("state is in sync", zap.Uint32("state sync point", s.syncPoint)) - err := s.bc.JumpToState(s) + err := s.jumpCallback(s.syncPoint) if err != nil { s.log.Fatal("failed to jump to the latest state sync point", zap.Error(err)) } @@ -465,15 +468,6 @@ func (s *Module) Traverse(root util.Uint256, process func(node mpt.Node, nodeByt return b.Traverse(process, false) } -// GetJumpHeight returns state sync point to jump to. It is not protected by mutex and should be called -// under the module lock. -func (s *Module) GetJumpHeight() (uint32, error) { - if s.syncStage != headersSynced|mptSynced|blocksSynced { - return 0, errors.New("state sync module has wong state to perform state jump") - } - return s.syncPoint, nil -} - // GetUnknownMPTNodesBatch returns set of currently unknown MPT nodes (`limit` at max). func (s *Module) GetUnknownMPTNodesBatch(limit int) []util.Uint256 { s.lock.RLock()