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