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