OSDN Git Service

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