6 "github.com/vapor/consensus"
7 "github.com/vapor/database/storage"
8 "github.com/vapor/protocol/bc"
9 "github.com/vapor/testutil"
12 var defaultEntry = map[bc.Hash]bc.Entry{
13 bc.Hash{V0: 0}: &bc.IntraChainOutput{
14 Source: &bc.ValueSource{
15 Value: &bc.AssetAmount{
16 AssetId: &bc.AssetID{V0: 0},
22 var coinbaseEntry = map[bc.Hash]bc.Entry{
23 bc.Hash{V0: 0}: &bc.IntraChainOutput{
24 Source: &bc.ValueSource{
25 Value: &bc.AssetAmount{
26 AssetId: consensus.BTMAssetID,
30 bc.Hash{V0: 1}: &bc.IntraChainOutput{
31 Source: &bc.ValueSource{
32 Value: &bc.AssetAmount{
33 AssetId: consensus.BTMAssetID,
40 var voteEntry = map[bc.Hash]bc.Entry{
41 bc.Hash{V0: 0}: &bc.VoteOutput{
42 Source: &bc.ValueSource{
43 Value: &bc.AssetAmount{
44 AssetId: &bc.AssetID{V0: 0},
50 var gasOnlyTxEntry = map[bc.Hash]bc.Entry{
51 bc.Hash{V1: 0}: &bc.IntraChainOutput{
52 Source: &bc.ValueSource{
53 Value: &bc.AssetAmount{
54 AssetId: consensus.BTMAssetID,
58 bc.Hash{V1: 1}: &bc.IntraChainOutput{
59 Source: &bc.ValueSource{
60 Value: &bc.AssetAmount{
61 AssetId: &bc.AssetID{V0: 999},
67 func TestApplyBlock(t *testing.T) {
70 inputView *UtxoViewpoint
71 fetchView *UtxoViewpoint
76 // can't find prevout in tx entries
78 BlockHeader: &bc.BlockHeader{
79 TransactionStatus: bc.NewTransactionStatus(),
81 Transactions: []*bc.Tx{
83 SpentOutputIDs: []bc.Hash{
86 Entries: defaultEntry,
90 inputView: &UtxoViewpoint{
91 Entries: map[bc.Hash]*storage.UtxoEntry{
92 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, false),
95 fetchView: NewUtxoViewpoint(),
100 BlockHeader: &bc.BlockHeader{
101 TransactionStatus: bc.NewTransactionStatus(),
103 Transactions: []*bc.Tx{
105 SpentOutputIDs: []bc.Hash{
108 Entries: defaultEntry,
112 inputView: NewUtxoViewpoint(),
113 fetchView: NewUtxoViewpoint(),
118 BlockHeader: &bc.BlockHeader{
119 TransactionStatus: bc.NewTransactionStatus(),
121 Transactions: []*bc.Tx{
123 SpentOutputIDs: []bc.Hash{
126 Entries: defaultEntry,
130 inputView: &UtxoViewpoint{
131 Entries: map[bc.Hash]*storage.UtxoEntry{
132 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, true),
139 BlockHeader: &bc.BlockHeader{
140 TransactionStatus: bc.NewTransactionStatus(),
142 Transactions: []*bc.Tx{
144 TxHeader: &bc.TxHeader{
145 ResultIds: []*bc.Hash{},
147 SpentOutputIDs: []bc.Hash{
150 Entries: defaultEntry,
154 inputView: &UtxoViewpoint{
155 Entries: map[bc.Hash]*storage.UtxoEntry{
156 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, false),
159 fetchView: &UtxoViewpoint{
160 Entries: map[bc.Hash]*storage.UtxoEntry{
161 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, true),
168 BlockHeader: &bc.BlockHeader{
169 Height: consensus.MainNetParams.CoinbasePendingBlockNumber + 1,
170 TransactionStatus: bc.NewTransactionStatus(),
172 Transactions: []*bc.Tx{
174 TxHeader: &bc.TxHeader{
175 ResultIds: []*bc.Hash{},
177 SpentOutputIDs: []bc.Hash{
180 Entries: defaultEntry,
184 inputView: &UtxoViewpoint{
185 Entries: map[bc.Hash]*storage.UtxoEntry{
186 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.CoinbaseUTXOType, 0, false),
189 fetchView: &UtxoViewpoint{
190 Entries: map[bc.Hash]*storage.UtxoEntry{
191 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.CoinbaseUTXOType, 0, true),
198 BlockHeader: &bc.BlockHeader{
200 TransactionStatus: bc.NewTransactionStatus(),
202 Transactions: []*bc.Tx{
204 TxHeader: &bc.TxHeader{
205 ResultIds: []*bc.Hash{},
207 SpentOutputIDs: []bc.Hash{
210 Entries: defaultEntry,
214 inputView: &UtxoViewpoint{
215 Entries: map[bc.Hash]*storage.UtxoEntry{
216 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.CoinbaseUTXOType, 0, false),
219 fetchView: &UtxoViewpoint{
220 Entries: map[bc.Hash]*storage.UtxoEntry{
221 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.CoinbaseUTXOType, 0, true),
227 // output will be store
229 BlockHeader: &bc.BlockHeader{
230 TransactionStatus: bc.NewTransactionStatus(),
232 Transactions: []*bc.Tx{
234 TxHeader: &bc.TxHeader{
235 ResultIds: []*bc.Hash{
240 SpentOutputIDs: []bc.Hash{},
241 Entries: coinbaseEntry,
245 inputView: NewUtxoViewpoint(),
246 fetchView: &UtxoViewpoint{
247 Entries: map[bc.Hash]*storage.UtxoEntry{
248 bc.Hash{V0: 1}: storage.NewUtxoEntry(storage.CoinbaseUTXOType, 0, false),
254 // apply gas only tx, non-btm asset spent input will not be spent
256 BlockHeader: &bc.BlockHeader{
257 TransactionStatus: bc.NewTransactionStatus(),
259 Transactions: []*bc.Tx{
261 TxHeader: &bc.TxHeader{
262 ResultIds: []*bc.Hash{},
264 SpentOutputIDs: []bc.Hash{
268 Entries: gasOnlyTxEntry,
272 inputView: &UtxoViewpoint{
273 Entries: map[bc.Hash]*storage.UtxoEntry{
274 bc.Hash{V1: 0}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, false),
275 bc.Hash{V1: 1}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, false),
278 fetchView: &UtxoViewpoint{
279 Entries: map[bc.Hash]*storage.UtxoEntry{
280 bc.Hash{V1: 0}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, true),
281 bc.Hash{V1: 1}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, false),
288 // apply gas only tx, non-btm asset spent output will not be store
290 BlockHeader: &bc.BlockHeader{
291 TransactionStatus: bc.NewTransactionStatus(),
293 Transactions: []*bc.Tx{
295 TxHeader: &bc.TxHeader{
296 ResultIds: []*bc.Hash{
301 SpentOutputIDs: []bc.Hash{},
302 Entries: gasOnlyTxEntry,
306 inputView: NewUtxoViewpoint(),
307 fetchView: NewUtxoViewpoint(),
313 BlockHeader: &bc.BlockHeader{
314 TransactionStatus: bc.NewTransactionStatus(),
316 Transactions: []*bc.Tx{
318 TxHeader: &bc.TxHeader{
319 ResultIds: []*bc.Hash{},
321 SpentOutputIDs: []bc.Hash{
328 inputView: &UtxoViewpoint{
329 Entries: map[bc.Hash]*storage.UtxoEntry{
330 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.VoteUTXOType, 0, false),
333 fetchView: &UtxoViewpoint{
334 Entries: map[bc.Hash]*storage.UtxoEntry{
335 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.VoteUTXOType, 0, true),
342 BlockHeader: &bc.BlockHeader{
343 Height: consensus.MainNetParams.VotePendingBlockNumber + 1,
344 TransactionStatus: bc.NewTransactionStatus(),
346 Transactions: []*bc.Tx{
348 TxHeader: &bc.TxHeader{
349 ResultIds: []*bc.Hash{},
351 SpentOutputIDs: []bc.Hash{
358 inputView: &UtxoViewpoint{
359 Entries: map[bc.Hash]*storage.UtxoEntry{
360 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.VoteUTXOType, 1, false),
363 fetchView: &UtxoViewpoint{
364 Entries: map[bc.Hash]*storage.UtxoEntry{
365 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.VoteUTXOType, 1, true),
372 for i, c := range cases {
373 c.block.TransactionStatus.SetStatus(0, c.gasOnlyTx)
374 if err := c.inputView.ApplyBlock(c.block, c.block.TransactionStatus); c.err != (err != nil) {
375 t.Errorf("case #%d want err = %v, get err = %v", i, c.err, err)
380 if !testutil.DeepEqual(c.inputView, c.fetchView) {
381 t.Errorf("test case %d, want %v, get %v", i, c.fetchView, c.inputView)
386 func TestDetachBlock(t *testing.T) {
389 inputView *UtxoViewpoint
390 fetchView *UtxoViewpoint
396 BlockHeader: &bc.BlockHeader{
397 TransactionStatus: bc.NewTransactionStatus(),
399 Transactions: []*bc.Tx{
401 TxHeader: &bc.TxHeader{
402 ResultIds: []*bc.Hash{},
404 SpentOutputIDs: []bc.Hash{
407 Entries: defaultEntry,
411 inputView: NewUtxoViewpoint(),
412 fetchView: &UtxoViewpoint{
413 Entries: map[bc.Hash]*storage.UtxoEntry{
414 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, false),
421 BlockHeader: &bc.BlockHeader{
422 TransactionStatus: bc.NewTransactionStatus(),
424 Transactions: []*bc.Tx{
426 TxHeader: &bc.TxHeader{
427 ResultIds: []*bc.Hash{
432 SpentOutputIDs: []bc.Hash{},
433 Entries: coinbaseEntry,
437 inputView: &UtxoViewpoint{
438 Entries: map[bc.Hash]*storage.UtxoEntry{
439 bc.Hash{V0: 1}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, false),
442 fetchView: &UtxoViewpoint{
443 Entries: map[bc.Hash]*storage.UtxoEntry{
444 bc.Hash{V0: 1}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, true),
451 BlockHeader: &bc.BlockHeader{
452 TransactionStatus: bc.NewTransactionStatus(),
454 Transactions: []*bc.Tx{
456 TxHeader: &bc.TxHeader{
457 ResultIds: []*bc.Hash{},
459 SpentOutputIDs: []bc.Hash{
462 Entries: defaultEntry,
466 inputView: &UtxoViewpoint{
467 Entries: map[bc.Hash]*storage.UtxoEntry{
468 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, false),
475 BlockHeader: &bc.BlockHeader{
476 TransactionStatus: bc.NewTransactionStatus(),
478 Transactions: []*bc.Tx{
480 TxHeader: &bc.TxHeader{
481 ResultIds: []*bc.Hash{},
483 SpentOutputIDs: []bc.Hash{
486 Entries: defaultEntry,
490 inputView: &UtxoViewpoint{
491 Entries: map[bc.Hash]*storage.UtxoEntry{
492 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, true),
495 fetchView: &UtxoViewpoint{
496 Entries: map[bc.Hash]*storage.UtxoEntry{
497 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, false),
504 BlockHeader: &bc.BlockHeader{
505 TransactionStatus: bc.NewTransactionStatus(),
507 Transactions: []*bc.Tx{
509 TxHeader: &bc.TxHeader{
510 ResultIds: []*bc.Hash{},
512 SpentOutputIDs: []bc.Hash{
516 Entries: gasOnlyTxEntry,
520 inputView: &UtxoViewpoint{
521 Entries: map[bc.Hash]*storage.UtxoEntry{
522 bc.Hash{V1: 0}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, true),
523 bc.Hash{V1: 1}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, true),
526 fetchView: &UtxoViewpoint{
527 Entries: map[bc.Hash]*storage.UtxoEntry{
528 bc.Hash{V1: 0}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, false),
529 bc.Hash{V1: 1}: storage.NewUtxoEntry(storage.NormalUTXOType, 0, true),
537 BlockHeader: &bc.BlockHeader{
538 TransactionStatus: bc.NewTransactionStatus(),
540 Transactions: []*bc.Tx{
542 TxHeader: &bc.TxHeader{
543 ResultIds: []*bc.Hash{
548 SpentOutputIDs: []bc.Hash{},
549 Entries: gasOnlyTxEntry,
553 inputView: NewUtxoViewpoint(),
554 fetchView: NewUtxoViewpoint(),
560 BlockHeader: &bc.BlockHeader{
561 TransactionStatus: bc.NewTransactionStatus(),
563 Transactions: []*bc.Tx{
565 TxHeader: &bc.TxHeader{
566 ResultIds: []*bc.Hash{},
568 SpentOutputIDs: []bc.Hash{
575 inputView: NewUtxoViewpoint(),
576 fetchView: &UtxoViewpoint{
577 Entries: map[bc.Hash]*storage.UtxoEntry{
578 bc.Hash{V0: 0}: storage.NewUtxoEntry(storage.VoteUTXOType, 0, false),
585 for i, c := range cases {
586 c.block.TransactionStatus.SetStatus(0, c.gasOnlyTx)
587 if err := c.inputView.DetachBlock(c.block, c.block.TransactionStatus); c.err != (err != nil) {
588 t.Errorf("case %d want err = %v, get err = %v", i, c.err, err)
593 if !testutil.DeepEqual(c.inputView, c.fetchView) {
594 t.Errorf("test case %d, want %v, get %v", i, c.fetchView, c.inputView)