OSDN Git Service

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