OSDN Git Service

add deleteBlock and then fix some tests (#491) rollback_pr2
authoripqhjjybj <250657661@qq.com>
Wed, 19 Feb 2020 01:51:27 +0000 (09:51 +0800)
committerGitHub <noreply@github.com>
Wed, 19 Feb 2020 01:51:27 +0000 (09:51 +0800)
* add deleteBlock and then fix some tests

* add new test

* delete line

* fix one error

* change test case

* add s to word

* s

* update test cases

* update package and delete one same case

Co-authored-by: Paladz <yzhu101@uottawa.ca>
database/store.go
database/store_test.go
protocol/block_test.go
protocol/consensus_node_manager_test.go
protocol/store.go
protocol/txpool_test.go

index 1970543..97cece7 100644 (file)
@@ -156,6 +156,44 @@ func GetConsensusResult(db dbm.DB, seq uint64) (*state.ConsensusResult, error) {
        return consensusResult, nil
 }
 
+// DeleteBlock delete a new block in the protocol.
+func (s *Store) DeleteBlock(block *types.Block) error {
+       blockHash := block.Hash()
+       blockHashes, err := s.GetBlockHashesByHeight(block.Height)
+       if err != nil {
+               return err
+       }
+
+       for i := 0; i < len(blockHashes); i++ {
+               if blockHashes[i].String() == blockHash.String() {
+                       blockHashes = append(blockHashes[0:i], blockHashes[i+1:len(blockHashes)]...)
+                       break
+               }
+       }
+
+       batch := s.db.NewBatch()
+       if len(blockHashes) == 0 {
+               batch.Delete(calcBlockHashesPrefix(block.Height))
+       } else {
+               binaryBlockHashes, err := json.Marshal(blockHashes)
+               if err != nil {
+                       return errors.Wrap(err, "Marshal block hashes")
+               }
+
+               batch.Set(calcBlockHashesPrefix(block.Height), binaryBlockHashes)
+       }
+
+       batch.Delete(calcBlockHeaderKey(&blockHash))
+       batch.Delete(calcBlockTransactionsKey(&blockHash))
+       batch.Delete(calcTxStatusKey(&blockHash))
+       batch.Write()
+
+       s.cache.removeBlockHashes(block.Height)
+       s.cache.removeBlockHeader(&block.BlockHeader)
+
+       return nil
+}
+
 // NewStore creates and returns a new Store object.
 func NewStore(db dbm.DB) *Store {
        fillBlockHeaderFn := func(hash *bc.Hash) (*types.BlockHeader, error) {
index 548f6b2..cf8e86a 100644 (file)
@@ -4,6 +4,8 @@ import (
        "os"
        "testing"
 
+       "github.com/stretchr/testify/require"
+
        "github.com/bytom/vapor/consensus"
        dbm "github.com/bytom/vapor/database/leveldb"
        "github.com/bytom/vapor/database/storage"
@@ -290,3 +292,227 @@ func TestSaveBlockHeader(t *testing.T) {
                }
        }
 }
+
+func TestDeleteBlock(t *testing.T) {
+       cases := []struct {
+               initBlocks  []*types.BlockHeader
+               deleteBlock *types.BlockHeader
+               wantBlocks  []*types.BlockHeader
+       }{
+               {
+                       initBlocks: []*types.BlockHeader{},
+                       deleteBlock: &types.BlockHeader{
+                               Version:   uint64(1),
+                               Height:    uint64(1),
+                               Timestamp: uint64(1528945000),
+                       },
+                       wantBlocks: []*types.BlockHeader{},
+               },
+               {
+                       initBlocks: []*types.BlockHeader{
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945000),
+                               },
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945005),
+                               },
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945010),
+                               },
+                       },
+                       deleteBlock: &types.BlockHeader{
+                               Version:   uint64(1),
+                               Height:    uint64(1),
+                               Timestamp: uint64(1528945000),
+                       },
+                       wantBlocks: []*types.BlockHeader{
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945005),
+                               },
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945010),
+                               },
+                       },
+               },
+               {
+                       initBlocks: []*types.BlockHeader{
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945000),
+                               },
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945005),
+                               },
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945010),
+                               },
+                       },
+                       deleteBlock: &types.BlockHeader{
+                               Version:   uint64(1),
+                               Height:    uint64(1),
+                               Timestamp: uint64(1528945005),
+                       },
+                       wantBlocks: []*types.BlockHeader{
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945000),
+                               },
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945010),
+                               },
+                       },
+               },
+               {
+                       initBlocks: []*types.BlockHeader{
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945000),
+                               },
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945005),
+                               },
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945010),
+                               },
+                       },
+                       deleteBlock: &types.BlockHeader{
+                               Version:   uint64(1),
+                               Height:    uint64(1),
+                               Timestamp: uint64(1528945010),
+                       },
+                       wantBlocks: []*types.BlockHeader{
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945000),
+                               },
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945005),
+                               },
+                       },
+               },
+               {
+                       initBlocks: []*types.BlockHeader{},
+                       deleteBlock: &types.BlockHeader{
+                               Version:   uint64(1),
+                               Height:    uint64(1),
+                               Timestamp: uint64(1528945030),
+                       },
+                       wantBlocks: []*types.BlockHeader{},
+               },
+               {
+                       initBlocks: []*types.BlockHeader{
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945000),
+                               },
+                       },
+                       deleteBlock: &types.BlockHeader{
+                               Version:   uint64(1),
+                               Height:    uint64(1),
+                               Timestamp: uint64(1528945030),
+                       },
+                       wantBlocks: []*types.BlockHeader{
+                               {
+                                       Version:   uint64(1),
+                                       Height:    uint64(1),
+                                       Timestamp: uint64(1528945000),
+                               },
+                       },
+               },
+       }
+
+       for _, c := range cases {
+               verifyStatus := &bc.TransactionStatus{
+                       VerifyStatus: []*bc.TxVerifyResult{
+                               {StatusFail: false},
+                       },
+               }
+               deleteBlock := &types.Block{
+                       BlockHeader: types.BlockHeader{
+                               Version:   c.deleteBlock.Version,
+                               Height:    c.deleteBlock.Height,
+                               Timestamp: c.deleteBlock.Timestamp,
+                       },
+               }
+
+               dbA := dbm.NewDB("dbu", "leveldb", "tempA")
+               dbB := dbm.NewDB("dbc", "leveldb", "tempB")
+
+               storeA := NewStore(dbA)
+               storeB := NewStore(dbB)
+
+               for i := 0; i < len(c.initBlocks); i++ {
+                       block := &types.Block{
+                               BlockHeader: types.BlockHeader{
+                                       Version:   c.initBlocks[i].Version,
+                                       Height:    c.initBlocks[i].Height,
+                                       Timestamp: c.initBlocks[i].Timestamp,
+                               },
+                       }
+                       if err := storeA.SaveBlock(block, verifyStatus); err != nil {
+                               t.Fatal(err)
+                       }
+               }
+
+               if err := storeA.DeleteBlock(deleteBlock); err != nil {
+                       t.Fatal(err)
+               }
+
+               for i := 0; i < len(c.wantBlocks); i++ {
+                       block := &types.Block{
+                               BlockHeader: types.BlockHeader{
+                                       Version:   c.wantBlocks[i].Version,
+                                       Height:    c.wantBlocks[i].Height,
+                                       Timestamp: c.wantBlocks[i].Timestamp,
+                               },
+                       }
+                       if err := storeB.SaveBlock(block, verifyStatus); err != nil {
+                               t.Fatal(err)
+                       }
+               }
+
+               iterA := dbA.Iterator()
+               iterB := dbB.Iterator()
+
+               for iterA.Next() && iterB.Next() {
+                       require.Equal(t, iterA.Key(), iterB.Key())
+                       require.Equal(t, iterA.Value(), iterB.Value())
+               }
+
+               if iterA.Next() || iterB.Next() {
+                       t.Fatalf("why iterator is not finished")
+               }
+
+               dbA.Close()
+               os.RemoveAll("tempA")
+               dbB.Close()
+               os.RemoveAll("tempB")
+       }
+}
index e32826f..ff2b40c 100644 (file)
@@ -23,9 +23,10 @@ func (s *mStore) GetStoreStatus() *BlockStoreState                             {
 func (s *mStore) GetTransactionStatus(*bc.Hash) (*bc.TransactionStatus, error) { return nil, nil }
 func (s *mStore) GetTransactionsUtxo(*state.UtxoViewpoint, []*bc.Tx) error     { return nil }
 func (s *mStore) GetUtxo(*bc.Hash) (*storage.UtxoEntry, error)                 { return nil, nil }
-func (s *mStore) GetConsensusResult(uint64) (*state.ConsensusResult, error)              { return nil, nil }
+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) 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 {
        s.blockHeaders[blockHeader.Hash()] = blockHeader
index 76e3428..db3ab8e 100644 (file)
@@ -299,7 +299,7 @@ func TestGetConsensusNodes(t *testing.T) {
                                        Height:            1202,
                                        PreviousBlockHash: testutil.MustDecodeHash("a5be1d1177eb027327baedb869f902f74850476d0b9432a30391a3165d3af7cc"),
                                },
-                               // fork chain, fork height in 1198, rollback 1200, 1199, append 1199, 1200 
+                               // fork chain, fork height in 1198, rollback 1200, 1199, append 1199, 1200
                                {
                                        Height:            1199,
                                        PreviousBlockHash: testutil.MustDecodeHash("ef24de31371b4d34363011b6c8b065b1acaad9264d9abae2253d584e0d3a8739"),
@@ -741,6 +741,10 @@ func (s *dummyStore) SaveBlock(block *types.Block, _ *bc.TransactionStatus) erro
        return nil
 }
 
+func (s *dummyStore) DeleteBlock(block *types.Block) error {
+       return nil
+}
+
 func (s *dummyStore) SaveBlockHeader(header *types.BlockHeader) error {
        hash := header.Hash()
        s.blockHeaders[hash.String()] = header
index 808b289..c4da6e3 100644 (file)
@@ -27,6 +27,7 @@ type Store interface {
        GetMainChainHash(uint64) (*bc.Hash, error)
        GetBlockHashesByHeight(uint64) ([]*bc.Hash, error)
 
+       DeleteBlock(*types.Block) error
        SaveBlock(*types.Block, *bc.TransactionStatus) error
        SaveBlockHeader(*types.BlockHeader) error
        SaveChainStatus(*types.BlockHeader, *types.BlockHeader, []*types.BlockHeader, *state.UtxoViewpoint, []*state.ConsensusResult) error
index 343eb07..544d1fa 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) 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 {
        return nil
@@ -672,6 +673,7 @@ func (s *mockStore1) GetUtxo(*bc.Hash) (*storage.UtxoEntry, error)
 func (s *mockStore1) GetConsensusResult(uint64) (*state.ConsensusResult, error) { return nil, nil }
 func (s *mockStore1) GetMainChainHash(uint64) (*bc.Hash, error)                 { return nil, nil }
 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) SaveBlockHeader(*types.BlockHeader) error                  { return nil }
 func (s *mockStore1) SaveChainStatus(*types.BlockHeader, *types.BlockHeader, []*types.BlockHeader, *state.UtxoViewpoint, []*state.ConsensusResult) error {