github.com/hyperion-hyn/go-ethereum@v2.4.0+incompatible/core/tx_pool_test.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package core 18 19 import ( 20 "crypto/ecdsa" 21 "fmt" 22 "io/ioutil" 23 "math/big" 24 "math/rand" 25 "os" 26 "reflect" 27 "testing" 28 "time" 29 30 "github.com/ethereum/go-ethereum/common" 31 "github.com/ethereum/go-ethereum/core/state" 32 "github.com/ethereum/go-ethereum/core/types" 33 "github.com/ethereum/go-ethereum/crypto" 34 "github.com/ethereum/go-ethereum/ethdb" 35 "github.com/ethereum/go-ethereum/event" 36 "github.com/ethereum/go-ethereum/params" 37 ) 38 39 // testTxPoolConfig is a transaction pool configuration without stateful disk 40 // sideeffects used during testing. 41 var testTxPoolConfig TxPoolConfig 42 43 func init() { 44 testTxPoolConfig = DefaultTxPoolConfig 45 testTxPoolConfig.Journal = "" 46 } 47 48 type testBlockChain struct { 49 statedb *state.StateDB 50 privateStateDb *state.StateDB 51 gasLimit uint64 52 chainHeadFeed *event.Feed 53 } 54 55 func (bc *testBlockChain) CurrentBlock() *types.Block { 56 return types.NewBlock(&types.Header{ 57 GasLimit: bc.gasLimit, 58 }, nil, nil, nil) 59 } 60 61 func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { 62 return bc.CurrentBlock() 63 } 64 65 func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, *state.StateDB, error) { 66 return bc.statedb, bc.privateStateDb, nil 67 } 68 69 func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription { 70 return bc.chainHeadFeed.Subscribe(ch) 71 } 72 73 func transaction(nonce uint64, gaslimit uint64, key *ecdsa.PrivateKey) *types.Transaction { 74 return pricedTransaction(nonce, gaslimit, big.NewInt(1), key) 75 } 76 77 func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey) *types.Transaction { 78 tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(100), gaslimit, gasprice, nil), types.HomesteadSigner{}, key) 79 return tx 80 } 81 82 func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { 83 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 84 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 85 86 key, _ := crypto.GenerateKey() 87 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 88 89 return pool, key 90 } 91 92 func setupQuorumTxPool() (*TxPool, *ecdsa.PrivateKey) { 93 db := ethdb.NewMemDatabase() 94 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 95 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 96 97 key, _ := crypto.GenerateKey() 98 pool := NewTxPool(testTxPoolConfig, params.QuorumTestChainConfig, blockchain) 99 100 return pool, key 101 } 102 103 // validateTxPoolInternals checks various consistency invariants within the pool. 104 func validateTxPoolInternals(pool *TxPool) error { 105 pool.mu.RLock() 106 defer pool.mu.RUnlock() 107 108 // Ensure the total transaction set is consistent with pending + queued 109 pending, queued := pool.stats() 110 if total := pool.all.Count(); total != pending+queued { 111 return fmt.Errorf("total transaction count %d != %d pending + %d queued", total, pending, queued) 112 } 113 if priced := pool.priced.items.Len() - pool.priced.stales; priced != pending+queued { 114 return fmt.Errorf("total priced transaction count %d != %d pending + %d queued", priced, pending, queued) 115 } 116 // Ensure the next nonce to assign is the correct one 117 for addr, txs := range pool.pending { 118 // Find the last transaction 119 var last uint64 120 for nonce := range txs.txs.items { 121 if last < nonce { 122 last = nonce 123 } 124 } 125 if nonce := pool.pendingState.GetNonce(addr); nonce != last+1 { 126 return fmt.Errorf("pending nonce mismatch: have %v, want %v", nonce, last+1) 127 } 128 } 129 return nil 130 } 131 132 // validateEvents checks that the correct number of transaction addition events 133 // were fired on the pool's event feed. 134 func validateEvents(events chan NewTxsEvent, count int) error { 135 var received []*types.Transaction 136 137 for len(received) < count { 138 select { 139 case ev := <-events: 140 received = append(received, ev.Txs...) 141 case <-time.After(time.Second): 142 return fmt.Errorf("event #%d not fired", len(received)) 143 } 144 } 145 if len(received) > count { 146 return fmt.Errorf("more than %d events fired: %v", count, received[count:]) 147 } 148 select { 149 case ev := <-events: 150 return fmt.Errorf("more than %d events fired: %v", count, ev.Txs) 151 152 case <-time.After(50 * time.Millisecond): 153 // This branch should be "default", but it's a data race between goroutines, 154 // reading the event channel and pushing into it, so better wait a bit ensuring 155 // really nothing gets injected. 156 } 157 return nil 158 } 159 160 func deriveSender(tx *types.Transaction) (common.Address, error) { 161 return types.Sender(types.HomesteadSigner{}, tx) 162 } 163 164 type testChain struct { 165 *testBlockChain 166 address common.Address 167 trigger *bool 168 } 169 170 // testChain.State() is used multiple times to reset the pending state. 171 // when simulate is true it will create a state that indicates 172 // that tx0 and tx1 are included in the chain. 173 func (c *testChain) State() (*state.StateDB, *state.StateDB, error) { 174 // delay "state change" by one. The tx pool fetches the 175 // state multiple times and by delaying it a bit we simulate 176 // a state change between those fetches. 177 stdb := c.statedb 178 if *c.trigger { 179 c.statedb, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 180 // simulate that the new head block included tx0 and tx1 181 c.statedb.SetNonce(c.address, 2) 182 c.statedb.SetBalance(c.address, new(big.Int).SetUint64(params.Ether)) 183 *c.trigger = false 184 } 185 return stdb, stdb, nil 186 } 187 188 // This test simulates a scenario where a new block is imported during a 189 // state reset and tests whether the pending state is in sync with the 190 // block head event that initiated the resetState(). 191 func TestStateChangeDuringTransactionPoolReset(t *testing.T) { 192 t.Parallel() 193 194 var ( 195 key, _ = crypto.GenerateKey() 196 address = crypto.PubkeyToAddress(key.PublicKey) 197 statedb, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 198 trigger = false 199 ) 200 201 // setup pool with 2 transaction in it 202 statedb.SetBalance(address, new(big.Int).SetUint64(params.Ether)) 203 blockchain := &testChain{&testBlockChain{statedb, statedb, 1000000000, new(event.Feed)}, address, &trigger} 204 205 tx0 := transaction(0, 100000, key) 206 tx1 := transaction(1, 100000, key) 207 208 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 209 defer pool.Stop() 210 211 nonce := pool.State().GetNonce(address) 212 if nonce != 0 { 213 t.Fatalf("Invalid nonce, want 0, got %d", nonce) 214 } 215 216 pool.AddRemotes(types.Transactions{tx0, tx1}) 217 218 nonce = pool.State().GetNonce(address) 219 if nonce != 2 { 220 t.Fatalf("Invalid nonce, want 2, got %d", nonce) 221 } 222 223 // trigger state change in the background 224 trigger = true 225 226 pool.lockedReset(nil, nil) 227 228 _, err := pool.Pending() 229 if err != nil { 230 t.Fatalf("Could not fetch pending transactions: %v", err) 231 } 232 nonce = pool.State().GetNonce(address) 233 if nonce != 2 { 234 t.Fatalf("Invalid nonce, want 2, got %d", nonce) 235 } 236 } 237 238 //Test for transactions that are invalid on Ethereum 239 func TestInvalidTransactions(t *testing.T) { 240 t.Parallel() 241 242 pool, key := setupTxPool() 243 defer pool.Stop() 244 245 tx := transaction(0, 100, key) 246 from, _ := deriveSender(tx) 247 248 pool.currentState.AddBalance(from, big.NewInt(1)) 249 if err := pool.AddRemote(tx); err != ErrInsufficientFunds { 250 t.Error("expected", ErrInsufficientFunds, "; got", err) 251 } 252 253 balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(new(big.Int).SetUint64(tx.Gas()), tx.GasPrice())) 254 pool.currentState.AddBalance(from, balance) 255 if err := pool.AddRemote(tx); err != ErrIntrinsicGas { 256 t.Error("expected", ErrIntrinsicGas, "; got", err) 257 } 258 259 pool.currentState.SetNonce(from, 1) 260 pool.currentState.AddBalance(from, big.NewInt(0xffffffffffffff)) 261 tx = transaction(0, 100000, key) 262 if err := pool.AddRemote(tx); err != ErrNonceTooLow { 263 t.Error("expected", ErrNonceTooLow, "; got", err) 264 } 265 266 tx = transaction(1, 100000, key) 267 pool.gasPrice = big.NewInt(1000) 268 if err := pool.AddRemote(tx); err != ErrUnderpriced { 269 t.Error("expected", ErrUnderpriced, "; got", err) 270 } 271 if err := pool.AddLocal(tx); err != nil { 272 t.Error("expected", nil, "; got", err) 273 } 274 275 tooMuchGas := pool.currentMaxGas + 1 276 tx1 := transaction(2, tooMuchGas, key) 277 if err := pool.AddRemote(tx1); err != ErrGasLimit { 278 t.Error("expected", ErrGasLimit, "; got", err) 279 } 280 281 data := make([]byte, (64*1024)+1) 282 tx2, _ := types.SignTx(types.NewTransaction(2, common.Address{}, big.NewInt(100), 100000, big.NewInt(1), data), types.HomesteadSigner{}, key) 283 if err := pool.AddRemote(tx2); err != ErrOversizedData { 284 t.Error("expected", ErrOversizedData, "; got", err) 285 } 286 287 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 288 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 289 params.TestChainConfig.TransactionSizeLimit = 128 290 pool2 := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 291 292 pool2.currentState.AddBalance(from, big.NewInt(0xffffffffffffff)) 293 data2 := make([]byte, (127 * 1024)) 294 295 tx3, _ := types.SignTx(types.NewTransaction(2, common.Address{}, big.NewInt(100), 100000, big.NewInt(1), data2), types.HomesteadSigner{}, key) 296 if err := pool2.AddRemote(tx3); err != ErrIntrinsicGas { 297 t.Error("expected", ErrIntrinsicGas, "; got", err) 298 } 299 300 data3 := make([]byte, (128*1024)+1) 301 tx4, _ := types.SignTx(types.NewTransaction(2, common.Address{}, big.NewInt(100), 100000, big.NewInt(1), data3), types.HomesteadSigner{}, key) 302 if err := pool2.AddRemote(tx4); err != ErrOversizedData { 303 t.Error("expected", ErrOversizedData, "; got", err) 304 } 305 306 tx5, _ := types.SignTx(types.NewTransaction(1, common.Address{}, big.NewInt(100), 0, big.NewInt(0), nil), types.HomesteadSigner{}, key) 307 balance = new(big.Int).Add(tx5.Value(), new(big.Int).Mul(new(big.Int).SetUint64(tx5.Gas()), tx5.GasPrice())) 308 309 from, _ = deriveSender(tx5) 310 pool.currentState.AddBalance(from, balance) 311 tx5.SetPrivate() 312 if err := pool.AddRemote(tx5); err != ErrEtherValueUnsupported { 313 t.Error("expected", ErrEtherValueUnsupported, "; got", err) 314 } 315 } 316 317 //Test for transactions that are only invalid on Quorum 318 func TestQuorumInvalidTransactions(t *testing.T) { 319 pool, key := setupQuorumTxPool() 320 defer pool.Stop() 321 322 tx := transaction(0, 0, key) 323 if err := pool.AddRemote(tx); err != ErrInvalidGasPrice { 324 t.Error("expected", ErrInvalidGasPrice, "; got", err) 325 } 326 327 } 328 329 func TestValidateTx_whenValueZeroTransferForPrivateTransaction(t *testing.T) { 330 pool, key := setupQuorumTxPool() 331 defer pool.Stop() 332 zeroValue := common.Big0 333 zeroGasPrice := common.Big0 334 defaultTxPoolGasLimit := uint64(1000000) 335 arbitraryTx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, zeroValue, defaultTxPoolGasLimit, zeroGasPrice, nil), types.HomesteadSigner{}, key) 336 arbitraryTx.SetPrivate() 337 338 if err := pool.AddRemote(arbitraryTx); err != ErrEtherValueUnsupported { 339 t.Error("expected:", ErrEtherValueUnsupported, "; got:", err) 340 } 341 } 342 343 func TestValidateTx_whenValueNonZeroTransferForPrivateTransaction(t *testing.T) { 344 pool, key := setupQuorumTxPool() 345 defer pool.Stop() 346 arbitraryValue := common.Big3 347 arbitraryTx, balance, from := newPrivateTransaction(arbitraryValue, nil, key) 348 pool.currentState.AddBalance(from, balance) 349 350 if err := pool.AddRemote(arbitraryTx); err != ErrEtherValueUnsupported { 351 t.Error("expected: ", ErrEtherValueUnsupported, "; got:", err) 352 } 353 } 354 355 func newPrivateTransaction(value *big.Int, data []byte, key *ecdsa.PrivateKey) (*types.Transaction, *big.Int, common.Address) { 356 zeroGasPrice := common.Big0 357 defaultTxPoolGasLimit := uint64(1000000) 358 arbitraryTx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, value, defaultTxPoolGasLimit, zeroGasPrice, data), types.HomesteadSigner{}, key) 359 arbitraryTx.SetPrivate() 360 balance := new(big.Int).Add(arbitraryTx.Value(), new(big.Int).Mul(new(big.Int).SetUint64(arbitraryTx.Gas()), arbitraryTx.GasPrice())) 361 from, _ := deriveSender(arbitraryTx) 362 return arbitraryTx, balance, from 363 } 364 365 func TestValidateTx_whenValueNonZeroWithSmartContractForPrivateTransaction(t *testing.T) { 366 pool, key := setupQuorumTxPool() 367 defer pool.Stop() 368 arbitraryValue := common.Big3 369 arbitraryTx, balance, from := newPrivateTransaction(arbitraryValue, []byte("arbitrary bytecode"), key) 370 pool.currentState.AddBalance(from, balance) 371 372 if err := pool.AddRemote(arbitraryTx); err != ErrEtherValueUnsupported { 373 t.Error("expected: ", ErrEtherValueUnsupported, "; got:", err) 374 } 375 } 376 377 func TestTransactionQueue(t *testing.T) { 378 t.Parallel() 379 380 pool, key := setupTxPool() 381 defer pool.Stop() 382 383 tx := transaction(0, 100, key) 384 from, _ := deriveSender(tx) 385 pool.currentState.AddBalance(from, big.NewInt(1000)) 386 pool.lockedReset(nil, nil) 387 pool.enqueueTx(tx.Hash(), tx) 388 389 pool.promoteExecutables([]common.Address{from}) 390 if len(pool.pending) != 1 { 391 t.Error("expected valid txs to be 1 is", len(pool.pending)) 392 } 393 394 tx = transaction(1, 100, key) 395 from, _ = deriveSender(tx) 396 pool.currentState.SetNonce(from, 2) 397 pool.enqueueTx(tx.Hash(), tx) 398 pool.promoteExecutables([]common.Address{from}) 399 if _, ok := pool.pending[from].txs.items[tx.Nonce()]; ok { 400 t.Error("expected transaction to be in tx pool") 401 } 402 403 if len(pool.queue) > 0 { 404 t.Error("expected transaction queue to be empty. is", len(pool.queue)) 405 } 406 407 pool, key = setupTxPool() 408 defer pool.Stop() 409 410 tx1 := transaction(0, 100, key) 411 tx2 := transaction(10, 100, key) 412 tx3 := transaction(11, 100, key) 413 from, _ = deriveSender(tx1) 414 pool.currentState.AddBalance(from, big.NewInt(1000)) 415 pool.lockedReset(nil, nil) 416 417 pool.enqueueTx(tx1.Hash(), tx1) 418 pool.enqueueTx(tx2.Hash(), tx2) 419 pool.enqueueTx(tx3.Hash(), tx3) 420 421 pool.promoteExecutables([]common.Address{from}) 422 423 if len(pool.pending) != 1 { 424 t.Error("expected tx pool to be 1, got", len(pool.pending)) 425 } 426 if pool.queue[from].Len() != 2 { 427 t.Error("expected len(queue) == 2, got", pool.queue[from].Len()) 428 } 429 } 430 431 func TestTransactionNegativeValue(t *testing.T) { 432 t.Parallel() 433 434 pool, key := setupTxPool() 435 defer pool.Stop() 436 437 tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), 100, big.NewInt(1), nil), types.HomesteadSigner{}, key) 438 from, _ := deriveSender(tx) 439 pool.currentState.AddBalance(from, big.NewInt(1)) 440 if err := pool.AddRemote(tx); err != ErrNegativeValue { 441 t.Error("expected", ErrNegativeValue, "got", err) 442 } 443 } 444 445 func TestTransactionChainFork(t *testing.T) { 446 t.Parallel() 447 448 pool, key := setupTxPool() 449 defer pool.Stop() 450 451 addr := crypto.PubkeyToAddress(key.PublicKey) 452 resetState := func() { 453 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 454 statedb.AddBalance(addr, big.NewInt(100000000000000)) 455 456 pool.chain = &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 457 pool.lockedReset(nil, nil) 458 } 459 resetState() 460 461 tx := transaction(0, 100000, key) 462 if _, err := pool.add(tx, false); err != nil { 463 t.Error("didn't expect error", err) 464 } 465 pool.removeTx(tx.Hash(), true) 466 467 // reset the pool's internal state 468 resetState() 469 if _, err := pool.add(tx, false); err != nil { 470 t.Error("didn't expect error", err) 471 } 472 } 473 474 func TestTransactionDoubleNonce(t *testing.T) { 475 t.Parallel() 476 477 pool, key := setupTxPool() 478 defer pool.Stop() 479 480 addr := crypto.PubkeyToAddress(key.PublicKey) 481 resetState := func() { 482 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 483 statedb.AddBalance(addr, big.NewInt(100000000000000)) 484 485 pool.chain = &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 486 pool.lockedReset(nil, nil) 487 } 488 resetState() 489 490 signer := types.HomesteadSigner{} 491 tx1, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 100000, big.NewInt(1), nil), signer, key) 492 tx2, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 1000000, big.NewInt(2), nil), signer, key) 493 tx3, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 1000000, big.NewInt(1), nil), signer, key) 494 495 // Add the first two transaction, ensure higher priced stays only 496 if replace, err := pool.add(tx1, false); err != nil || replace { 497 t.Errorf("first transaction insert failed (%v) or reported replacement (%v)", err, replace) 498 } 499 if replace, err := pool.add(tx2, false); err != nil || !replace { 500 t.Errorf("second transaction insert failed (%v) or not reported replacement (%v)", err, replace) 501 } 502 pool.promoteExecutables([]common.Address{addr}) 503 if pool.pending[addr].Len() != 1 { 504 t.Error("expected 1 pending transactions, got", pool.pending[addr].Len()) 505 } 506 if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() { 507 t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash()) 508 } 509 // Add the third transaction and ensure it's not saved (smaller price) 510 pool.add(tx3, false) 511 pool.promoteExecutables([]common.Address{addr}) 512 if pool.pending[addr].Len() != 1 { 513 t.Error("expected 1 pending transactions, got", pool.pending[addr].Len()) 514 } 515 if tx := pool.pending[addr].txs.items[0]; tx.Hash() != tx2.Hash() { 516 t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash()) 517 } 518 // Ensure the total transaction count is correct 519 if pool.all.Count() != 1 { 520 t.Error("expected 1 total transactions, got", pool.all.Count()) 521 } 522 } 523 524 func TestTransactionMissingNonce(t *testing.T) { 525 t.Parallel() 526 527 pool, key := setupTxPool() 528 defer pool.Stop() 529 530 addr := crypto.PubkeyToAddress(key.PublicKey) 531 pool.currentState.AddBalance(addr, big.NewInt(100000000000000)) 532 tx := transaction(1, 100000, key) 533 if _, err := pool.add(tx, false); err != nil { 534 t.Error("didn't expect error", err) 535 } 536 if len(pool.pending) != 0 { 537 t.Error("expected 0 pending transactions, got", len(pool.pending)) 538 } 539 if pool.queue[addr].Len() != 1 { 540 t.Error("expected 1 queued transaction, got", pool.queue[addr].Len()) 541 } 542 if pool.all.Count() != 1 { 543 t.Error("expected 1 total transactions, got", pool.all.Count()) 544 } 545 } 546 547 func TestTransactionNonceRecovery(t *testing.T) { 548 t.Parallel() 549 550 const n = 10 551 pool, key := setupTxPool() 552 defer pool.Stop() 553 554 addr := crypto.PubkeyToAddress(key.PublicKey) 555 pool.currentState.SetNonce(addr, n) 556 pool.currentState.AddBalance(addr, big.NewInt(100000000000000)) 557 pool.lockedReset(nil, nil) 558 559 tx := transaction(n, 100000, key) 560 if err := pool.AddRemote(tx); err != nil { 561 t.Error(err) 562 } 563 // simulate some weird re-order of transactions and missing nonce(s) 564 pool.currentState.SetNonce(addr, n-1) 565 pool.lockedReset(nil, nil) 566 if fn := pool.pendingState.GetNonce(addr); fn != n-1 { 567 t.Errorf("expected nonce to be %d, got %d", n-1, fn) 568 } 569 } 570 571 // Tests that if an account runs out of funds, any pending and queued transactions 572 // are dropped. 573 func TestTransactionDropping(t *testing.T) { 574 t.Parallel() 575 576 // Create a test account and fund it 577 pool, key := setupTxPool() 578 defer pool.Stop() 579 580 account, _ := deriveSender(transaction(0, 0, key)) 581 pool.currentState.AddBalance(account, big.NewInt(1000)) 582 583 // Add some pending and some queued transactions 584 var ( 585 tx0 = transaction(0, 100, key) 586 tx1 = transaction(1, 200, key) 587 tx2 = transaction(2, 300, key) 588 tx10 = transaction(10, 100, key) 589 tx11 = transaction(11, 200, key) 590 tx12 = transaction(12, 300, key) 591 ) 592 pool.promoteTx(account, tx0.Hash(), tx0) 593 pool.promoteTx(account, tx1.Hash(), tx1) 594 pool.promoteTx(account, tx2.Hash(), tx2) 595 pool.enqueueTx(tx10.Hash(), tx10) 596 pool.enqueueTx(tx11.Hash(), tx11) 597 pool.enqueueTx(tx12.Hash(), tx12) 598 599 // Check that pre and post validations leave the pool as is 600 if pool.pending[account].Len() != 3 { 601 t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 3) 602 } 603 if pool.queue[account].Len() != 3 { 604 t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 3) 605 } 606 if pool.all.Count() != 6 { 607 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 6) 608 } 609 pool.lockedReset(nil, nil) 610 if pool.pending[account].Len() != 3 { 611 t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 3) 612 } 613 if pool.queue[account].Len() != 3 { 614 t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 3) 615 } 616 if pool.all.Count() != 6 { 617 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 6) 618 } 619 // Reduce the balance of the account, and check that invalidated transactions are dropped 620 pool.currentState.AddBalance(account, big.NewInt(-650)) 621 pool.lockedReset(nil, nil) 622 623 if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok { 624 t.Errorf("funded pending transaction missing: %v", tx0) 625 } 626 if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; !ok { 627 t.Errorf("funded pending transaction missing: %v", tx0) 628 } 629 if _, ok := pool.pending[account].txs.items[tx2.Nonce()]; ok { 630 t.Errorf("out-of-fund pending transaction present: %v", tx1) 631 } 632 if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok { 633 t.Errorf("funded queued transaction missing: %v", tx10) 634 } 635 if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; !ok { 636 t.Errorf("funded queued transaction missing: %v", tx10) 637 } 638 if _, ok := pool.queue[account].txs.items[tx12.Nonce()]; ok { 639 t.Errorf("out-of-fund queued transaction present: %v", tx11) 640 } 641 if pool.all.Count() != 4 { 642 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 4) 643 } 644 // Reduce the block gas limit, check that invalidated transactions are dropped 645 pool.chain.(*testBlockChain).gasLimit = 100 646 pool.lockedReset(nil, nil) 647 648 if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok { 649 t.Errorf("funded pending transaction missing: %v", tx0) 650 } 651 if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; ok { 652 t.Errorf("over-gased pending transaction present: %v", tx1) 653 } 654 if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok { 655 t.Errorf("funded queued transaction missing: %v", tx10) 656 } 657 if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; ok { 658 t.Errorf("over-gased queued transaction present: %v", tx11) 659 } 660 if pool.all.Count() != 2 { 661 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 2) 662 } 663 // Reduce the block gas limit, check that invalidated transactions are dropped 664 pool.chain.(*testBlockChain).gasLimit = 100 665 pool.lockedReset(nil, nil) 666 667 if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok { 668 t.Errorf("funded pending transaction missing: %v", tx0) 669 } 670 if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; ok { 671 t.Errorf("over-gased pending transaction present: %v", tx1) 672 } 673 if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok { 674 t.Errorf("funded queued transaction missing: %v", tx10) 675 } 676 if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; ok { 677 t.Errorf("over-gased queued transaction present: %v", tx11) 678 } 679 if pool.all.Count() != 2 { 680 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 2) 681 } 682 } 683 684 // Tests that if a transaction is dropped from the current pending pool (e.g. out 685 // of fund), all consecutive (still valid, but not executable) transactions are 686 // postponed back into the future queue to prevent broadcasting them. 687 func TestTransactionPostponing(t *testing.T) { 688 t.Parallel() 689 690 // Create the pool to test the postponing with 691 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 692 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 693 694 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 695 defer pool.Stop() 696 697 // Create two test accounts to produce different gap profiles with 698 keys := make([]*ecdsa.PrivateKey, 2) 699 accs := make([]common.Address, len(keys)) 700 701 for i := 0; i < len(keys); i++ { 702 keys[i], _ = crypto.GenerateKey() 703 accs[i] = crypto.PubkeyToAddress(keys[i].PublicKey) 704 705 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(50100)) 706 } 707 // Add a batch consecutive pending transactions for validation 708 txs := []*types.Transaction{} 709 for i, key := range keys { 710 711 for j := 0; j < 100; j++ { 712 var tx *types.Transaction 713 if (i+j)%2 == 0 { 714 tx = transaction(uint64(j), 25000, key) 715 } else { 716 tx = transaction(uint64(j), 50000, key) 717 } 718 txs = append(txs, tx) 719 } 720 } 721 for i, err := range pool.AddRemotes(txs) { 722 if err != nil { 723 t.Fatalf("tx %d: failed to add transactions: %v", i, err) 724 } 725 } 726 // Check that pre and post validations leave the pool as is 727 if pending := pool.pending[accs[0]].Len() + pool.pending[accs[1]].Len(); pending != len(txs) { 728 t.Errorf("pending transaction mismatch: have %d, want %d", pending, len(txs)) 729 } 730 if len(pool.queue) != 0 { 731 t.Errorf("queued accounts mismatch: have %d, want %d", len(pool.queue), 0) 732 } 733 if pool.all.Count() != len(txs) { 734 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs)) 735 } 736 pool.lockedReset(nil, nil) 737 if pending := pool.pending[accs[0]].Len() + pool.pending[accs[1]].Len(); pending != len(txs) { 738 t.Errorf("pending transaction mismatch: have %d, want %d", pending, len(txs)) 739 } 740 if len(pool.queue) != 0 { 741 t.Errorf("queued accounts mismatch: have %d, want %d", len(pool.queue), 0) 742 } 743 if pool.all.Count() != len(txs) { 744 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs)) 745 } 746 // Reduce the balance of the account, and check that transactions are reorganised 747 for _, addr := range accs { 748 pool.currentState.AddBalance(addr, big.NewInt(-1)) 749 } 750 pool.lockedReset(nil, nil) 751 752 // The first account's first transaction remains valid, check that subsequent 753 // ones are either filtered out, or queued up for later. 754 if _, ok := pool.pending[accs[0]].txs.items[txs[0].Nonce()]; !ok { 755 t.Errorf("tx %d: valid and funded transaction missing from pending pool: %v", 0, txs[0]) 756 } 757 if _, ok := pool.queue[accs[0]].txs.items[txs[0].Nonce()]; ok { 758 t.Errorf("tx %d: valid and funded transaction present in future queue: %v", 0, txs[0]) 759 } 760 for i, tx := range txs[1:100] { 761 if i%2 == 1 { 762 if _, ok := pool.pending[accs[0]].txs.items[tx.Nonce()]; ok { 763 t.Errorf("tx %d: valid but future transaction present in pending pool: %v", i+1, tx) 764 } 765 if _, ok := pool.queue[accs[0]].txs.items[tx.Nonce()]; !ok { 766 t.Errorf("tx %d: valid but future transaction missing from future queue: %v", i+1, tx) 767 } 768 } else { 769 if _, ok := pool.pending[accs[0]].txs.items[tx.Nonce()]; ok { 770 t.Errorf("tx %d: out-of-fund transaction present in pending pool: %v", i+1, tx) 771 } 772 if _, ok := pool.queue[accs[0]].txs.items[tx.Nonce()]; ok { 773 t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", i+1, tx) 774 } 775 } 776 } 777 // The second account's first transaction got invalid, check that all transactions 778 // are either filtered out, or queued up for later. 779 if pool.pending[accs[1]] != nil { 780 t.Errorf("invalidated account still has pending transactions") 781 } 782 for i, tx := range txs[100:] { 783 if i%2 == 1 { 784 if _, ok := pool.queue[accs[1]].txs.items[tx.Nonce()]; !ok { 785 t.Errorf("tx %d: valid but future transaction missing from future queue: %v", 100+i, tx) 786 } 787 } else { 788 if _, ok := pool.queue[accs[1]].txs.items[tx.Nonce()]; ok { 789 t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", 100+i, tx) 790 } 791 } 792 } 793 if pool.all.Count() != len(txs)/2 { 794 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs)/2) 795 } 796 } 797 798 // Tests that if the transaction pool has both executable and non-executable 799 // transactions from an origin account, filling the nonce gap moves all queued 800 // ones into the pending pool. 801 func TestTransactionGapFilling(t *testing.T) { 802 t.Parallel() 803 804 // Create a test account and fund it 805 pool, key := setupTxPool() 806 defer pool.Stop() 807 808 account, _ := deriveSender(transaction(0, 0, key)) 809 pool.currentState.AddBalance(account, big.NewInt(1000000)) 810 811 // Keep track of transaction events to ensure all executables get announced 812 events := make(chan NewTxsEvent, testTxPoolConfig.AccountQueue+5) 813 sub := pool.txFeed.Subscribe(events) 814 defer sub.Unsubscribe() 815 816 // Create a pending and a queued transaction with a nonce-gap in between 817 if err := pool.AddRemote(transaction(0, 100000, key)); err != nil { 818 t.Fatalf("failed to add pending transaction: %v", err) 819 } 820 if err := pool.AddRemote(transaction(2, 100000, key)); err != nil { 821 t.Fatalf("failed to add queued transaction: %v", err) 822 } 823 pending, queued := pool.Stats() 824 if pending != 1 { 825 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 1) 826 } 827 if queued != 1 { 828 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) 829 } 830 if err := validateEvents(events, 1); err != nil { 831 t.Fatalf("original event firing failed: %v", err) 832 } 833 if err := validateTxPoolInternals(pool); err != nil { 834 t.Fatalf("pool internal state corrupted: %v", err) 835 } 836 // Fill the nonce gap and ensure all transactions become pending 837 if err := pool.AddRemote(transaction(1, 100000, key)); err != nil { 838 t.Fatalf("failed to add gapped transaction: %v", err) 839 } 840 pending, queued = pool.Stats() 841 if pending != 3 { 842 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) 843 } 844 if queued != 0 { 845 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 846 } 847 if err := validateEvents(events, 2); err != nil { 848 t.Fatalf("gap-filling event firing failed: %v", err) 849 } 850 if err := validateTxPoolInternals(pool); err != nil { 851 t.Fatalf("pool internal state corrupted: %v", err) 852 } 853 } 854 855 // Tests that if the transaction count belonging to a single account goes above 856 // some threshold, the higher transactions are dropped to prevent DOS attacks. 857 func TestTransactionQueueAccountLimiting(t *testing.T) { 858 t.Parallel() 859 860 // Create a test account and fund it 861 pool, key := setupTxPool() 862 defer pool.Stop() 863 864 account, _ := deriveSender(transaction(0, 0, key)) 865 pool.currentState.AddBalance(account, big.NewInt(1000000)) 866 867 // Keep queuing up transactions and make sure all above a limit are dropped 868 for i := uint64(1); i <= testTxPoolConfig.AccountQueue+5; i++ { 869 if err := pool.AddRemote(transaction(i, 100000, key)); err != nil { 870 t.Fatalf("tx %d: failed to add transaction: %v", i, err) 871 } 872 if len(pool.pending) != 0 { 873 t.Errorf("tx %d: pending pool size mismatch: have %d, want %d", i, len(pool.pending), 0) 874 } 875 if i <= testTxPoolConfig.AccountQueue { 876 if pool.queue[account].Len() != int(i) { 877 t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), i) 878 } 879 } else { 880 if pool.queue[account].Len() != int(testTxPoolConfig.AccountQueue) { 881 t.Errorf("tx %d: queue limit mismatch: have %d, want %d", i, pool.queue[account].Len(), testTxPoolConfig.AccountQueue) 882 } 883 } 884 } 885 if pool.all.Count() != int(testTxPoolConfig.AccountQueue) { 886 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), testTxPoolConfig.AccountQueue) 887 } 888 } 889 890 // Tests that if the transaction count belonging to multiple accounts go above 891 // some threshold, the higher transactions are dropped to prevent DOS attacks. 892 // 893 // This logic should not hold for local transactions, unless the local tracking 894 // mechanism is disabled. 895 func TestTransactionQueueGlobalLimiting(t *testing.T) { 896 testTransactionQueueGlobalLimiting(t, false) 897 } 898 func TestTransactionQueueGlobalLimitingNoLocals(t *testing.T) { 899 testTransactionQueueGlobalLimiting(t, true) 900 } 901 902 func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) { 903 t.Parallel() 904 905 // Create the pool to test the limit enforcement with 906 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 907 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 908 909 config := testTxPoolConfig 910 config.NoLocals = nolocals 911 config.GlobalQueue = config.AccountQueue*3 - 1 // reduce the queue limits to shorten test time (-1 to make it non divisible) 912 913 pool := NewTxPool(config, params.TestChainConfig, blockchain) 914 defer pool.Stop() 915 916 // Create a number of test accounts and fund them (last one will be the local) 917 keys := make([]*ecdsa.PrivateKey, 5) 918 for i := 0; i < len(keys); i++ { 919 keys[i], _ = crypto.GenerateKey() 920 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 921 } 922 local := keys[len(keys)-1] 923 924 // Generate and queue a batch of transactions 925 nonces := make(map[common.Address]uint64) 926 927 txs := make(types.Transactions, 0, 3*config.GlobalQueue) 928 for len(txs) < cap(txs) { 929 key := keys[rand.Intn(len(keys)-1)] // skip adding transactions with the local account 930 addr := crypto.PubkeyToAddress(key.PublicKey) 931 932 txs = append(txs, transaction(nonces[addr]+1, 100000, key)) 933 nonces[addr]++ 934 } 935 // Import the batch and verify that limits have been enforced 936 pool.AddRemotes(txs) 937 938 queued := 0 939 for addr, list := range pool.queue { 940 if list.Len() > int(config.AccountQueue) { 941 t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), config.AccountQueue) 942 } 943 queued += list.Len() 944 } 945 if queued > int(config.GlobalQueue) { 946 t.Fatalf("total transactions overflow allowance: %d > %d", queued, config.GlobalQueue) 947 } 948 // Generate a batch of transactions from the local account and import them 949 txs = txs[:0] 950 for i := uint64(0); i < 3*config.GlobalQueue; i++ { 951 txs = append(txs, transaction(i+1, 100000, local)) 952 } 953 pool.AddLocals(txs) 954 955 // If locals are disabled, the previous eviction algorithm should apply here too 956 if nolocals { 957 queued := 0 958 for addr, list := range pool.queue { 959 if list.Len() > int(config.AccountQueue) { 960 t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), config.AccountQueue) 961 } 962 queued += list.Len() 963 } 964 if queued > int(config.GlobalQueue) { 965 t.Fatalf("total transactions overflow allowance: %d > %d", queued, config.GlobalQueue) 966 } 967 } else { 968 // Local exemptions are enabled, make sure the local account owned the queue 969 if len(pool.queue) != 1 { 970 t.Errorf("multiple accounts in queue: have %v, want %v", len(pool.queue), 1) 971 } 972 // Also ensure no local transactions are ever dropped, even if above global limits 973 if queued := pool.queue[crypto.PubkeyToAddress(local.PublicKey)].Len(); uint64(queued) != 3*config.GlobalQueue { 974 t.Fatalf("local account queued transaction count mismatch: have %v, want %v", queued, 3*config.GlobalQueue) 975 } 976 } 977 } 978 979 // Tests that if an account remains idle for a prolonged amount of time, any 980 // non-executable transactions queued up are dropped to prevent wasting resources 981 // on shuffling them around. 982 // 983 // This logic should not hold for local transactions, unless the local tracking 984 // mechanism is disabled. 985 func TestTransactionQueueTimeLimiting(t *testing.T) { testTransactionQueueTimeLimiting(t, false) } 986 func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) { testTransactionQueueTimeLimiting(t, true) } 987 988 func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { 989 // Reduce the eviction interval to a testable amount 990 defer func(old time.Duration) { evictionInterval = old }(evictionInterval) 991 evictionInterval = time.Second 992 993 // Create the pool to test the non-expiration enforcement 994 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 995 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 996 997 config := testTxPoolConfig 998 config.Lifetime = time.Second 999 config.NoLocals = nolocals 1000 1001 pool := NewTxPool(config, params.TestChainConfig, blockchain) 1002 defer pool.Stop() 1003 1004 // Create two test accounts to ensure remotes expire but locals do not 1005 local, _ := crypto.GenerateKey() 1006 remote, _ := crypto.GenerateKey() 1007 1008 pool.currentState.AddBalance(crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000)) 1009 pool.currentState.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000)) 1010 1011 // Add the two transactions and ensure they both are queued up 1012 if err := pool.AddLocal(pricedTransaction(1, 100000, big.NewInt(1), local)); err != nil { 1013 t.Fatalf("failed to add local transaction: %v", err) 1014 } 1015 if err := pool.AddRemote(pricedTransaction(1, 100000, big.NewInt(1), remote)); err != nil { 1016 t.Fatalf("failed to add remote transaction: %v", err) 1017 } 1018 pending, queued := pool.Stats() 1019 if pending != 0 { 1020 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) 1021 } 1022 if queued != 2 { 1023 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) 1024 } 1025 if err := validateTxPoolInternals(pool); err != nil { 1026 t.Fatalf("pool internal state corrupted: %v", err) 1027 } 1028 // Wait a bit for eviction to run and clean up any leftovers, and ensure only the local remains 1029 time.Sleep(2 * config.Lifetime) 1030 1031 pending, queued = pool.Stats() 1032 if pending != 0 { 1033 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) 1034 } 1035 if nolocals { 1036 if queued != 0 { 1037 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 1038 } 1039 } else { 1040 if queued != 1 { 1041 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) 1042 } 1043 } 1044 if err := validateTxPoolInternals(pool); err != nil { 1045 t.Fatalf("pool internal state corrupted: %v", err) 1046 } 1047 } 1048 1049 // Tests that even if the transaction count belonging to a single account goes 1050 // above some threshold, as long as the transactions are executable, they are 1051 // accepted. 1052 func TestTransactionPendingLimiting(t *testing.T) { 1053 t.Parallel() 1054 1055 // Create a test account and fund it 1056 pool, key := setupTxPool() 1057 defer pool.Stop() 1058 1059 account, _ := deriveSender(transaction(0, 0, key)) 1060 pool.currentState.AddBalance(account, big.NewInt(1000000)) 1061 1062 // Keep track of transaction events to ensure all executables get announced 1063 events := make(chan NewTxsEvent, testTxPoolConfig.AccountQueue+5) 1064 sub := pool.txFeed.Subscribe(events) 1065 defer sub.Unsubscribe() 1066 1067 // Keep queuing up transactions and make sure all above a limit are dropped 1068 for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ { 1069 if err := pool.AddRemote(transaction(i, 100000, key)); err != nil { 1070 t.Fatalf("tx %d: failed to add transaction: %v", i, err) 1071 } 1072 if pool.pending[account].Len() != int(i)+1 { 1073 t.Errorf("tx %d: pending pool size mismatch: have %d, want %d", i, pool.pending[account].Len(), i+1) 1074 } 1075 if len(pool.queue) != 0 { 1076 t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), 0) 1077 } 1078 } 1079 if pool.all.Count() != int(testTxPoolConfig.AccountQueue+5) { 1080 t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), testTxPoolConfig.AccountQueue+5) 1081 } 1082 if err := validateEvents(events, int(testTxPoolConfig.AccountQueue+5)); err != nil { 1083 t.Fatalf("event firing failed: %v", err) 1084 } 1085 if err := validateTxPoolInternals(pool); err != nil { 1086 t.Fatalf("pool internal state corrupted: %v", err) 1087 } 1088 } 1089 1090 // Tests that the transaction limits are enforced the same way irrelevant whether 1091 // the transactions are added one by one or in batches. 1092 func TestTransactionQueueLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 1) } 1093 func TestTransactionPendingLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 0) } 1094 1095 func testTransactionLimitingEquivalency(t *testing.T, origin uint64) { 1096 t.Parallel() 1097 1098 // Add a batch of transactions to a pool one by one 1099 pool1, key1 := setupTxPool() 1100 defer pool1.Stop() 1101 1102 account1, _ := deriveSender(transaction(0, 0, key1)) 1103 pool1.currentState.AddBalance(account1, big.NewInt(1000000)) 1104 1105 for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ { 1106 if err := pool1.AddRemote(transaction(origin+i, 100000, key1)); err != nil { 1107 t.Fatalf("tx %d: failed to add transaction: %v", i, err) 1108 } 1109 } 1110 // Add a batch of transactions to a pool in one big batch 1111 pool2, key2 := setupTxPool() 1112 defer pool2.Stop() 1113 1114 account2, _ := deriveSender(transaction(0, 0, key2)) 1115 pool2.currentState.AddBalance(account2, big.NewInt(1000000)) 1116 1117 txs := []*types.Transaction{} 1118 for i := uint64(0); i < testTxPoolConfig.AccountQueue+5; i++ { 1119 txs = append(txs, transaction(origin+i, 100000, key2)) 1120 } 1121 pool2.AddRemotes(txs) 1122 1123 // Ensure the batch optimization honors the same pool mechanics 1124 if len(pool1.pending) != len(pool2.pending) { 1125 t.Errorf("pending transaction count mismatch: one-by-one algo: %d, batch algo: %d", len(pool1.pending), len(pool2.pending)) 1126 } 1127 if len(pool1.queue) != len(pool2.queue) { 1128 t.Errorf("queued transaction count mismatch: one-by-one algo: %d, batch algo: %d", len(pool1.queue), len(pool2.queue)) 1129 } 1130 if pool1.all.Count() != pool2.all.Count() { 1131 t.Errorf("total transaction count mismatch: one-by-one algo %d, batch algo %d", pool1.all.Count(), pool2.all.Count()) 1132 } 1133 if err := validateTxPoolInternals(pool1); err != nil { 1134 t.Errorf("pool 1 internal state corrupted: %v", err) 1135 } 1136 if err := validateTxPoolInternals(pool2); err != nil { 1137 t.Errorf("pool 2 internal state corrupted: %v", err) 1138 } 1139 if err := validateTxPoolInternals(pool1); err != nil { 1140 t.Errorf("pool 1 internal state corrupted: %v", err) 1141 } 1142 if err := validateTxPoolInternals(pool2); err != nil { 1143 t.Errorf("pool 2 internal state corrupted: %v", err) 1144 } 1145 } 1146 1147 // Tests that if the transaction count belonging to multiple accounts go above 1148 // some hard threshold, the higher transactions are dropped to prevent DOS 1149 // attacks. 1150 func TestTransactionPendingGlobalLimiting(t *testing.T) { 1151 t.Parallel() 1152 1153 // Create the pool to test the limit enforcement with 1154 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1155 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 1156 1157 config := testTxPoolConfig 1158 config.GlobalSlots = config.AccountSlots * 10 1159 1160 pool := NewTxPool(config, params.TestChainConfig, blockchain) 1161 defer pool.Stop() 1162 1163 // Create a number of test accounts and fund them 1164 keys := make([]*ecdsa.PrivateKey, 5) 1165 for i := 0; i < len(keys); i++ { 1166 keys[i], _ = crypto.GenerateKey() 1167 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 1168 } 1169 // Generate and queue a batch of transactions 1170 nonces := make(map[common.Address]uint64) 1171 1172 txs := types.Transactions{} 1173 for _, key := range keys { 1174 addr := crypto.PubkeyToAddress(key.PublicKey) 1175 for j := 0; j < int(config.GlobalSlots)/len(keys)*2; j++ { 1176 txs = append(txs, transaction(nonces[addr], 100000, key)) 1177 nonces[addr]++ 1178 } 1179 } 1180 // Import the batch and verify that limits have been enforced 1181 pool.AddRemotes(txs) 1182 1183 pending := 0 1184 for _, list := range pool.pending { 1185 pending += list.Len() 1186 } 1187 if pending > int(config.GlobalSlots) { 1188 t.Fatalf("total pending transactions overflow allowance: %d > %d", pending, config.GlobalSlots) 1189 } 1190 if err := validateTxPoolInternals(pool); err != nil { 1191 t.Fatalf("pool internal state corrupted: %v", err) 1192 } 1193 } 1194 1195 // Tests that if transactions start being capped, transactions are also removed from 'all' 1196 func TestTransactionCapClearsFromAll(t *testing.T) { 1197 t.Parallel() 1198 1199 // Create the pool to test the limit enforcement with 1200 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1201 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 1202 1203 config := testTxPoolConfig 1204 config.AccountSlots = 2 1205 config.AccountQueue = 2 1206 config.GlobalSlots = 8 1207 1208 pool := NewTxPool(config, params.TestChainConfig, blockchain) 1209 defer pool.Stop() 1210 1211 // Create a number of test accounts and fund them 1212 key, _ := crypto.GenerateKey() 1213 addr := crypto.PubkeyToAddress(key.PublicKey) 1214 pool.currentState.AddBalance(addr, big.NewInt(1000000)) 1215 1216 txs := types.Transactions{} 1217 for j := 0; j < int(config.GlobalSlots)*2; j++ { 1218 txs = append(txs, transaction(uint64(j), 100000, key)) 1219 } 1220 // Import the batch and verify that limits have been enforced 1221 pool.AddRemotes(txs) 1222 if err := validateTxPoolInternals(pool); err != nil { 1223 t.Fatalf("pool internal state corrupted: %v", err) 1224 } 1225 } 1226 1227 // Tests that if the transaction count belonging to multiple accounts go above 1228 // some hard threshold, if they are under the minimum guaranteed slot count then 1229 // the transactions are still kept. 1230 func TestTransactionPendingMinimumAllowance(t *testing.T) { 1231 t.Parallel() 1232 1233 // Create the pool to test the limit enforcement with 1234 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1235 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 1236 1237 config := testTxPoolConfig 1238 config.GlobalSlots = 0 1239 1240 pool := NewTxPool(config, params.TestChainConfig, blockchain) 1241 defer pool.Stop() 1242 1243 // Create a number of test accounts and fund them 1244 keys := make([]*ecdsa.PrivateKey, 5) 1245 for i := 0; i < len(keys); i++ { 1246 keys[i], _ = crypto.GenerateKey() 1247 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 1248 } 1249 // Generate and queue a batch of transactions 1250 nonces := make(map[common.Address]uint64) 1251 1252 txs := types.Transactions{} 1253 for _, key := range keys { 1254 addr := crypto.PubkeyToAddress(key.PublicKey) 1255 for j := 0; j < int(config.AccountSlots)*2; j++ { 1256 txs = append(txs, transaction(nonces[addr], 100000, key)) 1257 nonces[addr]++ 1258 } 1259 } 1260 // Import the batch and verify that limits have been enforced 1261 pool.AddRemotes(txs) 1262 1263 for addr, list := range pool.pending { 1264 if list.Len() != int(config.AccountSlots) { 1265 t.Errorf("addr %x: total pending transactions mismatch: have %d, want %d", addr, list.Len(), config.AccountSlots) 1266 } 1267 } 1268 if err := validateTxPoolInternals(pool); err != nil { 1269 t.Fatalf("pool internal state corrupted: %v", err) 1270 } 1271 } 1272 1273 // Tests that setting the transaction pool gas price to a higher value correctly 1274 // discards everything cheaper than that and moves any gapped transactions back 1275 // from the pending pool to the queue. 1276 // 1277 // Note, local transactions are never allowed to be dropped. 1278 func TestTransactionPoolRepricing(t *testing.T) { 1279 t.Parallel() 1280 1281 // Create the pool to test the pricing enforcement with 1282 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1283 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 1284 1285 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 1286 defer pool.Stop() 1287 1288 // Keep track of transaction events to ensure all executables get announced 1289 events := make(chan NewTxsEvent, 32) 1290 sub := pool.txFeed.Subscribe(events) 1291 defer sub.Unsubscribe() 1292 1293 // Create a number of test accounts and fund them 1294 keys := make([]*ecdsa.PrivateKey, 4) 1295 for i := 0; i < len(keys); i++ { 1296 keys[i], _ = crypto.GenerateKey() 1297 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 1298 } 1299 // Generate and queue a batch of transactions, both pending and queued 1300 txs := types.Transactions{} 1301 1302 txs = append(txs, pricedTransaction(0, 100000, big.NewInt(2), keys[0])) 1303 txs = append(txs, pricedTransaction(1, 100000, big.NewInt(1), keys[0])) 1304 txs = append(txs, pricedTransaction(2, 100000, big.NewInt(2), keys[0])) 1305 1306 txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[1])) 1307 txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[1])) 1308 txs = append(txs, pricedTransaction(2, 100000, big.NewInt(2), keys[1])) 1309 1310 txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[2])) 1311 txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[2])) 1312 txs = append(txs, pricedTransaction(3, 100000, big.NewInt(2), keys[2])) 1313 1314 ltx := pricedTransaction(0, 100000, big.NewInt(1), keys[3]) 1315 1316 // Import the batch and that both pending and queued transactions match up 1317 pool.AddRemotes(txs) 1318 pool.AddLocal(ltx) 1319 1320 pending, queued := pool.Stats() 1321 if pending != 7 { 1322 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 7) 1323 } 1324 if queued != 3 { 1325 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3) 1326 } 1327 if err := validateEvents(events, 7); err != nil { 1328 t.Fatalf("original event firing failed: %v", err) 1329 } 1330 if err := validateTxPoolInternals(pool); err != nil { 1331 t.Fatalf("pool internal state corrupted: %v", err) 1332 } 1333 // Reprice the pool and check that underpriced transactions get dropped 1334 pool.SetGasPrice(big.NewInt(2)) 1335 1336 pending, queued = pool.Stats() 1337 if pending != 2 { 1338 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) 1339 } 1340 if queued != 5 { 1341 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 5) 1342 } 1343 if err := validateEvents(events, 0); err != nil { 1344 t.Fatalf("reprice event firing failed: %v", err) 1345 } 1346 if err := validateTxPoolInternals(pool); err != nil { 1347 t.Fatalf("pool internal state corrupted: %v", err) 1348 } 1349 // Check that we can't add the old transactions back 1350 if err := pool.AddRemote(pricedTransaction(1, 100000, big.NewInt(1), keys[0])); err != ErrUnderpriced { 1351 t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) 1352 } 1353 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(1), keys[1])); err != ErrUnderpriced { 1354 t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) 1355 } 1356 if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(1), keys[2])); err != ErrUnderpriced { 1357 t.Fatalf("adding underpriced queued transaction error mismatch: have %v, want %v", err, ErrUnderpriced) 1358 } 1359 if err := validateEvents(events, 0); err != nil { 1360 t.Fatalf("post-reprice event firing failed: %v", err) 1361 } 1362 if err := validateTxPoolInternals(pool); err != nil { 1363 t.Fatalf("pool internal state corrupted: %v", err) 1364 } 1365 // However we can add local underpriced transactions 1366 tx := pricedTransaction(1, 100000, big.NewInt(1), keys[3]) 1367 if err := pool.AddLocal(tx); err != nil { 1368 t.Fatalf("failed to add underpriced local transaction: %v", err) 1369 } 1370 if pending, _ = pool.Stats(); pending != 3 { 1371 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) 1372 } 1373 if err := validateEvents(events, 1); err != nil { 1374 t.Fatalf("post-reprice local event firing failed: %v", err) 1375 } 1376 if err := validateTxPoolInternals(pool); err != nil { 1377 t.Fatalf("pool internal state corrupted: %v", err) 1378 } 1379 // And we can fill gaps with properly priced transactions 1380 if err := pool.AddRemote(pricedTransaction(1, 100000, big.NewInt(2), keys[0])); err != nil { 1381 t.Fatalf("failed to add pending transaction: %v", err) 1382 } 1383 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(2), keys[1])); err != nil { 1384 t.Fatalf("failed to add pending transaction: %v", err) 1385 } 1386 if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(2), keys[2])); err != nil { 1387 t.Fatalf("failed to add queued transaction: %v", err) 1388 } 1389 if err := validateEvents(events, 5); err != nil { 1390 t.Fatalf("post-reprice event firing failed: %v", err) 1391 } 1392 if err := validateTxPoolInternals(pool); err != nil { 1393 t.Fatalf("pool internal state corrupted: %v", err) 1394 } 1395 } 1396 1397 // Tests that setting the transaction pool gas price to a higher value does not 1398 // remove local transactions. 1399 func TestTransactionPoolRepricingKeepsLocals(t *testing.T) { 1400 t.Parallel() 1401 1402 // Create the pool to test the pricing enforcement with 1403 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1404 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 1405 1406 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 1407 defer pool.Stop() 1408 1409 // Create a number of test accounts and fund them 1410 keys := make([]*ecdsa.PrivateKey, 3) 1411 for i := 0; i < len(keys); i++ { 1412 keys[i], _ = crypto.GenerateKey() 1413 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000*1000000)) 1414 } 1415 // Create transaction (both pending and queued) with a linearly growing gasprice 1416 for i := uint64(0); i < 500; i++ { 1417 // Add pending 1418 p_tx := pricedTransaction(i, 100000, big.NewInt(int64(i)), keys[2]) 1419 if err := pool.AddLocal(p_tx); err != nil { 1420 t.Fatal(err) 1421 } 1422 // Add queued 1423 q_tx := pricedTransaction(i+501, 100000, big.NewInt(int64(i)), keys[2]) 1424 if err := pool.AddLocal(q_tx); err != nil { 1425 t.Fatal(err) 1426 } 1427 } 1428 pending, queued := pool.Stats() 1429 expPending, expQueued := 500, 500 1430 validate := func() { 1431 pending, queued = pool.Stats() 1432 if pending != expPending { 1433 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, expPending) 1434 } 1435 if queued != expQueued { 1436 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, expQueued) 1437 } 1438 1439 if err := validateTxPoolInternals(pool); err != nil { 1440 t.Fatalf("pool internal state corrupted: %v", err) 1441 } 1442 } 1443 validate() 1444 1445 // Reprice the pool and check that nothing is dropped 1446 pool.SetGasPrice(big.NewInt(2)) 1447 validate() 1448 1449 pool.SetGasPrice(big.NewInt(2)) 1450 pool.SetGasPrice(big.NewInt(4)) 1451 pool.SetGasPrice(big.NewInt(8)) 1452 pool.SetGasPrice(big.NewInt(100)) 1453 validate() 1454 } 1455 1456 // Tests that when the pool reaches its global transaction limit, underpriced 1457 // transactions are gradually shifted out for more expensive ones and any gapped 1458 // pending transactions are moved into the queue. 1459 // 1460 // Note, local transactions are never allowed to be dropped. 1461 func TestTransactionPoolUnderpricing(t *testing.T) { 1462 t.Parallel() 1463 1464 // Create the pool to test the pricing enforcement with 1465 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1466 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 1467 1468 config := testTxPoolConfig 1469 config.GlobalSlots = 2 1470 config.GlobalQueue = 2 1471 1472 pool := NewTxPool(config, params.TestChainConfig, blockchain) 1473 defer pool.Stop() 1474 1475 // Keep track of transaction events to ensure all executables get announced 1476 events := make(chan NewTxsEvent, 32) 1477 sub := pool.txFeed.Subscribe(events) 1478 defer sub.Unsubscribe() 1479 1480 // Create a number of test accounts and fund them 1481 keys := make([]*ecdsa.PrivateKey, 4) 1482 for i := 0; i < len(keys); i++ { 1483 keys[i], _ = crypto.GenerateKey() 1484 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 1485 } 1486 // Generate and queue a batch of transactions, both pending and queued 1487 txs := types.Transactions{} 1488 1489 txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[0])) 1490 txs = append(txs, pricedTransaction(1, 100000, big.NewInt(2), keys[0])) 1491 1492 txs = append(txs, pricedTransaction(1, 100000, big.NewInt(1), keys[1])) 1493 1494 ltx := pricedTransaction(0, 100000, big.NewInt(1), keys[2]) 1495 1496 // Import the batch and that both pending and queued transactions match up 1497 pool.AddRemotes(txs) 1498 pool.AddLocal(ltx) 1499 1500 pending, queued := pool.Stats() 1501 if pending != 3 { 1502 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) 1503 } 1504 if queued != 1 { 1505 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) 1506 } 1507 if err := validateEvents(events, 3); err != nil { 1508 t.Fatalf("original event firing failed: %v", err) 1509 } 1510 if err := validateTxPoolInternals(pool); err != nil { 1511 t.Fatalf("pool internal state corrupted: %v", err) 1512 } 1513 // Ensure that adding an underpriced transaction on block limit fails 1514 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(1), keys[1])); err != ErrUnderpriced { 1515 t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) 1516 } 1517 // Ensure that adding high priced transactions drops cheap ones, but not own 1518 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(3), keys[1])); err != nil { // +K1:0 => -K1:1 => Pend K0:0, K0:1, K1:0, K2:0; Que - 1519 t.Fatalf("failed to add well priced transaction: %v", err) 1520 } 1521 if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(4), keys[1])); err != nil { // +K1:2 => -K0:0 => Pend K1:0, K2:0; Que K0:1 K1:2 1522 t.Fatalf("failed to add well priced transaction: %v", err) 1523 } 1524 if err := pool.AddRemote(pricedTransaction(3, 100000, big.NewInt(5), keys[1])); err != nil { // +K1:3 => -K0:1 => Pend K1:0, K2:0; Que K1:2 K1:3 1525 t.Fatalf("failed to add well priced transaction: %v", err) 1526 } 1527 pending, queued = pool.Stats() 1528 if pending != 2 { 1529 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) 1530 } 1531 if queued != 2 { 1532 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) 1533 } 1534 if err := validateEvents(events, 1); err != nil { 1535 t.Fatalf("additional event firing failed: %v", err) 1536 } 1537 if err := validateTxPoolInternals(pool); err != nil { 1538 t.Fatalf("pool internal state corrupted: %v", err) 1539 } 1540 // Ensure that adding local transactions can push out even higher priced ones 1541 ltx = pricedTransaction(1, 100000, big.NewInt(0), keys[2]) 1542 if err := pool.AddLocal(ltx); err != nil { 1543 t.Fatalf("failed to append underpriced local transaction: %v", err) 1544 } 1545 ltx = pricedTransaction(0, 100000, big.NewInt(0), keys[3]) 1546 if err := pool.AddLocal(ltx); err != nil { 1547 t.Fatalf("failed to add new underpriced local transaction: %v", err) 1548 } 1549 pending, queued = pool.Stats() 1550 if pending != 3 { 1551 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3) 1552 } 1553 if queued != 1 { 1554 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) 1555 } 1556 if err := validateEvents(events, 2); err != nil { 1557 t.Fatalf("local event firing failed: %v", err) 1558 } 1559 if err := validateTxPoolInternals(pool); err != nil { 1560 t.Fatalf("pool internal state corrupted: %v", err) 1561 } 1562 } 1563 1564 // Tests that more expensive transactions push out cheap ones from the pool, but 1565 // without producing instability by creating gaps that start jumping transactions 1566 // back and forth between queued/pending. 1567 func TestTransactionPoolStableUnderpricing(t *testing.T) { 1568 t.Parallel() 1569 1570 // Create the pool to test the pricing enforcement with 1571 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1572 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 1573 1574 config := testTxPoolConfig 1575 config.GlobalSlots = 128 1576 config.GlobalQueue = 0 1577 1578 pool := NewTxPool(config, params.TestChainConfig, blockchain) 1579 defer pool.Stop() 1580 1581 // Keep track of transaction events to ensure all executables get announced 1582 events := make(chan NewTxsEvent, 32) 1583 sub := pool.txFeed.Subscribe(events) 1584 defer sub.Unsubscribe() 1585 1586 // Create a number of test accounts and fund them 1587 keys := make([]*ecdsa.PrivateKey, 2) 1588 for i := 0; i < len(keys); i++ { 1589 keys[i], _ = crypto.GenerateKey() 1590 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 1591 } 1592 // Fill up the entire queue with the same transaction price points 1593 txs := types.Transactions{} 1594 for i := uint64(0); i < config.GlobalSlots; i++ { 1595 txs = append(txs, pricedTransaction(i, 100000, big.NewInt(1), keys[0])) 1596 } 1597 pool.AddRemotes(txs) 1598 1599 pending, queued := pool.Stats() 1600 if pending != int(config.GlobalSlots) { 1601 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, config.GlobalSlots) 1602 } 1603 if queued != 0 { 1604 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 1605 } 1606 if err := validateEvents(events, int(config.GlobalSlots)); err != nil { 1607 t.Fatalf("original event firing failed: %v", err) 1608 } 1609 if err := validateTxPoolInternals(pool); err != nil { 1610 t.Fatalf("pool internal state corrupted: %v", err) 1611 } 1612 // Ensure that adding high priced transactions drops a cheap, but doesn't produce a gap 1613 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(3), keys[1])); err != nil { 1614 t.Fatalf("failed to add well priced transaction: %v", err) 1615 } 1616 pending, queued = pool.Stats() 1617 if pending != int(config.GlobalSlots) { 1618 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, config.GlobalSlots) 1619 } 1620 if queued != 0 { 1621 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 1622 } 1623 if err := validateEvents(events, 1); err != nil { 1624 t.Fatalf("additional event firing failed: %v", err) 1625 } 1626 if err := validateTxPoolInternals(pool); err != nil { 1627 t.Fatalf("pool internal state corrupted: %v", err) 1628 } 1629 } 1630 1631 // Tests that the pool rejects replacement transactions that don't meet the minimum 1632 // price bump required. 1633 func TestTransactionReplacement(t *testing.T) { 1634 t.Parallel() 1635 1636 // Create the pool to test the pricing enforcement with 1637 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1638 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 1639 1640 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 1641 defer pool.Stop() 1642 1643 // Keep track of transaction events to ensure all executables get announced 1644 events := make(chan NewTxsEvent, 32) 1645 sub := pool.txFeed.Subscribe(events) 1646 defer sub.Unsubscribe() 1647 1648 // Create a test account to add transactions with 1649 key, _ := crypto.GenerateKey() 1650 pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000)) 1651 1652 // Add pending transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too) 1653 price := int64(100) 1654 threshold := (price * (100 + int64(testTxPoolConfig.PriceBump))) / 100 1655 1656 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(1), key)); err != nil { 1657 t.Fatalf("failed to add original cheap pending transaction: %v", err) 1658 } 1659 if err := pool.AddRemote(pricedTransaction(0, 100001, big.NewInt(1), key)); err != ErrReplaceUnderpriced { 1660 t.Fatalf("original cheap pending transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) 1661 } 1662 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(2), key)); err != nil { 1663 t.Fatalf("failed to replace original cheap pending transaction: %v", err) 1664 } 1665 if err := validateEvents(events, 2); err != nil { 1666 t.Fatalf("cheap replacement event firing failed: %v", err) 1667 } 1668 1669 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(price), key)); err != nil { 1670 t.Fatalf("failed to add original proper pending transaction: %v", err) 1671 } 1672 if err := pool.AddRemote(pricedTransaction(0, 100001, big.NewInt(threshold-1), key)); err != ErrReplaceUnderpriced { 1673 t.Fatalf("original proper pending transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) 1674 } 1675 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(threshold), key)); err != nil { 1676 t.Fatalf("failed to replace original proper pending transaction: %v", err) 1677 } 1678 if err := validateEvents(events, 2); err != nil { 1679 t.Fatalf("proper replacement event firing failed: %v", err) 1680 } 1681 // Add queued transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too) 1682 if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(1), key)); err != nil { 1683 t.Fatalf("failed to add original cheap queued transaction: %v", err) 1684 } 1685 if err := pool.AddRemote(pricedTransaction(2, 100001, big.NewInt(1), key)); err != ErrReplaceUnderpriced { 1686 t.Fatalf("original cheap queued transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) 1687 } 1688 if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(2), key)); err != nil { 1689 t.Fatalf("failed to replace original cheap queued transaction: %v", err) 1690 } 1691 1692 if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(price), key)); err != nil { 1693 t.Fatalf("failed to add original proper queued transaction: %v", err) 1694 } 1695 if err := pool.AddRemote(pricedTransaction(2, 100001, big.NewInt(threshold-1), key)); err != ErrReplaceUnderpriced { 1696 t.Fatalf("original proper queued transaction replacement error mismatch: have %v, want %v", err, ErrReplaceUnderpriced) 1697 } 1698 if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(threshold), key)); err != nil { 1699 t.Fatalf("failed to replace original proper queued transaction: %v", err) 1700 } 1701 1702 if err := validateEvents(events, 0); err != nil { 1703 t.Fatalf("queued replacement event firing failed: %v", err) 1704 } 1705 if err := validateTxPoolInternals(pool); err != nil { 1706 t.Fatalf("pool internal state corrupted: %v", err) 1707 } 1708 } 1709 1710 // Tests that local transactions are journaled to disk, but remote transactions 1711 // get discarded between restarts. 1712 func TestTransactionJournaling(t *testing.T) { testTransactionJournaling(t, false) } 1713 func TestTransactionJournalingNoLocals(t *testing.T) { testTransactionJournaling(t, true) } 1714 1715 func testTransactionJournaling(t *testing.T, nolocals bool) { 1716 t.Parallel() 1717 1718 // Create a temporary file for the journal 1719 file, err := ioutil.TempFile("", "") 1720 if err != nil { 1721 t.Fatalf("failed to create temporary journal: %v", err) 1722 } 1723 journal := file.Name() 1724 defer os.Remove(journal) 1725 1726 // Clean up the temporary file, we only need the path for now 1727 file.Close() 1728 os.Remove(journal) 1729 1730 // Create the original pool to inject transaction into the journal 1731 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1732 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 1733 1734 config := testTxPoolConfig 1735 config.NoLocals = nolocals 1736 config.Journal = journal 1737 config.Rejournal = time.Second 1738 1739 pool := NewTxPool(config, params.TestChainConfig, blockchain) 1740 1741 // Create two test accounts to ensure remotes expire but locals do not 1742 local, _ := crypto.GenerateKey() 1743 remote, _ := crypto.GenerateKey() 1744 1745 pool.currentState.AddBalance(crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000)) 1746 pool.currentState.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000)) 1747 1748 // Add three local and a remote transactions and ensure they are queued up 1749 if err := pool.AddLocal(pricedTransaction(0, 100000, big.NewInt(1), local)); err != nil { 1750 t.Fatalf("failed to add local transaction: %v", err) 1751 } 1752 if err := pool.AddLocal(pricedTransaction(1, 100000, big.NewInt(1), local)); err != nil { 1753 t.Fatalf("failed to add local transaction: %v", err) 1754 } 1755 if err := pool.AddLocal(pricedTransaction(2, 100000, big.NewInt(1), local)); err != nil { 1756 t.Fatalf("failed to add local transaction: %v", err) 1757 } 1758 if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(1), remote)); err != nil { 1759 t.Fatalf("failed to add remote transaction: %v", err) 1760 } 1761 pending, queued := pool.Stats() 1762 if pending != 4 { 1763 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 4) 1764 } 1765 if queued != 0 { 1766 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 1767 } 1768 if err := validateTxPoolInternals(pool); err != nil { 1769 t.Fatalf("pool internal state corrupted: %v", err) 1770 } 1771 // Terminate the old pool, bump the local nonce, create a new pool and ensure relevant transaction survive 1772 pool.Stop() 1773 statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) 1774 blockchain = &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 1775 1776 pool = NewTxPool(config, params.TestChainConfig, blockchain) 1777 1778 pending, queued = pool.Stats() 1779 if queued != 0 { 1780 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 1781 } 1782 if nolocals { 1783 if pending != 0 { 1784 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) 1785 } 1786 } else { 1787 if pending != 2 { 1788 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) 1789 } 1790 } 1791 if err := validateTxPoolInternals(pool); err != nil { 1792 t.Fatalf("pool internal state corrupted: %v", err) 1793 } 1794 // Bump the nonce temporarily and ensure the newly invalidated transaction is removed 1795 statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 2) 1796 pool.lockedReset(nil, nil) 1797 time.Sleep(2 * config.Rejournal) 1798 pool.Stop() 1799 1800 statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) 1801 blockchain = &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 1802 pool = NewTxPool(config, params.TestChainConfig, blockchain) 1803 1804 pending, queued = pool.Stats() 1805 if pending != 0 { 1806 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0) 1807 } 1808 if nolocals { 1809 if queued != 0 { 1810 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) 1811 } 1812 } else { 1813 if queued != 1 { 1814 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) 1815 } 1816 } 1817 if err := validateTxPoolInternals(pool); err != nil { 1818 t.Fatalf("pool internal state corrupted: %v", err) 1819 } 1820 pool.Stop() 1821 } 1822 1823 // TestTransactionStatusCheck tests that the pool can correctly retrieve the 1824 // pending status of individual transactions. 1825 func TestTransactionStatusCheck(t *testing.T) { 1826 t.Parallel() 1827 1828 // Create the pool to test the status retrievals with 1829 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 1830 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 1831 1832 pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) 1833 defer pool.Stop() 1834 1835 // Create the test accounts to check various transaction statuses with 1836 keys := make([]*ecdsa.PrivateKey, 3) 1837 for i := 0; i < len(keys); i++ { 1838 keys[i], _ = crypto.GenerateKey() 1839 pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) 1840 } 1841 // Generate and queue a batch of transactions, both pending and queued 1842 txs := types.Transactions{} 1843 1844 txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[0])) // Pending only 1845 txs = append(txs, pricedTransaction(0, 100000, big.NewInt(1), keys[1])) // Pending and queued 1846 txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[1])) 1847 txs = append(txs, pricedTransaction(2, 100000, big.NewInt(1), keys[2])) // Queued only 1848 1849 // Import the transaction and ensure they are correctly added 1850 pool.AddRemotes(txs) 1851 1852 pending, queued := pool.Stats() 1853 if pending != 2 { 1854 t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) 1855 } 1856 if queued != 2 { 1857 t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) 1858 } 1859 if err := validateTxPoolInternals(pool); err != nil { 1860 t.Fatalf("pool internal state corrupted: %v", err) 1861 } 1862 // Retrieve the status of each transaction and validate them 1863 hashes := make([]common.Hash, len(txs)) 1864 for i, tx := range txs { 1865 hashes[i] = tx.Hash() 1866 } 1867 hashes = append(hashes, common.Hash{}) 1868 1869 statuses := pool.Status(hashes) 1870 expect := []TxStatus{TxStatusPending, TxStatusPending, TxStatusQueued, TxStatusQueued, TxStatusUnknown} 1871 1872 for i := 0; i < len(statuses); i++ { 1873 if statuses[i] != expect[i] { 1874 t.Errorf("transaction %d: status mismatch: have %v, want %v", i, statuses[i], expect[i]) 1875 } 1876 } 1877 } 1878 1879 // Benchmarks the speed of validating the contents of the pending queue of the 1880 // transaction pool. 1881 func BenchmarkPendingDemotion100(b *testing.B) { benchmarkPendingDemotion(b, 100) } 1882 func BenchmarkPendingDemotion1000(b *testing.B) { benchmarkPendingDemotion(b, 1000) } 1883 func BenchmarkPendingDemotion10000(b *testing.B) { benchmarkPendingDemotion(b, 10000) } 1884 1885 func benchmarkPendingDemotion(b *testing.B, size int) { 1886 // Add a batch of transactions to a pool one by one 1887 pool, key := setupTxPool() 1888 defer pool.Stop() 1889 1890 account, _ := deriveSender(transaction(0, 0, key)) 1891 pool.currentState.AddBalance(account, big.NewInt(1000000)) 1892 1893 for i := 0; i < size; i++ { 1894 tx := transaction(uint64(i), 100000, key) 1895 pool.promoteTx(account, tx.Hash(), tx) 1896 } 1897 // Benchmark the speed of pool validation 1898 b.ResetTimer() 1899 for i := 0; i < b.N; i++ { 1900 pool.demoteUnexecutables() 1901 } 1902 } 1903 1904 // Benchmarks the speed of scheduling the contents of the future queue of the 1905 // transaction pool. 1906 func BenchmarkFuturePromotion100(b *testing.B) { benchmarkFuturePromotion(b, 100) } 1907 func BenchmarkFuturePromotion1000(b *testing.B) { benchmarkFuturePromotion(b, 1000) } 1908 func BenchmarkFuturePromotion10000(b *testing.B) { benchmarkFuturePromotion(b, 10000) } 1909 1910 func benchmarkFuturePromotion(b *testing.B, size int) { 1911 // Add a batch of transactions to a pool one by one 1912 pool, key := setupTxPool() 1913 defer pool.Stop() 1914 1915 account, _ := deriveSender(transaction(0, 0, key)) 1916 pool.currentState.AddBalance(account, big.NewInt(1000000)) 1917 1918 for i := 0; i < size; i++ { 1919 tx := transaction(uint64(1+i), 100000, key) 1920 pool.enqueueTx(tx.Hash(), tx) 1921 } 1922 // Benchmark the speed of pool validation 1923 b.ResetTimer() 1924 for i := 0; i < b.N; i++ { 1925 pool.promoteExecutables(nil) 1926 } 1927 } 1928 1929 // Benchmarks the speed of iterative transaction insertion. 1930 func BenchmarkPoolInsert(b *testing.B) { 1931 // Generate a batch of transactions to enqueue into the pool 1932 pool, key := setupTxPool() 1933 defer pool.Stop() 1934 1935 account, _ := deriveSender(transaction(0, 0, key)) 1936 pool.currentState.AddBalance(account, big.NewInt(1000000)) 1937 1938 txs := make(types.Transactions, b.N) 1939 for i := 0; i < b.N; i++ { 1940 txs[i] = transaction(uint64(i), 100000, key) 1941 } 1942 // Benchmark importing the transactions into the queue 1943 b.ResetTimer() 1944 for _, tx := range txs { 1945 pool.AddRemote(tx) 1946 } 1947 } 1948 1949 // Benchmarks the speed of batched transaction insertion. 1950 func BenchmarkPoolBatchInsert100(b *testing.B) { benchmarkPoolBatchInsert(b, 100) } 1951 func BenchmarkPoolBatchInsert1000(b *testing.B) { benchmarkPoolBatchInsert(b, 1000) } 1952 func BenchmarkPoolBatchInsert10000(b *testing.B) { benchmarkPoolBatchInsert(b, 10000) } 1953 1954 func benchmarkPoolBatchInsert(b *testing.B, size int) { 1955 // Generate a batch of transactions to enqueue into the pool 1956 pool, key := setupTxPool() 1957 defer pool.Stop() 1958 1959 account, _ := deriveSender(transaction(0, 0, key)) 1960 pool.currentState.AddBalance(account, big.NewInt(1000000)) 1961 1962 batches := make([]types.Transactions, b.N) 1963 for i := 0; i < b.N; i++ { 1964 batches[i] = make(types.Transactions, size) 1965 for j := 0; j < size; j++ { 1966 batches[i][j] = transaction(uint64(size*i+j), 100000, key) 1967 } 1968 } 1969 // Benchmark importing the transactions into the queue 1970 b.ResetTimer() 1971 for _, batch := range batches { 1972 pool.AddRemotes(batch) 1973 } 1974 } 1975 1976 //Checks that the EIP155 signer is assigned to the TxPool no matter the configuration, even invalid config 1977 func TestEIP155SignerOnTxPool(t *testing.T) { 1978 var flagtests = []struct { 1979 name string 1980 homesteadBlock *big.Int 1981 eip155Block *big.Int 1982 }{ 1983 {"hsnileip155nil", nil, nil}, 1984 {"hsnileip1550", nil, big.NewInt(0)}, 1985 {"hsnileip155100", nil, big.NewInt(100)}, 1986 {"hs0eip155nil", big.NewInt(0), nil}, 1987 {"hs0eip1550", big.NewInt(0), big.NewInt(0)}, 1988 {"hs0eip155100", big.NewInt(0), big.NewInt(100)}, 1989 {"hs100eip155nil", big.NewInt(100), nil}, 1990 {"hs100eip1550", big.NewInt(100), big.NewInt(0)}, 1991 {"hs100eip155100", big.NewInt(100), big.NewInt(100)}, 1992 } 1993 1994 for _, tt := range flagtests { 1995 t.Run("", func(t *testing.T) { 1996 db := ethdb.NewMemDatabase() 1997 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 1998 blockchain := &testBlockChain{statedb, statedb, 1000000, new(event.Feed)} 1999 2000 chainconfig := ¶ms.ChainConfig{ 2001 ChainID: big.NewInt(10), 2002 HomesteadBlock: tt.homesteadBlock, 2003 EIP150Block: big.NewInt(0), 2004 EIP155Block: tt.eip155Block, 2005 EIP158Block: big.NewInt(0), 2006 ByzantiumBlock: big.NewInt(0), 2007 Ethash: new(params.EthashConfig), 2008 } 2009 2010 pool := NewTxPool(testTxPoolConfig, chainconfig, blockchain) 2011 2012 if reflect.TypeOf(types.EIP155Signer{}) != reflect.TypeOf(pool.signer) { 2013 t.Fail() 2014 } 2015 }) 2016 } 2017 2018 }