OSDN Git Service

fix casper rollback (#1951)
[bytom/bytom.git] / protocol / txpool_test.go
1 package protocol
2
3 import (
4         "testing"
5         "time"
6
7         "github.com/davecgh/go-spew/spew"
8
9         "github.com/bytom/bytom/consensus"
10         "github.com/bytom/bytom/database/storage"
11         "github.com/bytom/bytom/event"
12         "github.com/bytom/bytom/protocol/bc"
13         "github.com/bytom/bytom/protocol/bc/types"
14         "github.com/bytom/bytom/protocol/state"
15         "github.com/bytom/bytom/testutil"
16 )
17
18 var testTxs = []*types.Tx{
19         //tx0
20         types.NewTx(types.TxData{
21                 SerializedSize: 100,
22                 Inputs: []*types.TxInput{
23                         types.NewSpendInput(nil, bc.NewHash([32]byte{0x01}), *consensus.BTMAssetID, 1, 1, []byte{0x51}, nil),
24                 },
25                 Outputs: []*types.TxOutput{
26                         types.NewOriginalTxOutput(*consensus.BTMAssetID, 1, []byte{0x6a}, nil),
27                 },
28         }),
29         //tx1
30         types.NewTx(types.TxData{
31                 SerializedSize: 100,
32                 Inputs: []*types.TxInput{
33                         types.NewSpendInput(nil, bc.NewHash([32]byte{0x01}), *consensus.BTMAssetID, 1, 1, []byte{0x51}, nil),
34                 },
35                 Outputs: []*types.TxOutput{
36                         types.NewOriginalTxOutput(*consensus.BTMAssetID, 1, []byte{0x6b}, nil),
37                 },
38         }),
39         //tx2
40         types.NewTx(types.TxData{
41                 SerializedSize: 150,
42                 TimeRange:      0,
43                 Inputs: []*types.TxInput{
44                         types.NewSpendInput(nil, bc.NewHash([32]byte{0x01}), *consensus.BTMAssetID, 1, 1, []byte{0x51}, nil),
45                         types.NewSpendInput(nil, bc.NewHash([32]byte{0x02}), bc.NewAssetID([32]byte{0xa1}), 4, 1, []byte{0x51}, nil),
46                 },
47                 Outputs: []*types.TxOutput{
48                         types.NewOriginalTxOutput(*consensus.BTMAssetID, 1, []byte{0x6b}, nil),
49                         types.NewOriginalTxOutput(bc.NewAssetID([32]byte{0xa1}), 4, []byte{0x61}, nil),
50                 },
51         }),
52         //tx3
53         types.NewTx(types.TxData{
54                 SerializedSize: 100,
55                 Inputs: []*types.TxInput{
56                         types.NewSpendInput(nil, testutil.MustDecodeHash("dbea684b5c5153ed7729669a53d6c59574f26015a3e1eb2a0e8a1c645425a764"), bc.NewAssetID([32]byte{0xa1}), 4, 1, []byte{0x61}, nil),
57                 },
58                 Outputs: []*types.TxOutput{
59                         types.NewOriginalTxOutput(bc.NewAssetID([32]byte{0xa1}), 3, []byte{0x62}, nil),
60                         types.NewOriginalTxOutput(bc.NewAssetID([32]byte{0xa1}), 1, []byte{0x63}, nil),
61                 },
62         }),
63         //tx4
64         types.NewTx(types.TxData{
65                 SerializedSize: 100,
66                 Inputs: []*types.TxInput{
67                         types.NewSpendInput(nil, testutil.MustDecodeHash("d84d0be0fd08e7341f2d127749bb0d0844d4560f53bd54861cee9981fd922cad"), bc.NewAssetID([32]byte{0xa1}), 3, 0, []byte{0x62}, nil),
68                 },
69                 Outputs: []*types.TxOutput{
70                         types.NewOriginalTxOutput(bc.NewAssetID([32]byte{0xa1}), 2, []byte{0x64}, nil),
71                         types.NewOriginalTxOutput(bc.NewAssetID([32]byte{0xa1}), 1, []byte{0x65}, nil),
72                 },
73         }),
74         //tx5
75         types.NewTx(types.TxData{
76                 SerializedSize: 100,
77                 Inputs: []*types.TxInput{
78                         types.NewSpendInput(nil, bc.NewHash([32]byte{0x01}), *consensus.BTMAssetID, 1, 1, []byte{0x51}, nil),
79                 },
80                 Outputs: []*types.TxOutput{
81                         types.NewOriginalTxOutput(*consensus.BTMAssetID, 0, []byte{0x51}, nil),
82                 },
83         }),
84         //tx6
85         types.NewTx(types.TxData{
86                 SerializedSize: 100,
87                 Inputs: []*types.TxInput{
88                         types.NewSpendInput(nil, bc.NewHash([32]byte{0x01}), *consensus.BTMAssetID, 3, 1, []byte{0x51}, nil),
89                         types.NewSpendInput(nil, testutil.MustDecodeHash("d84d0be0fd08e7341f2d127749bb0d0844d4560f53bd54861cee9981fd922cad"), bc.NewAssetID([32]byte{0xa1}), 3, 0, []byte{0x62}, nil),
90                 },
91                 Outputs: []*types.TxOutput{
92                         types.NewOriginalTxOutput(*consensus.BTMAssetID, 2, []byte{0x51}, nil),
93                         types.NewOriginalTxOutput(bc.NewAssetID([32]byte{0xa1}), 0, []byte{0x65}, nil),
94                 },
95         }),
96 }
97
98 type mockStore struct{}
99
100 func (s *mockStore) GetBlockHeader(hash *bc.Hash) (*types.BlockHeader, error)     { return nil, nil }
101 func (s *mockStore) GetCheckpoint(hash *bc.Hash) (*state.Checkpoint, error)       { return nil, nil }
102 func (s *mockStore) GetCheckpointsByHeight(u uint64) ([]*state.Checkpoint, error) { return nil, nil }
103 func (s *mockStore) SaveCheckpoints([]*state.Checkpoint) error                   { return nil }
104 func (s *mockStore) CheckpointsFromNode(height uint64, hash *bc.Hash) ([]*state.Checkpoint, error)      { return nil, nil }
105 func (s *mockStore) BlockExist(hash *bc.Hash) bool                                { return false }
106 func (s *mockStore) GetBlock(*bc.Hash) (*types.Block, error)                      { return nil, nil }
107 func (s *mockStore) GetStoreStatus() *BlockStoreState                             { return nil }
108 func (s *mockStore) GetTransactionsUtxo(*state.UtxoViewpoint, []*bc.Tx) error     { return nil }
109 func (s *mockStore) GetUtxo(*bc.Hash) (*storage.UtxoEntry, error)                 { return nil, nil }
110 func (s *mockStore) GetContract(hash [32]byte) ([]byte, error)                    { return nil, nil }
111 func (s *mockStore) LoadBlockIndex(uint64) (*state.BlockIndex, error)             { return nil, nil }
112 func (s *mockStore) SaveBlock(*types.Block) error                                 { return nil }
113 func (s *mockStore) SaveBlockHeader(*types.BlockHeader) error                     { return nil }
114 func (s *mockStore) SaveChainStatus(*state.BlockNode, *state.UtxoViewpoint, *state.ContractViewpoint, uint64, *bc.Hash) error {
115         return nil
116 }
117
118 func TestAddOrphan(t *testing.T) {
119         cases := []struct {
120                 before         *TxPool
121                 after          *TxPool
122                 addOrphan      *TxDesc
123                 requireParents []*bc.Hash
124         }{
125                 {
126                         before: &TxPool{
127                                 orphans:       map[bc.Hash]*orphanTx{},
128                                 orphansByPrev: map[bc.Hash]map[bc.Hash]*orphanTx{},
129                         },
130                         after: &TxPool{
131                                 orphans: map[bc.Hash]*orphanTx{
132                                         testTxs[0].ID: {
133                                                 TxDesc: &TxDesc{
134                                                         Tx: testTxs[0],
135                                                 },
136                                         },
137                                 },
138                                 orphansByPrev: map[bc.Hash]map[bc.Hash]*orphanTx{
139                                         testTxs[0].SpentOutputIDs[0]: {
140                                                 testTxs[0].ID: {
141                                                         TxDesc: &TxDesc{
142                                                                 Tx: testTxs[0],
143                                                         },
144                                                 },
145                                         },
146                                 },
147                         },
148                         addOrphan:      &TxDesc{Tx: testTxs[0]},
149                         requireParents: []*bc.Hash{&testTxs[0].SpentOutputIDs[0]},
150                 },
151                 {
152                         before: &TxPool{
153                                 orphans: map[bc.Hash]*orphanTx{
154                                         testTxs[0].ID: {
155                                                 TxDesc: &TxDesc{
156                                                         Tx: testTxs[0],
157                                                 },
158                                         },
159                                 },
160                                 orphansByPrev: map[bc.Hash]map[bc.Hash]*orphanTx{
161                                         testTxs[0].SpentOutputIDs[0]: {
162                                                 testTxs[0].ID: {
163                                                         TxDesc: &TxDesc{
164                                                                 Tx: testTxs[0],
165                                                         },
166                                                 },
167                                         },
168                                 },
169                         },
170                         after: &TxPool{
171                                 orphans: map[bc.Hash]*orphanTx{
172                                         testTxs[0].ID: {
173                                                 TxDesc: &TxDesc{
174                                                         Tx: testTxs[0],
175                                                 },
176                                         },
177                                         testTxs[1].ID: {
178                                                 TxDesc: &TxDesc{
179                                                         Tx: testTxs[1],
180                                                 },
181                                         },
182                                 },
183                                 orphansByPrev: map[bc.Hash]map[bc.Hash]*orphanTx{
184                                         testTxs[0].SpentOutputIDs[0]: {
185                                                 testTxs[0].ID: {
186                                                         TxDesc: &TxDesc{
187                                                                 Tx: testTxs[0],
188                                                         },
189                                                 },
190                                                 testTxs[1].ID: {
191                                                         TxDesc: &TxDesc{
192                                                                 Tx: testTxs[1],
193                                                         },
194                                                 },
195                                         },
196                                 },
197                         },
198                         addOrphan:      &TxDesc{Tx: testTxs[1]},
199                         requireParents: []*bc.Hash{&testTxs[1].SpentOutputIDs[0]},
200                 },
201                 {
202                         before: &TxPool{
203                                 orphans:       map[bc.Hash]*orphanTx{},
204                                 orphansByPrev: map[bc.Hash]map[bc.Hash]*orphanTx{},
205                         },
206                         after: &TxPool{
207                                 orphans: map[bc.Hash]*orphanTx{
208                                         testTxs[2].ID: {
209                                                 TxDesc: &TxDesc{
210                                                         Tx: testTxs[2],
211                                                 },
212                                         },
213                                 },
214                                 orphansByPrev: map[bc.Hash]map[bc.Hash]*orphanTx{
215                                         testTxs[2].SpentOutputIDs[1]: {
216                                                 testTxs[2].ID: {
217                                                         TxDesc: &TxDesc{
218                                                                 Tx: testTxs[2],
219                                                         },
220                                                 },
221                                         },
222                                 },
223                         },
224                         addOrphan:      &TxDesc{Tx: testTxs[2]},
225                         requireParents: []*bc.Hash{&testTxs[2].SpentOutputIDs[1]},
226                 },
227         }
228
229         for i, c := range cases {
230                 c.before.addOrphan(c.addOrphan, c.requireParents)
231                 for _, orphan := range c.before.orphans {
232                         orphan.expiration = time.Time{}
233                 }
234                 for _, orphans := range c.before.orphansByPrev {
235                         for _, orphan := range orphans {
236                                 orphan.expiration = time.Time{}
237                         }
238                 }
239                 if !testutil.DeepEqual(c.before, c.after) {
240                         t.Errorf("case %d: got %v want %v", i, c.before, c.after)
241                 }
242         }
243 }
244
245 func TestAddTransaction(t *testing.T) {
246         dispatcher := event.NewDispatcher()
247         cases := []struct {
248                 before *TxPool
249                 after  *TxPool
250                 addTx  *TxDesc
251         }{
252                 {
253                         before: &TxPool{
254                                 pool:            map[bc.Hash]*TxDesc{},
255                                 utxo:            map[bc.Hash]*types.Tx{},
256                                 eventDispatcher: dispatcher,
257                         },
258                         after: &TxPool{
259                                 pool: map[bc.Hash]*TxDesc{
260                                         testTxs[2].ID: {
261                                                 Tx: testTxs[2],
262                                         },
263                                 },
264                                 utxo: map[bc.Hash]*types.Tx{
265                                         *testTxs[2].ResultIds[0]: testTxs[2],
266                                         *testTxs[2].ResultIds[1]: testTxs[2],
267                                 },
268                         },
269                         addTx: &TxDesc{
270                                 Tx: testTxs[2],
271                         },
272                 },
273                 {
274                         before: &TxPool{
275                                 pool:            map[bc.Hash]*TxDesc{},
276                                 utxo:            map[bc.Hash]*types.Tx{},
277                                 eventDispatcher: dispatcher,
278                         },
279                         after: &TxPool{
280                                 pool: map[bc.Hash]*TxDesc{
281                                         testTxs[2].ID: {
282                                                 Tx: testTxs[2],
283                                         },
284                                 },
285                                 utxo: map[bc.Hash]*types.Tx{
286                                         *testTxs[2].ResultIds[0]: testTxs[2],
287                                         *testTxs[2].ResultIds[1]: testTxs[2],
288                                 },
289                         },
290                         addTx: &TxDesc{
291                                 Tx: testTxs[2],
292                         },
293                 },
294         }
295
296         for i, c := range cases {
297                 c.before.addTransaction(c.addTx)
298                 for _, txD := range c.before.pool {
299                         txD.Added = time.Time{}
300                 }
301                 if !testutil.DeepEqual(c.before.pool, c.after.pool) {
302                         t.Errorf("case %d: pool: got %v want %v", i, c.before.pool, c.after.pool)
303                 }
304                 if !testutil.DeepEqual(c.before.utxo, c.after.utxo) {
305                         t.Errorf("case %d: utxo: got %v want %v", i, c.before.utxo, c.after.utxo)
306                 }
307         }
308 }
309
310 func TestExpireOrphan(t *testing.T) {
311         before := &TxPool{
312                 orphans: map[bc.Hash]*orphanTx{
313                         testTxs[0].ID: {
314                                 expiration: time.Unix(1533489701, 0),
315                                 TxDesc: &TxDesc{
316                                         Tx: testTxs[0],
317                                 },
318                         },
319                         testTxs[1].ID: {
320                                 expiration: time.Unix(1633489701, 0),
321                                 TxDesc: &TxDesc{
322                                         Tx: testTxs[1],
323                                 },
324                         },
325                 },
326                 orphansByPrev: map[bc.Hash]map[bc.Hash]*orphanTx{
327                         testTxs[0].SpentOutputIDs[0]: {
328                                 testTxs[0].ID: {
329                                         expiration: time.Unix(1533489701, 0),
330                                         TxDesc: &TxDesc{
331                                                 Tx: testTxs[0],
332                                         },
333                                 },
334                                 testTxs[1].ID: {
335                                         expiration: time.Unix(1633489701, 0),
336                                         TxDesc: &TxDesc{
337                                                 Tx: testTxs[1],
338                                         },
339                                 },
340                         },
341                 },
342         }
343
344         want := &TxPool{
345                 orphans: map[bc.Hash]*orphanTx{
346                         testTxs[1].ID: {
347                                 expiration: time.Unix(1633489701, 0),
348                                 TxDesc: &TxDesc{
349                                         Tx: testTxs[1],
350                                 },
351                         },
352                 },
353                 orphansByPrev: map[bc.Hash]map[bc.Hash]*orphanTx{
354                         testTxs[0].SpentOutputIDs[0]: {
355                                 testTxs[1].ID: {
356                                         expiration: time.Unix(1633489701, 0),
357                                         TxDesc: &TxDesc{
358                                                 Tx: testTxs[1],
359                                         },
360                                 },
361                         },
362                 },
363         }
364
365         before.ExpireOrphan(time.Unix(1633479701, 0))
366         if !testutil.DeepEqual(before, want) {
367                 t.Errorf("got %v want %v", before, want)
368         }
369 }
370
371 func TestProcessOrphans(t *testing.T) {
372         t.Skip("Skipping testing in CI environment temp")
373         dispatcher := event.NewDispatcher()
374         cases := []struct {
375                 before    *TxPool
376                 after     *TxPool
377                 processTx *TxDesc
378         }{
379                 {
380                         before: &TxPool{
381                                 pool:            map[bc.Hash]*TxDesc{},
382                                 utxo:            map[bc.Hash]*types.Tx{},
383                                 eventDispatcher: dispatcher,
384                                 orphans: map[bc.Hash]*orphanTx{
385                                         testTxs[3].ID: {
386                                                 TxDesc: &TxDesc{
387                                                         Tx: testTxs[3],
388                                                 },
389                                         },
390                                 },
391                                 orphansByPrev: map[bc.Hash]map[bc.Hash]*orphanTx{
392                                         testTxs[3].SpentOutputIDs[0]: {
393                                                 testTxs[3].ID: {
394                                                         TxDesc: &TxDesc{
395                                                                 Tx: testTxs[3],
396                                                         },
397                                                 },
398                                         },
399                                 },
400                         },
401                         after: &TxPool{
402                                 pool: map[bc.Hash]*TxDesc{
403                                         testTxs[3].ID: {
404                                                 Tx: testTxs[3],
405                                         },
406                                 },
407                                 utxo: map[bc.Hash]*types.Tx{
408                                         *testTxs[3].ResultIds[0]: testTxs[3],
409                                         *testTxs[3].ResultIds[1]: testTxs[3],
410                                 },
411                                 eventDispatcher: dispatcher,
412                                 orphans:         map[bc.Hash]*orphanTx{},
413                                 orphansByPrev:   map[bc.Hash]map[bc.Hash]*orphanTx{},
414                         },
415                         processTx: &TxDesc{Tx: testTxs[2]},
416                 },
417                 {
418                         before: &TxPool{
419                                 pool:            map[bc.Hash]*TxDesc{},
420                                 utxo:            map[bc.Hash]*types.Tx{},
421                                 eventDispatcher: dispatcher,
422                                 orphans: map[bc.Hash]*orphanTx{
423                                         testTxs[3].ID: {
424                                                 TxDesc: &TxDesc{
425                                                         Tx: testTxs[3],
426                                                 },
427                                         },
428                                         testTxs[4].ID: {
429                                                 TxDesc: &TxDesc{
430                                                         Tx: testTxs[4],
431                                                 },
432                                         },
433                                 },
434                                 orphansByPrev: map[bc.Hash]map[bc.Hash]*orphanTx{
435                                         testTxs[3].SpentOutputIDs[0]: {
436                                                 testTxs[3].ID: {
437                                                         TxDesc: &TxDesc{
438                                                                 Tx: testTxs[3],
439                                                         },
440                                                 },
441                                         },
442                                         testTxs[4].SpentOutputIDs[0]: {
443                                                 testTxs[4].ID: {
444                                                         TxDesc: &TxDesc{
445                                                                 Tx: testTxs[4],
446                                                         },
447                                                 },
448                                         },
449                                 },
450                         },
451                         after: &TxPool{
452                                 pool: map[bc.Hash]*TxDesc{
453                                         testTxs[3].ID: {
454                                                 Tx: testTxs[3],
455                                         },
456                                         testTxs[4].ID: {
457                                                 Tx: testTxs[4],
458                                         },
459                                 },
460                                 utxo: map[bc.Hash]*types.Tx{
461                                         *testTxs[3].ResultIds[0]: testTxs[3],
462                                         *testTxs[3].ResultIds[1]: testTxs[3],
463                                         *testTxs[4].ResultIds[0]: testTxs[4],
464                                         *testTxs[4].ResultIds[1]: testTxs[4],
465                                 },
466                                 eventDispatcher: dispatcher,
467                                 orphans:         map[bc.Hash]*orphanTx{},
468                                 orphansByPrev:   map[bc.Hash]map[bc.Hash]*orphanTx{},
469                         },
470                         processTx: &TxDesc{Tx: testTxs[2]},
471                 },
472         }
473
474         for i, c := range cases {
475                 c.before.store = &mockStore{}
476                 c.before.addTransaction(c.processTx)
477                 c.before.processOrphans(c.processTx)
478                 c.before.RemoveTransaction(&c.processTx.Tx.ID)
479                 c.before.store = nil
480                 c.before.lastUpdated = 0
481                 for _, txD := range c.before.pool {
482                         txD.Added = time.Time{}
483                 }
484
485                 if !testutil.DeepEqual(c.before, c.after) {
486                         t.Errorf("case %d: got %v want %v", i, c.before, c.after)
487                 }
488         }
489 }
490
491 func TestRemoveOrphan(t *testing.T) {
492         cases := []struct {
493                 before       *TxPool
494                 after        *TxPool
495                 removeHashes []*bc.Hash
496         }{
497                 {
498                         before: &TxPool{
499                                 orphans: map[bc.Hash]*orphanTx{
500                                         testTxs[0].ID: {
501                                                 expiration: time.Unix(1533489701, 0),
502                                                 TxDesc: &TxDesc{
503                                                         Tx: testTxs[0],
504                                                 },
505                                         },
506                                 },
507                                 orphansByPrev: map[bc.Hash]map[bc.Hash]*orphanTx{
508                                         testTxs[0].SpentOutputIDs[0]: {
509                                                 testTxs[0].ID: {
510                                                         expiration: time.Unix(1533489701, 0),
511                                                         TxDesc: &TxDesc{
512                                                                 Tx: testTxs[0],
513                                                         },
514                                                 },
515                                         },
516                                 },
517                         },
518                         after: &TxPool{
519                                 orphans:       map[bc.Hash]*orphanTx{},
520                                 orphansByPrev: map[bc.Hash]map[bc.Hash]*orphanTx{},
521                         },
522                         removeHashes: []*bc.Hash{
523                                 &testTxs[0].ID,
524                         },
525                 },
526                 {
527                         before: &TxPool{
528                                 orphans: map[bc.Hash]*orphanTx{
529                                         testTxs[0].ID: {
530                                                 expiration: time.Unix(1533489701, 0),
531                                                 TxDesc: &TxDesc{
532                                                         Tx: testTxs[0],
533                                                 },
534                                         },
535                                         testTxs[1].ID: {
536                                                 expiration: time.Unix(1533489701, 0),
537                                                 TxDesc: &TxDesc{
538                                                         Tx: testTxs[1],
539                                                 },
540                                         },
541                                 },
542                                 orphansByPrev: map[bc.Hash]map[bc.Hash]*orphanTx{
543                                         testTxs[0].SpentOutputIDs[0]: {
544                                                 testTxs[0].ID: {
545                                                         expiration: time.Unix(1533489701, 0),
546                                                         TxDesc: &TxDesc{
547                                                                 Tx: testTxs[0],
548                                                         },
549                                                 },
550                                                 testTxs[1].ID: {
551                                                         expiration: time.Unix(1533489701, 0),
552                                                         TxDesc: &TxDesc{
553                                                                 Tx: testTxs[1],
554                                                         },
555                                                 },
556                                         },
557                                 },
558                         },
559                         after: &TxPool{
560                                 orphans: map[bc.Hash]*orphanTx{
561                                         testTxs[0].ID: {
562                                                 expiration: time.Unix(1533489701, 0),
563                                                 TxDesc: &TxDesc{
564                                                         Tx: testTxs[0],
565                                                 },
566                                         },
567                                 },
568                                 orphansByPrev: map[bc.Hash]map[bc.Hash]*orphanTx{
569                                         testTxs[0].SpentOutputIDs[0]: {
570                                                 testTxs[0].ID: {
571                                                         expiration: time.Unix(1533489701, 0),
572                                                         TxDesc: &TxDesc{
573                                                                 Tx: testTxs[0],
574                                                         },
575                                                 },
576                                         },
577                                 },
578                         },
579                         removeHashes: []*bc.Hash{
580                                 &testTxs[1].ID,
581                         },
582                 },
583         }
584
585         for i, c := range cases {
586                 for _, hash := range c.removeHashes {
587                         c.before.removeOrphan(hash)
588                 }
589                 if !testutil.DeepEqual(c.before, c.after) {
590                         t.Errorf("case %d: got %v want %v", i, c.before, c.after)
591                 }
592         }
593 }
594
595 type mockStore1 struct{}
596
597 func (s *mockStore1) GetBlockHeader(hash *bc.Hash) (*types.BlockHeader, error)     { return nil, nil }
598 func (s *mockStore1) GetCheckpoint(hash *bc.Hash) (*state.Checkpoint, error)       { return nil, nil }
599 func (s *mockStore1) GetCheckpointsByHeight(u uint64) ([]*state.Checkpoint, error) { return nil, nil }
600 func (s *mockStore1) SaveCheckpoints([]*state.Checkpoint) error                   { return nil }
601 func (s *mockStore1) CheckpointsFromNode(height uint64, hash *bc.Hash) ([]*state.Checkpoint, error)      { return nil, nil }
602 func (s *mockStore1) BlockExist(hash *bc.Hash) bool                                { return false }
603 func (s *mockStore1) GetBlock(*bc.Hash) (*types.Block, error)                      { return nil, nil }
604 func (s *mockStore1) GetStoreStatus() *BlockStoreState                             { return nil }
605 func (s *mockStore1) GetTransactionStatus(*bc.Hash) (*bc.TransactionStatus, error) { return nil, nil }
606 func (s *mockStore1) GetTransactionsUtxo(utxoView *state.UtxoViewpoint, tx []*bc.Tx) error {
607         for _, hash := range testTxs[2].SpentOutputIDs {
608                 utxoView.Entries[hash] = &storage.UtxoEntry{IsCoinBase: false, Spent: false}
609         }
610         return nil
611 }
612 func (s *mockStore1) GetUtxo(*bc.Hash) (*storage.UtxoEntry, error)        { return nil, nil }
613 func (s *mockStore1) GetContract(hash [32]byte) ([]byte, error)           { return nil, nil }
614 func (s *mockStore1) LoadBlockIndex(uint64) (*state.BlockIndex, error)    { return nil, nil }
615 func (s *mockStore1) SaveBlock(*types.Block) error                        { return nil }
616 func (s *mockStore1) SaveBlockHeader(*types.BlockHeader) error            { return nil }
617 func (s *mockStore1) SaveChainStatus(*state.BlockNode, *state.UtxoViewpoint, *state.ContractViewpoint, uint64, *bc.Hash) error { return nil}
618
619 func TestProcessTransaction(t *testing.T) {
620         txPool := &TxPool{
621                 pool:            make(map[bc.Hash]*TxDesc),
622                 utxo:            make(map[bc.Hash]*types.Tx),
623                 orphans:         make(map[bc.Hash]*orphanTx),
624                 orphansByPrev:   make(map[bc.Hash]map[bc.Hash]*orphanTx),
625                 store:           &mockStore1{},
626                 eventDispatcher: event.NewDispatcher(),
627         }
628         cases := []struct {
629                 want  *TxPool
630                 addTx *TxDesc
631         }{
632                 //Dust tx
633                 {
634                         want: &TxPool{},
635                         addTx: &TxDesc{
636                                 Tx: testTxs[3],
637                         },
638                 },
639                 //Dust tx
640                 {
641                         want: &TxPool{},
642                         addTx: &TxDesc{
643                                 Tx: testTxs[4],
644                         },
645                 },
646                 //Dust tx
647                 {
648                         want: &TxPool{},
649                         addTx: &TxDesc{
650                                 Tx: testTxs[5],
651                         },
652                 },
653                 //Dust tx
654                 {
655                         want: &TxPool{},
656                         addTx: &TxDesc{
657                                 Tx: testTxs[6],
658                         },
659                 },
660                 //normal tx
661                 {
662                         want: &TxPool{
663                                 pool: map[bc.Hash]*TxDesc{
664                                         testTxs[2].ID: {
665                                                 Tx:     testTxs[2],
666                                                 Weight: 150,
667                                         },
668                                 },
669                                 utxo: map[bc.Hash]*types.Tx{
670                                         *testTxs[2].ResultIds[0]: testTxs[2],
671                                         *testTxs[2].ResultIds[1]: testTxs[2],
672                                 },
673                         },
674                         addTx: &TxDesc{
675                                 Tx: testTxs[2],
676                         },
677                 },
678         }
679
680         for i, c := range cases {
681                 txPool.ProcessTransaction(c.addTx.Tx, 0, 0)
682                 for _, txD := range txPool.pool {
683                         txD.Added = time.Time{}
684                 }
685                 for _, txD := range txPool.orphans {
686                         txD.Added = time.Time{}
687                         txD.expiration = time.Time{}
688                 }
689
690                 if !testutil.DeepEqual(txPool.pool, c.want.pool) {
691                         t.Errorf("case %d: test ProcessTransaction pool mismatch got %s want %s", i, spew.Sdump(txPool.pool), spew.Sdump(c.want.pool))
692                 }
693                 if !testutil.DeepEqual(txPool.utxo, c.want.utxo) {
694                         t.Errorf("case %d: test ProcessTransaction utxo mismatch got %s want %s", i, spew.Sdump(txPool.utxo), spew.Sdump(c.want.utxo))
695                 }
696                 if !testutil.DeepEqual(txPool.orphans, c.want.orphans) {
697                         t.Errorf("case %d: test ProcessTransaction orphans mismatch got %s want %s", i, spew.Sdump(txPool.orphans), spew.Sdump(c.want.orphans))
698                 }
699                 if !testutil.DeepEqual(txPool.orphansByPrev, c.want.orphansByPrev) {
700                         t.Errorf("case %d: test ProcessTransaction orphansByPrev mismatch got %s want %s", i, spew.Sdump(txPool.orphansByPrev), spew.Sdump(c.want.orphansByPrev))
701                 }
702         }
703 }