From 3b10a18ba05f0c8495fc76f9f46491a57c76311a Mon Sep 17 00:00:00 2001 From: ipqhjjybj <250657661@qq.com> Date: Wed, 19 Feb 2020 09:51:27 +0800 Subject: [PATCH] add deleteBlock and then fix some tests (#491) * 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 --- database/store.go | 38 ++++++ database/store_test.go | 226 ++++++++++++++++++++++++++++++++ protocol/block_test.go | 3 +- protocol/consensus_node_manager_test.go | 6 +- protocol/store.go | 1 + protocol/txpool_test.go | 2 + 6 files changed, 274 insertions(+), 2 deletions(-) diff --git a/database/store.go b/database/store.go index 1970543b..97cece79 100644 --- a/database/store.go +++ b/database/store.go @@ -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) { diff --git a/database/store_test.go b/database/store_test.go index 548f6b24..cf8e86a9 100644 --- a/database/store_test.go +++ b/database/store_test.go @@ -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") + } +} diff --git a/protocol/block_test.go b/protocol/block_test.go index e32826f9..ff2b40c6 100644 --- a/protocol/block_test.go +++ b/protocol/block_test.go @@ -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 diff --git a/protocol/consensus_node_manager_test.go b/protocol/consensus_node_manager_test.go index 76e3428f..db3ab8ea 100644 --- a/protocol/consensus_node_manager_test.go +++ b/protocol/consensus_node_manager_test.go @@ -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 diff --git a/protocol/store.go b/protocol/store.go index 808b289f..c4da6e34 100644 --- a/protocol/store.go +++ b/protocol/store.go @@ -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 diff --git a/protocol/txpool_test.go b/protocol/txpool_test.go index 343eb073..544d1fa3 100644 --- a/protocol/txpool_test.go +++ b/protocol/txpool_test.go @@ -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 { -- 2.11.0