OSDN Git Service

Rollback pr3 (#496)
authoripqhjjybj <250657661@qq.com>
Thu, 20 Feb 2020 09:01:13 +0000 (17:01 +0800)
committerGitHub <noreply@github.com>
Thu, 20 Feb 2020 09:01:13 +0000 (17:01 +0800)
* rollback chain

* fix test ci

* delete irrblock judge

* update rollblock

* delete test case

* fix bad delete

* change rollback

* delete one test

* add tip

* change rollback

* fix one err

* remove fmt

* remove one test

* rename

* rename variable

Co-authored-by: Poseidon <shenao.78@163.com>
database/store.go
node/node.go
protocol/block.go
protocol/block_test.go
protocol/consensus_node_manager_test.go
protocol/store.go
protocol/txpool_test.go

index 97cece7..4ffc65d 100644 (file)
@@ -156,6 +156,18 @@ func GetConsensusResult(db dbm.DB, seq uint64) (*state.ConsensusResult, error) {
        return consensusResult, nil
 }
 
+// DeleteConsensusResult delete a consensusResult from cache and database
+func (s *Store) DeleteConsensusResult(seq uint64) error {
+       consensusResult, err := GetConsensusResult(s.db, seq)
+       if err != nil {
+               return err
+       }
+
+       s.db.Delete(calcConsensusResultKey(seq))
+       s.cache.removeConsensusResult(consensusResult)
+       return nil
+}
+
 // DeleteBlock delete a new block in the protocol.
 func (s *Store) DeleteBlock(block *types.Block) error {
        blockHash := block.Hash()
index 1ecb0e4..7640e8e 100644 (file)
@@ -203,7 +203,7 @@ func Rollback(config *cfg.Config, targetHeight uint64) error {
                return err
        }
 
-       return nil
+       return chain.Rollback(targetHeight)
 }
 
 func initNodeConfig(config *cfg.Config) error {
index 6710fb5..09e72df 100644 (file)
@@ -172,6 +172,78 @@ func (c *Chain) detachBlock(detachBlockHeader *types.BlockHeader, consensusResul
        return block, nil
 }
 
+func (c *Chain) syncSubProtocols() error {
+       for _, p := range c.subProtocols {
+               if err := c.syncProtocolStatus(p); err != nil {
+                       return errors.Wrap(err, p.Name(), "sync sub protocol status")
+               }
+       }
+       return nil
+}
+
+// Rollback rollback the chain from one blockHeight to targetBlockHeight
+// WARNING: we recommend to use this only in commond line
+func (c *Chain) Rollback(targetHeight uint64) error {
+       c.cond.L.Lock()
+       defer c.cond.L.Unlock()
+
+       utxoView := state.NewUtxoViewpoint()
+       consensusResult, err := c.getBestConsensusResult()
+       if err != nil {
+               return err
+       }
+
+       if err = c.syncSubProtocols(); err != nil {
+               return err
+       }
+
+       targetBlockHeader, err := c.GetHeaderByHeight(targetHeight)
+       if err != nil {
+               return err
+       }
+
+       _, deletedBlockHeaders, err := c.calcReorganizeChain(targetBlockHeader, c.bestBlockHeader)
+       if err != nil {
+               return err
+       }
+
+       deletedBlocks := []*types.Block{}
+       for _, deletedBlockHeader := range deletedBlockHeaders {
+               block, err := c.detachBlock(deletedBlockHeader, consensusResult, utxoView)
+               if err != nil {
+                       return err
+               }
+
+               deletedBlocks = append(deletedBlocks, block)
+       }
+
+       setIrrBlockHeader := c.lastIrrBlockHeader
+       if c.lastIrrBlockHeader.Height > targetBlockHeader.Height {
+               setIrrBlockHeader = targetBlockHeader
+       }
+
+       startSeq := state.CalcVoteSeq(c.bestBlockHeader.Height)
+
+       if err = c.setState(targetBlockHeader, setIrrBlockHeader, nil, utxoView, []*state.ConsensusResult{consensusResult.Fork()}); err != nil {
+               return err
+       }
+
+       for _, block := range deletedBlocks {
+               if err := c.store.DeleteBlock(block); err != nil {
+                       return err
+               }
+       }
+
+       endSeq := state.CalcVoteSeq(targetHeight)
+       for nowSeq := startSeq; nowSeq > endSeq; nowSeq-- {
+               if err := c.store.DeleteConsensusResult(nowSeq); err != nil {
+                       return err
+               }
+       }
+
+       return nil
+}
+
 func (c *Chain) reorganizeChain(blockHeader *types.BlockHeader) error {
        attachBlockHeaders, detachBlockHeaders, err := c.calcReorganizeChain(blockHeader, c.bestBlockHeader)
        if err != nil {
@@ -185,10 +257,8 @@ func (c *Chain) reorganizeChain(blockHeader *types.BlockHeader) error {
                return err
        }
 
-       for _, p := range c.subProtocols {
-               if err := c.syncProtocolStatus(p); err != nil {
-                       return errors.Wrap(err, p.Name(), "sync sub protocol status")
-               }
+       if err = c.syncSubProtocols(); err != nil {
+               return err
        }
 
        txsToRestore := map[bc.Hash]*types.Tx{}
index ff2b40c..ba13dbe 100644 (file)
@@ -26,6 +26,7 @@ func (s *mStore) GetUtxo(*bc.Hash) (*storage.UtxoEntry, error)                 {
 func (s *mStore) GetConsensusResult(uint64) (*state.ConsensusResult, error)    { return nil, nil }
 func (s *mStore) GetMainChainHash(uint64) (*bc.Hash, error)                    { return nil, nil }
 func (s *mStore) GetBlockHashesByHeight(uint64) ([]*bc.Hash, error)            { return nil, nil }
+func (s *mStore) DeleteConsensusResult(seq uint64) error                       { return nil }
 func (s *mStore) DeleteBlock(*types.Block) error                               { return nil }
 func (s *mStore) SaveBlock(*types.Block, *bc.TransactionStatus) error          { return nil }
 func (s *mStore) SaveBlockHeader(blockHeader *types.BlockHeader) error {
index db3ab8e..5647126 100644 (file)
@@ -735,6 +735,10 @@ func (s *dummyStore) GetBlockHashesByHeight(uint64) ([]*bc.Hash, error) {
        return nil, nil
 }
 
+func (s *dummyStore) DeleteConsensusResult(seq uint64) error {
+       return nil
+}
+
 func (s *dummyStore) SaveBlock(block *types.Block, _ *bc.TransactionStatus) error {
        hash := block.Hash()
        s.blocks[hash.String()] = block
index c4da6e3..275efdb 100644 (file)
@@ -27,6 +27,7 @@ type Store interface {
        GetMainChainHash(uint64) (*bc.Hash, error)
        GetBlockHashesByHeight(uint64) ([]*bc.Hash, error)
 
+       DeleteConsensusResult(uint64) error
        DeleteBlock(*types.Block) error
        SaveBlock(*types.Block, *bc.TransactionStatus) error
        SaveBlockHeader(*types.BlockHeader) error
index 544d1fa..50e448e 100644 (file)
@@ -122,6 +122,7 @@ func (s *mockStore) GetConsensusResult(uint64) (*state.ConsensusResult, error)
 func (s *mockStore) GetMainChainHash(uint64) (*bc.Hash, error)                    { return nil, nil }
 func (s *mockStore) GetBlockHashesByHeight(uint64) ([]*bc.Hash, error)            { return nil, nil }
 func (s *mockStore) SaveBlock(*types.Block, *bc.TransactionStatus) error          { return nil }
+func (s *mockStore) DeleteConsensusResult(seq uint64) error                       { return nil }
 func (s *mockStore) DeleteBlock(*types.Block) error                               { return nil }
 func (s *mockStore) SaveBlockHeader(*types.BlockHeader) error                     { return nil }
 func (s *mockStore) SaveChainStatus(*types.BlockHeader, *types.BlockHeader, []*types.BlockHeader, *state.UtxoViewpoint, []*state.ConsensusResult) error {
@@ -675,6 +676,7 @@ func (s *mockStore1) GetMainChainHash(uint64) (*bc.Hash, error)
 func (s *mockStore1) GetBlockHashesByHeight(uint64) ([]*bc.Hash, error)         { return nil, nil }
 func (s *mockStore1) DeleteBlock(*types.Block) error                            { return nil }
 func (s *mockStore1) SaveBlock(*types.Block, *bc.TransactionStatus) error       { return nil }
+func (s *mockStore1) DeleteConsensusResult(seq uint64) error                    { return nil }
 func (s *mockStore1) SaveBlockHeader(*types.BlockHeader) error                  { return nil }
 func (s *mockStore1) SaveChainStatus(*types.BlockHeader, *types.BlockHeader, []*types.BlockHeader, *state.UtxoViewpoint, []*state.ConsensusResult) error {
        return nil