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.Output{
14 Source: &bc.ValueSource{
15 Value: &bc.AssetAmount{
16 AssetId: &bc.AssetID{V0: 0},
22 var gasOnlyTxEntry = map[bc.Hash]bc.Entry{
23 bc.Hash{V1: 0}: &bc.Output{
24 Source: &bc.ValueSource{
25 Value: &bc.AssetAmount{
26 AssetId: consensus.BTMAssetID,
30 bc.Hash{V1: 1}: &bc.Output{
31 Source: &bc.ValueSource{
32 Value: &bc.AssetAmount{
33 AssetId: &bc.AssetID{V0: 999},
39 func TestApplyBlock(t *testing.T) {
42 inputView *UtxoViewpoint
43 fetchView *UtxoViewpoint
48 // can't find prevout in tx entries
50 BlockHeader: &bc.BlockHeader{
51 TransactionStatus: bc.NewTransactionStatus(),
53 Transactions: []*bc.Tx{
55 SpentOutputIDs: []bc.Hash{
58 Entries: defaultEntry,
62 inputView: &UtxoViewpoint{
63 Entries: map[bc.Hash]*storage.UtxoEntry{
64 bc.Hash{V0: 0}: storage.NewUtxoEntry(false, 0, false),
67 fetchView: NewUtxoViewpoint(),
72 BlockHeader: &bc.BlockHeader{
73 TransactionStatus: bc.NewTransactionStatus(),
75 Transactions: []*bc.Tx{
77 SpentOutputIDs: []bc.Hash{
80 Entries: defaultEntry,
84 inputView: NewUtxoViewpoint(),
85 fetchView: NewUtxoViewpoint(),
90 BlockHeader: &bc.BlockHeader{
91 TransactionStatus: bc.NewTransactionStatus(),
93 Transactions: []*bc.Tx{
95 SpentOutputIDs: []bc.Hash{
98 Entries: defaultEntry,
102 inputView: &UtxoViewpoint{
103 Entries: map[bc.Hash]*storage.UtxoEntry{
104 bc.Hash{V0: 0}: storage.NewUtxoEntry(false, 0, true),
111 BlockHeader: &bc.BlockHeader{
112 TransactionStatus: bc.NewTransactionStatus(),
114 Transactions: []*bc.Tx{
116 TxHeader: &bc.TxHeader{
117 ResultIds: []*bc.Hash{},
119 SpentOutputIDs: []bc.Hash{
122 Entries: defaultEntry,
126 inputView: &UtxoViewpoint{
127 Entries: map[bc.Hash]*storage.UtxoEntry{
128 bc.Hash{V0: 0}: storage.NewUtxoEntry(false, 0, false),
131 fetchView: &UtxoViewpoint{
132 Entries: map[bc.Hash]*storage.UtxoEntry{
133 bc.Hash{V0: 0}: storage.NewUtxoEntry(false, 0, true),
140 BlockHeader: &bc.BlockHeader{
142 TransactionStatus: bc.NewTransactionStatus(),
144 Transactions: []*bc.Tx{
146 TxHeader: &bc.TxHeader{
147 ResultIds: []*bc.Hash{},
149 SpentOutputIDs: []bc.Hash{
152 Entries: defaultEntry,
156 inputView: &UtxoViewpoint{
157 Entries: map[bc.Hash]*storage.UtxoEntry{
158 bc.Hash{V0: 0}: storage.NewUtxoEntry(true, 0, false),
161 fetchView: &UtxoViewpoint{
162 Entries: map[bc.Hash]*storage.UtxoEntry{
163 bc.Hash{V0: 0}: storage.NewUtxoEntry(true, 0, true),
170 BlockHeader: &bc.BlockHeader{
172 TransactionStatus: bc.NewTransactionStatus(),
174 Transactions: []*bc.Tx{
176 TxHeader: &bc.TxHeader{
177 ResultIds: []*bc.Hash{},
179 SpentOutputIDs: []bc.Hash{
182 Entries: defaultEntry,
186 inputView: &UtxoViewpoint{
187 Entries: map[bc.Hash]*storage.UtxoEntry{
188 bc.Hash{V0: 0}: storage.NewUtxoEntry(true, 0, false),
191 fetchView: &UtxoViewpoint{
192 Entries: map[bc.Hash]*storage.UtxoEntry{
193 bc.Hash{V0: 0}: storage.NewUtxoEntry(true, 0, true),
199 // output will be store
201 BlockHeader: &bc.BlockHeader{
202 TransactionStatus: bc.NewTransactionStatus(),
204 Transactions: []*bc.Tx{
206 TxHeader: &bc.TxHeader{
207 ResultIds: []*bc.Hash{
211 SpentOutputIDs: []bc.Hash{},
212 Entries: defaultEntry,
216 inputView: NewUtxoViewpoint(),
217 fetchView: &UtxoViewpoint{
218 Entries: map[bc.Hash]*storage.UtxoEntry{
219 bc.Hash{V0: 0}: storage.NewUtxoEntry(true, 0, false),
225 // apply gas only tx, non-btm asset spent input will not be spent
227 BlockHeader: &bc.BlockHeader{
228 TransactionStatus: bc.NewTransactionStatus(),
230 Transactions: []*bc.Tx{
232 TxHeader: &bc.TxHeader{
233 ResultIds: []*bc.Hash{},
235 SpentOutputIDs: []bc.Hash{
239 Entries: gasOnlyTxEntry,
243 inputView: &UtxoViewpoint{
244 Entries: map[bc.Hash]*storage.UtxoEntry{
245 bc.Hash{V1: 0}: storage.NewUtxoEntry(false, 0, false),
246 bc.Hash{V1: 1}: storage.NewUtxoEntry(false, 0, false),
249 fetchView: &UtxoViewpoint{
250 Entries: map[bc.Hash]*storage.UtxoEntry{
251 bc.Hash{V1: 0}: storage.NewUtxoEntry(false, 0, true),
252 bc.Hash{V1: 1}: storage.NewUtxoEntry(false, 0, false),
259 // apply gas only tx, non-btm asset spent output will not be store
261 BlockHeader: &bc.BlockHeader{
262 TransactionStatus: bc.NewTransactionStatus(),
264 Transactions: []*bc.Tx{
266 TxHeader: &bc.TxHeader{
267 ResultIds: []*bc.Hash{
272 SpentOutputIDs: []bc.Hash{},
273 Entries: gasOnlyTxEntry,
277 inputView: NewUtxoViewpoint(),
278 fetchView: &UtxoViewpoint{
279 Entries: map[bc.Hash]*storage.UtxoEntry{
280 bc.Hash{V1: 0}: storage.NewUtxoEntry(true, 0, false),
288 for i, c := range cases {
289 c.block.TransactionStatus.SetStatus(0, c.gasOnlyTx)
290 if err := c.inputView.ApplyBlock(c.block, c.block.TransactionStatus); c.err != (err != nil) {
291 t.Errorf("case #%d want err = %v, get err = %v", i, c.err, err)
296 if !testutil.DeepEqual(c.inputView, c.fetchView) {
297 t.Errorf("test case %d, want %v, get %v", i, c.fetchView, c.inputView)
302 func TestDetachBlock(t *testing.T) {
305 inputView *UtxoViewpoint
306 fetchView *UtxoViewpoint
312 BlockHeader: &bc.BlockHeader{
313 TransactionStatus: bc.NewTransactionStatus(),
315 Transactions: []*bc.Tx{
317 TxHeader: &bc.TxHeader{
318 ResultIds: []*bc.Hash{},
320 SpentOutputIDs: []bc.Hash{
323 Entries: defaultEntry,
327 inputView: NewUtxoViewpoint(),
328 fetchView: &UtxoViewpoint{
329 Entries: map[bc.Hash]*storage.UtxoEntry{
330 bc.Hash{V0: 0}: storage.NewUtxoEntry(false, 0, false),
337 BlockHeader: &bc.BlockHeader{
338 TransactionStatus: bc.NewTransactionStatus(),
340 Transactions: []*bc.Tx{
342 TxHeader: &bc.TxHeader{
343 ResultIds: []*bc.Hash{
347 SpentOutputIDs: []bc.Hash{},
348 Entries: defaultEntry,
352 inputView: NewUtxoViewpoint(),
353 fetchView: &UtxoViewpoint{
354 Entries: map[bc.Hash]*storage.UtxoEntry{
355 bc.Hash{V0: 0}: storage.NewUtxoEntry(false, 0, true),
362 BlockHeader: &bc.BlockHeader{
363 TransactionStatus: bc.NewTransactionStatus(),
365 Transactions: []*bc.Tx{
367 TxHeader: &bc.TxHeader{
368 ResultIds: []*bc.Hash{},
370 SpentOutputIDs: []bc.Hash{
373 Entries: defaultEntry,
377 inputView: &UtxoViewpoint{
378 Entries: map[bc.Hash]*storage.UtxoEntry{
379 bc.Hash{V0: 0}: storage.NewUtxoEntry(false, 0, false),
386 BlockHeader: &bc.BlockHeader{
387 TransactionStatus: bc.NewTransactionStatus(),
389 Transactions: []*bc.Tx{
391 TxHeader: &bc.TxHeader{
392 ResultIds: []*bc.Hash{},
394 SpentOutputIDs: []bc.Hash{
397 Entries: defaultEntry,
401 inputView: &UtxoViewpoint{
402 Entries: map[bc.Hash]*storage.UtxoEntry{
403 bc.Hash{V0: 0}: storage.NewUtxoEntry(false, 0, true),
406 fetchView: &UtxoViewpoint{
407 Entries: map[bc.Hash]*storage.UtxoEntry{
408 bc.Hash{V0: 0}: storage.NewUtxoEntry(false, 0, false),
415 BlockHeader: &bc.BlockHeader{
416 TransactionStatus: bc.NewTransactionStatus(),
418 Transactions: []*bc.Tx{
420 TxHeader: &bc.TxHeader{
421 ResultIds: []*bc.Hash{},
423 SpentOutputIDs: []bc.Hash{
427 Entries: gasOnlyTxEntry,
431 inputView: &UtxoViewpoint{
432 Entries: map[bc.Hash]*storage.UtxoEntry{
433 bc.Hash{V1: 0}: storage.NewUtxoEntry(false, 0, true),
434 bc.Hash{V1: 1}: storage.NewUtxoEntry(false, 0, true),
437 fetchView: &UtxoViewpoint{
438 Entries: map[bc.Hash]*storage.UtxoEntry{
439 bc.Hash{V1: 0}: storage.NewUtxoEntry(false, 0, false),
440 bc.Hash{V1: 1}: storage.NewUtxoEntry(false, 0, true),
448 BlockHeader: &bc.BlockHeader{
449 TransactionStatus: bc.NewTransactionStatus(),
451 Transactions: []*bc.Tx{
453 TxHeader: &bc.TxHeader{
454 ResultIds: []*bc.Hash{
459 SpentOutputIDs: []bc.Hash{},
460 Entries: gasOnlyTxEntry,
464 inputView: NewUtxoViewpoint(),
465 fetchView: &UtxoViewpoint{
466 Entries: map[bc.Hash]*storage.UtxoEntry{
467 bc.Hash{V1: 0}: storage.NewUtxoEntry(false, 0, true),
475 for i, c := range cases {
476 c.block.TransactionStatus.SetStatus(0, c.gasOnlyTx)
477 if err := c.inputView.DetachBlock(c.block, c.block.TransactionStatus); c.err != (err != nil) {
478 t.Errorf("case %d want err = %v, get err = %v", i, c.err, err)
483 if !testutil.DeepEqual(c.inputView, c.fetchView) {
484 t.Errorf("test case %d, want %v, get %v", i, c.fetchView, c.inputView)