Tests that if the transaction pool has both executable and non-executable transactions from an origin account, filling the nonce gap moves all queued ones into the pending pool.
(t *testing.T)
| 667 | // transactions from an origin account, filling the nonce gap moves all queued |
| 668 | // ones into the pending pool. |
| 669 | func TestTransactionGapFilling(t *testing.T) { |
| 670 | t.Parallel() |
| 671 | |
| 672 | // Create a test account and fund it |
| 673 | pool, key := setupTxPool() |
| 674 | defer pool.Stop() |
| 675 | |
| 676 | account, _ := deriveSender(transaction(0, 0, key)) |
| 677 | pool.currentState.AddBalance(account, big.NewInt(1000000)) |
| 678 | |
| 679 | // Keep track of transaction events to ensure all executables get announced |
| 680 | events := make(chan NewTxsEvent, testTxPoolConfig.AccountQueue+5) |
| 681 | sub := pool.txFeed.Subscribe(events) |
| 682 | defer sub.Unsubscribe() |
| 683 | |
| 684 | // Create a pending and a queued transaction with a nonce-gap in between |
| 685 | if err := pool.AddRemote(transaction(0, 100000, key)); err != nil { |
| 686 | t.Fatalf("failed to add pending transaction: %v", err) |
| 687 | } |
| 688 | if err := pool.AddRemote(transaction(2, 100000, key)); err != nil { |
| 689 | t.Fatalf("failed to add queued transaction: %v", err) |
| 690 | } |
| 691 | pending, queued := pool.Stats() |
| 692 | if pending != 1 { |
| 693 | t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 1) |
| 694 | } |
| 695 | if queued != 1 { |
| 696 | t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) |
| 697 | } |
| 698 | if err := validateEvents(events, 1); err != nil { |
| 699 | t.Fatalf("original event firing failed: %v", err) |
| 700 | } |
| 701 | if err := validateTxPoolInternals(pool); err != nil { |
| 702 | t.Fatalf("pool internal state corrupted: %v", err) |
| 703 | } |
| 704 | // Fill the nonce gap and ensure all transactions become pending |
| 705 | if err := pool.AddRemote(transaction(1, 100000, key)); err != nil { |
| 706 | t.Fatalf("failed to add gapped transaction: %v", err) |
| 707 | } |
| 708 | pending, queued = pool.Stats() |
| 709 | if pending != 3 { |
| 710 | t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) |
| 711 | } |
| 712 | if queued != 0 { |
| 713 | t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) |
| 714 | } |
| 715 | if err := validateEvents(events, 2); err != nil { |
| 716 | t.Fatalf("gap-filling event firing failed: %v", err) |
| 717 | } |
| 718 | if err := validateTxPoolInternals(pool); err != nil { |
| 719 | t.Fatalf("pool internal state corrupted: %v", err) |
| 720 | } |
| 721 | } |
| 722 | |
| 723 | // Tests that if the transaction count belonging to a single account goes above |
| 724 | // some threshold, the higher transactions are dropped to prevent DOS attacks. |
nothing calls this directly
no test coverage detected