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