OSDN Git Service

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