OSDN Git Service

add test case for not btm (#1616)
[bytom/bytom.git] / test / utxo_view / utxo_view_test.go
1 package utxo_view
2
3 import (
4         "os"
5         "testing"
6
7         "github.com/bytom/testutil"
8
9         "github.com/golang/protobuf/proto"
10         dbm "github.com/tendermint/tmlibs/db"
11
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"
17 )
18
19 func TestAttachOrDetachBlocks(t *testing.T) {
20         cases := []struct {
21                 desc           string
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
28         }{
29                 {
30                         desc:   "coinbase tx",
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),
35                         },
36                         attachTxStatus: []*bc.TransactionStatus{
37                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
38                                         &bc.TxVerifyResult{StatusFail: false},
39                                 }},
40                         },
41                 },
42                 {
43                         desc: "Chain trading 3",
44                         before: map[bc.Hash]*storage.UtxoEntry{
45                                 newTx(mockBlocks[1].Transactions[1]).getSpentOutputID(0): storage.NewUtxoEntry(false, mockBlocks[1].Height-1, false),
46                         },
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),
53                         },
54                         attachBlock: []*bc.Block{
55                                 types.MapBlock(&mockBlocks[1].Block),
56                         },
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},
63                                 }},
64                         },
65                 },
66                 {
67                         desc: "detach 1 block, attach 2 block",
68                         before: map[bc.Hash]*storage.UtxoEntry{
69                                 *newTx(mockBlocks[2].Transactions[0]).OutputHash(0): storage.NewUtxoEntry(true, mockBlocks[2].Height, false),
70                                 *newTx(mockBlocks[2].Transactions[1]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[2].Height, false),
71                                 *newTx(mockBlocks[2].Transactions[1]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[2].Height, false),
72                         },
73                         want: map[bc.Hash]*storage.UtxoEntry{
74                                 *newTx(mockBlocks[3].Transactions[0]).OutputHash(0): storage.NewUtxoEntry(true, mockBlocks[3].Height, false),
75                                 *newTx(mockBlocks[3].Transactions[1]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[3].Height, false),
76
77                                 *newTx(mockBlocks[4].Transactions[0]).OutputHash(0): storage.NewUtxoEntry(true, mockBlocks[4].Height, false),
78                                 *newTx(mockBlocks[4].Transactions[1]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[4].Height, false),
79                                 *newTx(mockBlocks[4].Transactions[1]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[4].Height, false),
80                         },
81                         attachBlock: []*bc.Block{
82                                 types.MapBlock(&mockBlocks[3].Block),
83                                 types.MapBlock(&mockBlocks[4].Block),
84                         },
85                         detachBlock: []*bc.Block{
86                                 types.MapBlock(&mockBlocks[2].Block),
87                         },
88                         attachTxStatus: []*bc.TransactionStatus{
89                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
90                                         &bc.TxVerifyResult{StatusFail: false},
91                                         &bc.TxVerifyResult{StatusFail: false},
92                                 }},
93                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
94                                         &bc.TxVerifyResult{StatusFail: false},
95                                         &bc.TxVerifyResult{StatusFail: false},
96                                 }},
97                         },
98                         detachTxStatus: []*bc.TransactionStatus{
99                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
100                                         &bc.TxVerifyResult{StatusFail: false},
101                                         &bc.TxVerifyResult{StatusFail: false},
102                                 }},
103                         },
104                 },
105                 {
106                         desc: "detach block 5, attach block 6",
107                         before: map[bc.Hash]*storage.UtxoEntry{
108                                 *newTx(mockBlocks[5].Transactions[0]).OutputHash(0): storage.NewUtxoEntry(true, mockBlocks[5].Height, false),
109                                 *newTx(mockBlocks[5].Transactions[1]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[5].Height, false),
110                                 *newTx(mockBlocks[5].Transactions[1]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[5].Height, false),
111
112                                 *newTx(mockBlocks[6].Transactions[0]).OutputHash(0): storage.NewUtxoEntry(true, mockBlocks[6].Height, false),
113                                 *newTx(mockBlocks[6].Transactions[1]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[6].Height, false),
114                                 *newTx(mockBlocks[6].Transactions[1]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[6].Height, false),
115                                 *newTx(mockBlocks[6].Transactions[1]).OutputHash(2): storage.NewUtxoEntry(false, mockBlocks[6].Height, false),
116                                 *newTx(mockBlocks[6].Transactions[1]).OutputHash(3): storage.NewUtxoEntry(false, mockBlocks[6].Height, false),
117                                 *newTx(mockBlocks[6].Transactions[2]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[6].Height, false),
118                                 *newTx(mockBlocks[6].Transactions[2]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[6].Height, false),
119                                 *newTx(mockBlocks[6].Transactions[2]).OutputHash(2): storage.NewUtxoEntry(false, mockBlocks[6].Height, false),
120                                 *newTx(mockBlocks[6].Transactions[2]).OutputHash(3): storage.NewUtxoEntry(false, mockBlocks[6].Height, false),
121
122                                 *newTx(mockBlocks[7].Transactions[0]).OutputHash(0): storage.NewUtxoEntry(true, mockBlocks[7].Height, false),
123                                 *newTx(mockBlocks[7].Transactions[1]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[7].Height, false),
124                                 *newTx(mockBlocks[7].Transactions[1]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[7].Height, false),
125                                 *newTx(mockBlocks[7].Transactions[1]).OutputHash(2): storage.NewUtxoEntry(false, mockBlocks[7].Height, false),
126                                 *newTx(mockBlocks[7].Transactions[1]).OutputHash(3): storage.NewUtxoEntry(false, mockBlocks[7].Height, false),
127
128                                 *newTx(mockBlocks[8].Transactions[0]).OutputHash(0): storage.NewUtxoEntry(true, mockBlocks[8].Height, false),
129                                 *newTx(mockBlocks[8].Transactions[1]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[8].Height, false),
130                                 *newTx(mockBlocks[8].Transactions[1]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[8].Height, false),
131                                 *newTx(mockBlocks[8].Transactions[1]).OutputHash(2): storage.NewUtxoEntry(false, mockBlocks[8].Height, false),
132                                 *newTx(mockBlocks[8].Transactions[1]).OutputHash(3): storage.NewUtxoEntry(false, mockBlocks[8].Height, false),
133                                 *newTx(mockBlocks[8].Transactions[2]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[8].Height, false),
134                                 *newTx(mockBlocks[8].Transactions[2]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[8].Height, false),
135                                 *newTx(mockBlocks[8].Transactions[3]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[8].Height, false),
136                                 *newTx(mockBlocks[8].Transactions[3]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[8].Height, false),
137
138                                 *newTx(mockBlocks[9].Transactions[0]).OutputHash(0): storage.NewUtxoEntry(true, mockBlocks[9].Height, false),
139                                 *newTx(mockBlocks[9].Transactions[1]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[9].Height, false),
140                                 *newTx(mockBlocks[9].Transactions[1]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[9].Height, false),
141                         },
142                         want: map[bc.Hash]*storage.UtxoEntry{
143                                 *newTx(mockBlocks[10].Transactions[0]).OutputHash(0): storage.NewUtxoEntry(true, mockBlocks[10].Height, false),
144                                 *newTx(mockBlocks[10].Transactions[1]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
145                                 *newTx(mockBlocks[10].Transactions[1]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
146                                 *newTx(mockBlocks[10].Transactions[2]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
147                                 *newTx(mockBlocks[10].Transactions[2]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
148                                 *newTx(mockBlocks[10].Transactions[2]).OutputHash(2): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
149                                 *newTx(mockBlocks[10].Transactions[2]).OutputHash(3): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
150                                 *newTx(mockBlocks[10].Transactions[3]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
151                                 *newTx(mockBlocks[10].Transactions[3]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
152                                 *newTx(mockBlocks[10].Transactions[3]).OutputHash(2): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
153                                 *newTx(mockBlocks[10].Transactions[3]).OutputHash(3): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
154                                 *newTx(mockBlocks[10].Transactions[4]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
155                                 *newTx(mockBlocks[10].Transactions[4]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
156                                 *newTx(mockBlocks[10].Transactions[4]).OutputHash(2): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
157                                 *newTx(mockBlocks[10].Transactions[4]).OutputHash(3): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
158                                 *newTx(mockBlocks[10].Transactions[5]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
159                                 *newTx(mockBlocks[10].Transactions[5]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
160                                 *newTx(mockBlocks[10].Transactions[5]).OutputHash(2): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
161                                 *newTx(mockBlocks[10].Transactions[5]).OutputHash(3): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
162
163                                 *newTx(mockBlocks[11].Transactions[0]).OutputHash(0): storage.NewUtxoEntry(true, mockBlocks[11].Height, false),
164                                 *newTx(mockBlocks[11].Transactions[1]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[11].Height, false),
165                                 *newTx(mockBlocks[11].Transactions[1]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[11].Height, false),
166                                 *newTx(mockBlocks[11].Transactions[2]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[11].Height, false),
167                                 *newTx(mockBlocks[11].Transactions[2]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[11].Height, false),
168                                 *newTx(mockBlocks[11].Transactions[3]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[11].Height, false),
169                                 *newTx(mockBlocks[11].Transactions[3]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[11].Height, false),
170                         },
171                         attachBlock: []*bc.Block{
172                                 types.MapBlock(&mockBlocks[10].Block),
173                                 types.MapBlock(&mockBlocks[11].Block),
174                         },
175                         detachBlock: []*bc.Block{
176                                 types.MapBlock(&mockBlocks[9].Block),
177                                 types.MapBlock(&mockBlocks[8].Block),
178                                 types.MapBlock(&mockBlocks[7].Block),
179                                 types.MapBlock(&mockBlocks[6].Block),
180                                 types.MapBlock(&mockBlocks[5].Block),
181                         },
182                         attachTxStatus: []*bc.TransactionStatus{
183                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
184                                         &bc.TxVerifyResult{StatusFail: false},
185                                         &bc.TxVerifyResult{StatusFail: false},
186                                         &bc.TxVerifyResult{StatusFail: false},
187                                         &bc.TxVerifyResult{StatusFail: false},
188                                         &bc.TxVerifyResult{StatusFail: false},
189                                         &bc.TxVerifyResult{StatusFail: false},
190                                 }},
191                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
192                                         &bc.TxVerifyResult{StatusFail: false},
193                                         &bc.TxVerifyResult{StatusFail: false},
194                                         &bc.TxVerifyResult{StatusFail: false},
195                                         &bc.TxVerifyResult{StatusFail: false},
196                                         &bc.TxVerifyResult{StatusFail: false},
197                                 }},
198                         },
199                         detachTxStatus: []*bc.TransactionStatus{
200
201                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
202                                         &bc.TxVerifyResult{StatusFail: false},
203                                         &bc.TxVerifyResult{StatusFail: false},
204                                 }},
205                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
206                                         &bc.TxVerifyResult{StatusFail: false},
207                                         &bc.TxVerifyResult{StatusFail: false},
208                                         &bc.TxVerifyResult{StatusFail: false},
209                                         &bc.TxVerifyResult{StatusFail: false},
210                                 }},
211                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
212                                         &bc.TxVerifyResult{StatusFail: false},
213                                         &bc.TxVerifyResult{StatusFail: false},
214                                 }},
215                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
216                                         &bc.TxVerifyResult{StatusFail: false},
217                                         &bc.TxVerifyResult{StatusFail: false},
218                                         &bc.TxVerifyResult{StatusFail: false},
219                                 }},
220                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
221                                         &bc.TxVerifyResult{StatusFail: false},
222                                         &bc.TxVerifyResult{StatusFail: false},
223                                 }},
224                         },
225                 },
226                 {
227                         desc: "detach block 5, attach block 6. Other asset deals failed.",
228                         before: map[bc.Hash]*storage.UtxoEntry{
229                                 *newTx(mockBlocks[5].Transactions[0]).OutputHash(0): storage.NewUtxoEntry(true, mockBlocks[5].Height, false),
230                                 *newTx(mockBlocks[5].Transactions[1]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[5].Height, false),
231                                 *newTx(mockBlocks[5].Transactions[1]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[5].Height, false),
232
233                                 *newTx(mockBlocks[6].Transactions[0]).OutputHash(0):      storage.NewUtxoEntry(true, mockBlocks[6].Height, false),
234                                 *newTx(mockBlocks[6].Transactions[1]).OutputHash(0):      storage.NewUtxoEntry(false, mockBlocks[6].Height, false),
235                                 *newTx(mockBlocks[6].Transactions[1]).OutputHash(1):      storage.NewUtxoEntry(false, mockBlocks[6].Height, false),
236                                 newTx(mockBlocks[6].Transactions[1]).getSpentOutputID(1): storage.NewUtxoEntry(false, mockBlocks[6].Height-1, false),
237
238                                 *newTx(mockBlocks[6].Transactions[2]).OutputHash(0):      storage.NewUtxoEntry(false, mockBlocks[6].Height, false),
239                                 *newTx(mockBlocks[6].Transactions[2]).OutputHash(1):      storage.NewUtxoEntry(false, mockBlocks[6].Height, false),
240                                 newTx(mockBlocks[6].Transactions[2]).getSpentOutputID(1): storage.NewUtxoEntry(false, mockBlocks[6].Height-1, false),
241
242                                 *newTx(mockBlocks[7].Transactions[0]).OutputHash(0):      storage.NewUtxoEntry(true, mockBlocks[7].Height, false),
243                                 *newTx(mockBlocks[7].Transactions[1]).OutputHash(0):      storage.NewUtxoEntry(false, mockBlocks[7].Height, false),
244                                 *newTx(mockBlocks[7].Transactions[1]).OutputHash(1):      storage.NewUtxoEntry(false, mockBlocks[7].Height, false),
245                                 newTx(mockBlocks[7].Transactions[1]).getSpentOutputID(1): storage.NewUtxoEntry(false, mockBlocks[7].Height-1, false),
246
247                                 *newTx(mockBlocks[8].Transactions[0]).OutputHash(0):      storage.NewUtxoEntry(true, mockBlocks[8].Height, false),
248                                 *newTx(mockBlocks[8].Transactions[1]).OutputHash(0):      storage.NewUtxoEntry(false, mockBlocks[8].Height, false),
249                                 *newTx(mockBlocks[8].Transactions[1]).OutputHash(1):      storage.NewUtxoEntry(false, mockBlocks[8].Height, false),
250                                 newTx(mockBlocks[8].Transactions[1]).getSpentOutputID(1): storage.NewUtxoEntry(false, mockBlocks[8].Height-1, false),
251
252                                 *newTx(mockBlocks[8].Transactions[2]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[8].Height, false),
253                                 *newTx(mockBlocks[8].Transactions[2]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[8].Height, false),
254                                 *newTx(mockBlocks[8].Transactions[3]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[8].Height, false),
255                                 *newTx(mockBlocks[8].Transactions[3]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[8].Height, false),
256
257                                 *newTx(mockBlocks[9].Transactions[0]).OutputHash(0): storage.NewUtxoEntry(true, mockBlocks[9].Height, false),
258                                 *newTx(mockBlocks[9].Transactions[1]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[9].Height, false),
259                                 *newTx(mockBlocks[9].Transactions[1]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[9].Height, false),
260                         },
261                         want: map[bc.Hash]*storage.UtxoEntry{
262
263                                 *newTx(mockBlocks[10].Transactions[0]).OutputHash(0): storage.NewUtxoEntry(true, mockBlocks[10].Height, false),
264                                 *newTx(mockBlocks[10].Transactions[1]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
265                                 *newTx(mockBlocks[10].Transactions[1]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
266
267                                 *newTx(mockBlocks[10].Transactions[2]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
268                                 *newTx(mockBlocks[10].Transactions[2]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
269                                 *newTx(mockBlocks[10].Transactions[2]).OutputHash(2): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
270                                 *newTx(mockBlocks[10].Transactions[2]).OutputHash(3): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
271
272                                 *newTx(mockBlocks[10].Transactions[3]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
273                                 *newTx(mockBlocks[10].Transactions[3]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
274                                 *newTx(mockBlocks[10].Transactions[3]).OutputHash(2): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
275                                 *newTx(mockBlocks[10].Transactions[3]).OutputHash(3): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
276
277                                 *newTx(mockBlocks[10].Transactions[4]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
278                                 *newTx(mockBlocks[10].Transactions[4]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
279                                 *newTx(mockBlocks[10].Transactions[4]).OutputHash(2): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
280                                 *newTx(mockBlocks[10].Transactions[4]).OutputHash(3): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
281                                 *newTx(mockBlocks[10].Transactions[5]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
282                                 *newTx(mockBlocks[10].Transactions[5]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
283                                 *newTx(mockBlocks[10].Transactions[5]).OutputHash(2): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
284                                 *newTx(mockBlocks[10].Transactions[5]).OutputHash(3): storage.NewUtxoEntry(false, mockBlocks[10].Height, false),
285
286                                 *newTx(mockBlocks[11].Transactions[0]).OutputHash(0): storage.NewUtxoEntry(true, mockBlocks[11].Height, false),
287                                 *newTx(mockBlocks[11].Transactions[1]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[11].Height, false),
288                                 *newTx(mockBlocks[11].Transactions[1]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[11].Height, false),
289                                 *newTx(mockBlocks[11].Transactions[2]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[11].Height, false),
290                                 *newTx(mockBlocks[11].Transactions[2]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[11].Height, false),
291                                 *newTx(mockBlocks[11].Transactions[3]).OutputHash(0): storage.NewUtxoEntry(false, mockBlocks[11].Height, false),
292                                 *newTx(mockBlocks[11].Transactions[3]).OutputHash(1): storage.NewUtxoEntry(false, mockBlocks[11].Height, false),
293                         },
294                         attachBlock: []*bc.Block{
295                                 types.MapBlock(&mockBlocks[10].Block),
296                                 types.MapBlock(&mockBlocks[11].Block),
297                         },
298                         detachBlock: []*bc.Block{
299                                 types.MapBlock(&mockBlocks[9].Block),
300                                 types.MapBlock(&mockBlocks[8].Block),
301                                 types.MapBlock(&mockBlocks[7].Block),
302                                 types.MapBlock(&mockBlocks[6].Block),
303                                 types.MapBlock(&mockBlocks[5].Block),
304                         },
305                         attachTxStatus: []*bc.TransactionStatus{
306                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
307                                         &bc.TxVerifyResult{StatusFail: false},
308                                         &bc.TxVerifyResult{StatusFail: false},
309                                         &bc.TxVerifyResult{StatusFail: false},
310                                         &bc.TxVerifyResult{StatusFail: false},
311                                         &bc.TxVerifyResult{StatusFail: false},
312                                         &bc.TxVerifyResult{StatusFail: false},
313                                 }},
314                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
315                                         &bc.TxVerifyResult{StatusFail: false},
316                                         &bc.TxVerifyResult{StatusFail: false},
317                                         &bc.TxVerifyResult{StatusFail: false},
318                                         &bc.TxVerifyResult{StatusFail: false},
319                                         &bc.TxVerifyResult{StatusFail: false},
320                                 }},
321                         },
322                         detachTxStatus: []*bc.TransactionStatus{
323                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
324                                         &bc.TxVerifyResult{StatusFail: false},
325                                         &bc.TxVerifyResult{StatusFail: false},
326                                 }},
327                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
328                                         &bc.TxVerifyResult{StatusFail: false},
329                                         &bc.TxVerifyResult{StatusFail: true},
330                                         &bc.TxVerifyResult{StatusFail: false},
331                                         &bc.TxVerifyResult{StatusFail: false},
332                                 }},
333                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
334                                         &bc.TxVerifyResult{StatusFail: false},
335                                         &bc.TxVerifyResult{StatusFail: true},
336                                 }},
337                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
338                                         &bc.TxVerifyResult{StatusFail: false},
339                                         &bc.TxVerifyResult{StatusFail: true},
340                                         &bc.TxVerifyResult{StatusFail: true},
341                                 }},
342                                 &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{
343                                         &bc.TxVerifyResult{StatusFail: false},
344                                         &bc.TxVerifyResult{StatusFail: false},
345                                 }},
346                         },
347                 },
348         }
349         node := blockNode(types.MapBlock(&mockBlocks[0].Block).BlockHeader)
350         defer os.RemoveAll("temp")
351         for index, c := range cases {
352                 testDB := dbm.NewDB("testdb", "leveldb", "temp")
353                 store := leveldb.NewStore(testDB)
354
355                 utxoViewpoint := state.NewUtxoViewpoint()
356                 for k, v := range c.before {
357                         utxoViewpoint.Entries[k] = v
358                 }
359                 if err := store.SaveChainStatus(node, utxoViewpoint); err != nil {
360                         t.Error(err)
361                 }
362
363                 utxoViewpoint = state.NewUtxoViewpoint()
364                 for index, block := range c.detachBlock {
365                         if err := store.GetTransactionsUtxo(utxoViewpoint, block.Transactions); err != nil {
366                                 t.Error(err)
367                         }
368                         if err := utxoViewpoint.DetachBlock(block, c.detachTxStatus[index]); err != nil {
369                                 t.Error(err)
370                         }
371                 }
372
373                 for index, block := range c.attachBlock {
374                         if err := store.GetTransactionsUtxo(utxoViewpoint, block.Transactions); err != nil {
375                                 t.Error(err)
376                         }
377                         if err := utxoViewpoint.ApplyBlock(block, c.attachTxStatus[index]); err != nil {
378                                 t.Error(err)
379                         }
380                 }
381                 if err := store.SaveChainStatus(node, utxoViewpoint); err != nil {
382                         t.Error(err)
383                 }
384
385                 want := map[string]*storage.UtxoEntry{}
386                 result := make(map[string]*storage.UtxoEntry)
387
388                 for k, v := range c.want {
389                         want[string(calcUtxoKey(&k))] = v
390                 }
391
392                 iter := testDB.IteratorPrefix([]byte(utxoPreFix))
393                 defer iter.Release()
394
395                 for iter.Next() {
396                         utxoEntry := &storage.UtxoEntry{}
397                         if err := proto.Unmarshal(iter.Value(), utxoEntry); err != nil {
398                                 t.Error(err)
399                         }
400                         key := string(iter.Key())
401                         result[key] = utxoEntry
402                 }
403
404                 if !testutil.DeepEqual(want, result) {
405                         t.Errorf("case [%d] fail. want: %v, result: %v", index, want, result)
406                 }
407                 testDB.Close()
408                 os.RemoveAll("temp")
409         }
410 }