OSDN Git Service

add_new_casper_for_chain (#1931)
[bytom/bytom.git] / database / store_test.go
1 package database
2
3 import (
4         "os"
5         "testing"
6
7         "github.com/bytom/bytom/config"
8         dbm "github.com/bytom/bytom/database/leveldb"
9         "github.com/bytom/bytom/database/storage"
10         "github.com/bytom/bytom/protocol"
11         "github.com/bytom/bytom/protocol/bc"
12         "github.com/bytom/bytom/protocol/bc/types"
13         "github.com/bytom/bytom/protocol/state"
14         "github.com/bytom/bytom/testutil"
15 )
16
17 func TestLoadBlockIndex(t *testing.T) {
18         defer os.RemoveAll("temp")
19         testDB := dbm.NewDB("testdb", "leveldb", "temp")
20         store := NewStore(testDB)
21
22         block := config.GenesisBlock()
23         if err := store.SaveBlock(block); err != nil {
24                 t.Fatal(err)
25         }
26
27         for block.Height <= 128 {
28                 preHash := block.Hash()
29                 block.PreviousBlockHash = preHash
30                 block.Height++
31                 if err := store.SaveBlock(block); err != nil {
32                         t.Fatal(err)
33                 }
34
35                 if block.Height%32 != 0 {
36                         continue
37                 }
38
39                 for i := uint64(0); i < block.Height/32; i++ {
40                         if err := store.SaveBlock(block); err != nil {
41                                 t.Fatal(err)
42                         }
43                 }
44         }
45
46         if _, err := store.LoadBlockIndex(128); err != nil {
47                 t.Fatal(err)
48         }
49 }
50
51 func TestLoadBlockIndexBestHeight(t *testing.T) {
52         cases := []struct {
53                 blockBestHeight uint64
54                 stateBestHeight uint64
55         }{
56                 {
57                         blockBestHeight: 100,
58                         stateBestHeight: 90,
59                 },
60                 {
61                         blockBestHeight: 100,
62                         stateBestHeight: 0,
63                 },
64                 {
65                         blockBestHeight: 100,
66                         stateBestHeight: 100,
67                 },
68         }
69
70         defer os.RemoveAll("temp")
71         testDB := dbm.NewDB("testdb", "leveldb", "temp")
72         store := NewStore(testDB)
73         var savedBlocks []types.Block
74
75         for _, c := range cases {
76                 block := config.GenesisBlock()
77                 for i := uint64(0); i < c.blockBestHeight; i++ {
78                         if err := store.SaveBlock(block); err != nil {
79                                 t.Fatal(err)
80                         }
81
82                         savedBlocks = append(savedBlocks, *block)
83                         block.PreviousBlockHash = block.Hash()
84                         block.Height++
85                 }
86
87                 index, err := store.LoadBlockIndex(c.stateBestHeight)
88                 if err != nil {
89                         t.Fatal(err)
90                 }
91
92                 for _, block := range savedBlocks {
93                         blockHash := block.Hash()
94                         if existIndex := index.BlockExist(&blockHash); (block.Height <= c.stateBestHeight) != existIndex {
95                                 t.Errorf("Error in load block index")
96                         }
97                 }
98         }
99 }
100
101 func TestLoadBlockIndexEquals(t *testing.T) {
102         defer os.RemoveAll("temp")
103         testDB := dbm.NewDB("testdb", "leveldb", "temp")
104         store := NewStore(testDB)
105
106         block := config.GenesisBlock()
107         expectBlockIndex := state.NewBlockIndex()
108         var parent *state.BlockNode
109
110         for block.Height <= 100 {
111                 if err := store.SaveBlock(block); err != nil {
112                         t.Fatal(err)
113                 }
114
115                 if block.Height != 0 {
116                         parent = expectBlockIndex.GetNode(&block.PreviousBlockHash)
117                 }
118
119                 node, err := state.NewBlockNode(&block.BlockHeader, parent)
120                 if err != nil {
121                         t.Fatal(err)
122                 }
123
124                 expectBlockIndex.AddNode(node)
125                 block.PreviousBlockHash = block.Hash()
126                 block.Height++
127         }
128
129         index, err := store.LoadBlockIndex(100)
130         if err != nil {
131                 t.Fatal(err)
132         }
133
134         if !testutil.DeepEqual(expectBlockIndex, index) {
135                 t.Errorf("got block index:%v, expect block index:%v", index, expectBlockIndex)
136         }
137 }
138
139 func TestSaveChainStatus(t *testing.T) {
140         defer os.RemoveAll("temp")
141         testDB := dbm.NewDB("testdb", "leveldb", "temp")
142         store := NewStore(testDB)
143
144         node := &state.BlockNode{Height: 100, Hash: bc.Hash{V0: 0, V1: 1, V2: 2, V3: 3}}
145         view := &state.UtxoViewpoint{
146                 Entries: map[bc.Hash]*storage.UtxoEntry{
147                         bc.Hash{V0: 1, V1: 2, V2: 3, V3: 4}: &storage.UtxoEntry{IsCoinBase: false, BlockHeight: 100, Spent: false},
148                         bc.Hash{V0: 1, V1: 2, V2: 3, V3: 4}: &storage.UtxoEntry{IsCoinBase: true, BlockHeight: 100, Spent: true},
149                         bc.Hash{V0: 1, V1: 1, V2: 3, V3: 4}: &storage.UtxoEntry{IsCoinBase: false, BlockHeight: 100, Spent: true},
150                 },
151         }
152
153         contractView := state.NewContractViewpoint()
154         if err := store.SaveChainStatus(node, view, contractView, 0, &bc.Hash{}); err != nil {
155                 t.Fatal(err)
156         }
157
158         expectStatus := &protocol.BlockStoreState{Height: node.Height, Hash: &node.Hash, FinalizedHeight: 0, FinalizedHash: &bc.Hash{}}
159         if !testutil.DeepEqual(store.GetStoreStatus(), expectStatus) {
160                 t.Errorf("got block status:%v, expect block status:%v", store.GetStoreStatus(), expectStatus)
161         }
162
163         for hash, utxo := range view.Entries {
164                 if utxo.Spent && !utxo.IsCoinBase {
165                         continue
166                 }
167
168                 gotUtxo, err := store.GetUtxo(&hash)
169                 if err != nil {
170                         t.Fatal(err)
171                 }
172
173                 if !testutil.DeepEqual(utxo, gotUtxo) {
174                         t.Errorf("got utxo entry:%v, expect utxo entry:%v", gotUtxo, utxo)
175                 }
176         }
177 }
178
179 func TestSaveBlock(t *testing.T) {
180         testDB := dbm.NewDB("testdb", "leveldb", "temp")
181         defer func() {
182                 testDB.Close()
183                 os.RemoveAll("temp")
184         }()
185
186         store := NewStore(testDB)
187         block := config.GenesisBlock()
188         if err := store.SaveBlock(block); err != nil {
189                 t.Fatal(err)
190         }
191
192         blockHash := block.Hash()
193         gotBlock, err := store.GetBlock(&blockHash)
194         if err != nil {
195                 t.Fatal(err)
196         }
197
198         gotBlock.Transactions[0].Tx.SerializedSize = 0
199         gotBlock.Transactions[0].SerializedSize = 0
200         if !testutil.DeepEqual(block, gotBlock) {
201                 t.Errorf("got block:%v, expect block:%v", gotBlock, block)
202         }
203
204         data := store.db.Get(CalcBlockHeaderIndexKey(block.Height, &blockHash))
205         gotBlockHeader := types.BlockHeader{}
206         if err := gotBlockHeader.UnmarshalText(data); err != nil {
207                 t.Fatal(err)
208         }
209
210         if !testutil.DeepEqual(block.BlockHeader, gotBlockHeader) {
211                 t.Errorf("got block header:%v, expect block header:%v", gotBlockHeader, block.BlockHeader)
212         }
213 }
214