7 "github.com/bytom/testutil"
9 "github.com/golang/protobuf/proto"
10 dbm "github.com/tendermint/tmlibs/db"
12 "github.com/bytom/database/leveldb"
13 "github.com/bytom/database/storage"
14 "github.com/bytom/protocol/bc"
15 "github.com/bytom/protocol/bc/types"
16 "github.com/bytom/protocol/state"
19 func TestAttachOrDetachBlocks(t *testing.T) {
22 before map[bc.Hash]*storage.UtxoEntry
23 want map[bc.Hash]*storage.UtxoEntry
24 attachBlock []*bc.Block
25 detachBlock []*bc.Block
26 attachTxStatus []*bc.TransactionStatus
27 detachTxStatus []*bc.TransactionStatus
31 before: make(map[bc.Hash]*storage.UtxoEntry),
32 want: map[bc.Hash]*storage.UtxoEntry{*newTx(mockBlocks[0].Transactions[0]).OutputHash(0): storage.NewUtxoEntry(true, mockBlocks[0].Block.Height, false)},
33 attachBlock: []*bc.Block{
34 types.MapBlock(&mockBlocks[0].Block),
36 attachTxStatus: []*bc.TransactionStatus{
37 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
38 &bc.TxVerifyResult{StatusFail: false},
43 desc: "Chain trading 3",
44 before: map[bc.Hash]*storage.UtxoEntry{
45 newTx(mockBlocks[1].Transactions[1]).getSpentOutputID(): storage.NewUtxoEntry(false, mockBlocks[1].Height-1, false),
47 want: map[bc.Hash]*storage.UtxoEntry{
48 *newTx(mockBlocks[1].Transactions[0]).OutputHash(0): storage.NewUtxoEntry(true, mockBlocks[1].Height, false),
49 *newTx(mockBlocks[1].Transactions[1]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[1].Height, false),
50 *newTx(mockBlocks[1].Transactions[2]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[1].Height, false),
51 *newTx(mockBlocks[1].Transactions[3]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[1].Height, false),
52 *newTx(mockBlocks[1].Transactions[3]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[1].Height, false),
54 attachBlock: []*bc.Block{
55 types.MapBlock(&mockBlocks[1].Block),
57 attachTxStatus: []*bc.TransactionStatus{
58 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
59 &bc.TxVerifyResult{StatusFail: false},
60 &bc.TxVerifyResult{StatusFail: false},
61 &bc.TxVerifyResult{StatusFail: false},
62 &bc.TxVerifyResult{StatusFail: false},
67 node := blockNode(types.MapBlock(&mockBlocks[0].Block).BlockHeader)
68 defer os.RemoveAll("temp")
69 for index, c := range cases {
70 testDB := dbm.NewDB("testdb", "leveldb", "temp")
71 store := leveldb.NewStore(testDB)
73 utxoViewpoint := state.NewUtxoViewpoint()
74 for k, v := range c.before {
75 utxoViewpoint.Entries[k] = v
77 if err := store.SaveChainStatus(node, utxoViewpoint); err != nil {
81 utxoViewpoint = state.NewUtxoViewpoint()
82 for index, block := range c.detachBlock {
83 if err := store.GetTransactionsUtxo(utxoViewpoint, block.Transactions); err != nil {
86 if err := utxoViewpoint.DetachBlock(block, c.detachTxStatus[index]); err != nil {
91 for index, block := range c.attachBlock {
92 if err := store.GetTransactionsUtxo(utxoViewpoint, block.Transactions); err != nil {
95 if err := utxoViewpoint.ApplyBlock(block, c.attachTxStatus[index]); err != nil {
99 if err := store.SaveChainStatus(node, utxoViewpoint); err != nil {
103 want := map[string]*storage.UtxoEntry{}
104 result := make(map[string]*storage.UtxoEntry)
106 for k, v := range c.want {
107 want[string(calcUtxoKey(&k))] = v
110 iter := testDB.IteratorPrefix([]byte(utxoPreFix))
114 utxoEntry := &storage.UtxoEntry{}
115 if err := proto.Unmarshal(iter.Value(), utxoEntry); err != nil {
118 key := string(iter.Key())
119 result[key] = utxoEntry
122 if !testutil.DeepEqual(want, result) {
123 t.Errorf("case [%d] fail. want: %v, result: %v", index, want, result)