diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go index 7bba0c46b..f23e64b15 100644 --- a/blockchain/blockchain.go +++ b/blockchain/blockchain.go @@ -1409,6 +1409,8 @@ func (b *BlockChain) reorganizeChain(detachNodes, attachNodes *list.List) error // recover check point from genesis block if recoverFromDefault { + //reset all mem state data + b.CkpManager.OnReset() b.InitCheckpoint(nil, nil, nil) } @@ -1731,6 +1733,7 @@ func (b *BlockChain) connectBestChain(node *BlockNode, block *Block, confirm *pa // for future processing, so add the block to the side chain holding // cache. log.Debugf("Adding block %x to side chain cache", node.Hash.Bytes()) + b.blockCache[*node.Hash] = block b.confirmCache[*node.Hash] = confirm //b.Index[*node.Hash] = node @@ -2045,7 +2048,6 @@ func (b *BlockChain) BlockLocatorFromHash(inhash *Uint256) []*Uint256 { // The desired block height is in the main chain, so look it up // from the main chain database. - h, err := b.GetBlockHash(uint32(blockHeight)) if err != nil { log.Debugf("Lookup of known valid height failed %v", blockHeight) diff --git a/blockchain/indexers/checkpoint.go b/blockchain/indexers/checkpoint.go index 10af8cfde..28a3037ae 100644 --- a/blockchain/indexers/checkpoint.go +++ b/blockchain/indexers/checkpoint.go @@ -41,6 +41,10 @@ func (c *Checkpoint) OnRollbackTo(height uint32) error { return nil } +func (c *Checkpoint) OnReset() error { + return nil +} + func (c *Checkpoint) OnRollbackSeekTo(height uint32) { return } diff --git a/core/checkpoint/manager.go b/core/checkpoint/manager.go index 4facf3146..b25c5d111 100644 --- a/core/checkpoint/manager.go +++ b/core/checkpoint/manager.go @@ -110,6 +110,9 @@ type ICheckPoint interface { // GetHeight returns initial height checkpoint should start with. StartHeight() uint32 + + //reset + OnReset() error } // Manager holds checkpoints save automatically. @@ -200,6 +203,20 @@ func (m *Manager) GetCheckpoint(key string, height uint32) ( } } +func (m *Manager) OnReset() error { + m.mtx.Lock() + defer m.mtx.Unlock() + + sortedPoints := m.getOrderedCheckpoints() + for i, v := range sortedPoints { + err := v.OnReset() + if err != nil { + log.Error(" Reset ", err, " i", i) + } + } + return nil +} + // Restore will load all data of each checkpoints file and store in // corresponding meta-data. func (m *Manager) Restore() (err error) { diff --git a/core/checkpoint/manager_test.go b/core/checkpoint/manager_test.go index 7fe614705..3d52b634b 100644 --- a/core/checkpoint/manager_test.go +++ b/core/checkpoint/manager_test.go @@ -135,6 +135,10 @@ func (c *checkpoint) OnRollbackSeekTo(height uint32) { return } +func (c *checkpoint) OnReset() error { + return nil +} + func TestManager_SaveAndRestore(t *testing.T) { data := uint64(1) currentHeight := uint32(10) diff --git a/cr/state/checkpoint.go b/cr/state/checkpoint.go index a62a919c5..7d2829e0b 100644 --- a/cr/state/checkpoint.go +++ b/cr/state/checkpoint.go @@ -46,6 +46,27 @@ func (c *Checkpoint) OnBlockSaved(block *types.DposBlock) { c.committee.ProcessBlock(block.Block, block.Confirm) } +func (c *Checkpoint) OnReset() error { + log.Info("cr state OnReset") + keyFrame := NewKeyFrame() + + committee := &Committee{ + state: NewState(c.committee.Params), + Params: c.committee.Params, + KeyFrame: *keyFrame, + firstHistory: utils.NewHistory(maxHistoryCapacity), + inactiveCRHistory: utils.NewHistory(maxHistoryCapacity), + committeeHistory: utils.NewHistory(maxHistoryCapacity), + appropriationHistory: utils.NewHistory(maxHistoryCapacity), + } + c.initFromCommittee(committee) + c.committee.Recover(c) + c.committee.state.RegisterFunctions(&FunctionsConfig{ + GetHistoryMember: committee.getHistoryMember, + }) + return nil +} + func (c *Checkpoint) OnRollbackTo(height uint32) error { keyFrame := NewKeyFrame() if height < c.StartHeight() { diff --git a/cr/state/committee.go b/cr/state/committee.go index 7ca7b5fc0..bfa7b7d43 100644 --- a/cr/state/committee.go +++ b/cr/state/committee.go @@ -1185,6 +1185,7 @@ func (c *Committee) getSignersFromWithdrawFromSideChainTx(tx interfaces.Transact publicKeys := make([]string, 0) if tx.PayloadVersion() == payload.WithdrawFromSideChainVersionV2 { allPulicKeys := c.getCurrentArbiters() + pld := tx.Payload().(*payload.WithdrawFromSideChain) for _, index := range pld.Signers { publicKeys = append(publicKeys, hex.EncodeToString(allPulicKeys[index])) diff --git a/dpos/state/arbitrators.go b/dpos/state/arbitrators.go index 878967807..9d18359a9 100644 --- a/dpos/state/arbitrators.go +++ b/dpos/state/arbitrators.go @@ -285,7 +285,6 @@ func (a *Arbiters) CheckNextTurnDPOSInfoTx(block *types.Block) error { if needNextTurnDposInfo { needNextTurnDPOSInfoCount = 1 } - if nextTurnDPOSInfoTxCount != needNextTurnDPOSInfoCount { return fmt.Errorf("current block height %d, NextTurnDPOSInfo "+ "transaction count should be %d, current block contains %d", diff --git a/dpos/state/checkpoint.go b/dpos/state/checkpoint.go index 1979c0cf7..6a520c310 100644 --- a/dpos/state/checkpoint.go +++ b/dpos/state/checkpoint.go @@ -78,6 +78,20 @@ func (c *CheckPoint) OnRollbackSeekTo(height uint32) { c.arbitrators.RollbackSeekTo(height) } +func (c *CheckPoint) OnReset() error { + log.Info("dpos state OnReset") + ar := &Arbiters{} + ar.State = &State{ + StateKeyFrame: NewStateKeyFrame(), + } + if err := ar.initArbitrators(c.arbitrators.ChainParams); err != nil { + return err + } + c.initFromArbitrators(ar) + c.arbitrators.RecoverFromCheckPoints(c) + return nil +} + func (c *CheckPoint) OnRollbackTo(height uint32) error { if height < c.StartHeight() { ar := &Arbiters{} diff --git a/elanet/netsync/manager.go b/elanet/netsync/manager.go index bae07a6b1..58699b46e 100644 --- a/elanet/netsync/manager.go +++ b/elanet/netsync/manager.go @@ -437,6 +437,7 @@ func (sm *SyncManager) handleBlockMsg(bmsg *blockMsg) { log.Debug("sm.chain.BestChain.Height:", sm.chain.BestChain.Height, "sm.syncHeight:", sm.syncHeight, "isOrphan:", isOrphan) + // Request the parents for the orphan block from the peer that sent it. if isOrphan { orphanRoot := sm.chain.GetOrphanRoot(&blockHash) @@ -567,9 +568,7 @@ func (sm *SyncManager) handleInvMsg(imsg *invMsg) { // Add it to the request queue. state.requestQueue = append(state.requestQueue, iv) continue - } - - if iv.Type == msg.InvTypeConfirmedBlock { + } else if iv.Type == msg.InvTypeConfirmedBlock { // The block is an orphan block that we already have. // When the existing orphan was processed, it requested // the missing parent blocks. When this scenario @@ -605,7 +604,6 @@ func (sm *SyncManager) handleInvMsg(imsg *invMsg) { } } } - // Request as much as possible at once. Anything that won't fit into // the request will be requested on the next inv message. numRequested := 0 @@ -659,7 +657,7 @@ func (sm *SyncManager) handleInvMsg(imsg *invMsg) { } // maxBlockLocators = 500 - if len(gdmsg.InvList) == 500 { + if len(invVects) == 500 { locator := sm.chain.GetOrphanBlockLocator(invVects) log.Info("PushGetBlocksMsg 2:", locator, "count:", len(gdmsg.InvList)) if err := peer.PushGetBlocksMsg(locator, &zeroHash); err != nil { diff --git a/mempool/txpoolcheckpoint.go b/mempool/txpoolcheckpoint.go index 868fb136c..10e7b9717 100644 --- a/mempool/txpoolcheckpoint.go +++ b/mempool/txpoolcheckpoint.go @@ -76,6 +76,10 @@ func (c *txPoolCheckpoint) GetHeight() uint32 { return c.height } +func (c *txPoolCheckpoint) OnReset() error { + return nil +} + func (c *txPoolCheckpoint) SetHeight(height uint32) { c.height = height } diff --git a/wallet/coincheckpoint.go b/wallet/coincheckpoint.go index e328d4e74..f09565362 100644 --- a/wallet/coincheckpoint.go +++ b/wallet/coincheckpoint.go @@ -127,6 +127,10 @@ func (ccp *CoinsCheckPoint) Generator() func(buf []byte) checkpoint.ICheckPoint } } +func (ccp *CoinsCheckPoint) OnReset() error { + return nil +} + func (ccp *CoinsCheckPoint) LogError(err error) { log.Warn(err.Error()) }