github.com/m3shine/gochain@v2.2.26+incompatible/core/tx_pool.go (about) 1 // Copyright 2014 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 "context" 21 "errors" 22 "fmt" 23 "math" 24 "math/big" 25 "sort" 26 "sync" 27 "time" 28 29 "go.opencensus.io/trace" 30 31 "github.com/gochain-io/gochain/common" 32 "github.com/gochain-io/gochain/common/prque" 33 "github.com/gochain-io/gochain/core/state" 34 "github.com/gochain-io/gochain/core/types" 35 "github.com/gochain-io/gochain/eth/gasprice" 36 "github.com/gochain-io/gochain/log" 37 "github.com/gochain-io/gochain/metrics" 38 "github.com/gochain-io/gochain/params" 39 ) 40 41 const ( 42 // chainHeadChanSize is the size of channel listening to ChainHeadEvent. 43 chainHeadChanSize = 32 44 ) 45 46 var ( 47 // ErrInvalidSender is returned if the transaction contains an invalid signature. 48 ErrInvalidSender = errors.New("invalid sender") 49 50 // ErrNonceTooLow is returned if the nonce of a transaction is lower than the 51 // one present in the local chain. 52 ErrNonceTooLow = errors.New("nonce too low") 53 54 // ErrUnderpriced is returned if a transaction's gas price is below the minimum 55 // configured for the transaction pool. 56 ErrUnderpriced = errors.New("transaction underpriced") 57 58 // ErrPoolLimit is returned if the pool is full. 59 ErrPoolLimit = errors.New("transaction pool limit reached") 60 61 // ErrReplaceUnderpriced is returned if a transaction is attempted to be replaced 62 // with a different one without the required price bump. 63 ErrReplaceUnderpriced = errors.New("replacement transaction underpriced") 64 65 // ErrInsufficientFunds is returned if the total cost of executing a transaction 66 // is higher than the balance of the user's account. 67 ErrInsufficientFunds = errors.New("insufficient funds for gas * price + value") 68 69 // ErrIntrinsicGas is returned if the transaction is specified to use less gas 70 // than required to start the invocation. 71 ErrIntrinsicGas = errors.New("intrinsic gas too low") 72 73 // ErrGasLimit is returned if a transaction's requested gas limit exceeds the 74 // maximum allowance of the current block. 75 ErrGasLimit = errors.New("exceeds block gas limit") 76 77 // ErrNegativeValue is a sanity error to ensure noone is able to specify a 78 // transaction with a negative value. 79 ErrNegativeValue = errors.New("negative value") 80 81 // ErrOversizedData is returned if the input data of a transaction is greater 82 // than some meaningful limit a user might use. This is not a consensus error 83 // making the transaction invalid, rather a DOS protection. 84 ErrOversizedData = errors.New("oversized data") 85 ) 86 87 var ( 88 evictionInterval = time.Minute // Time interval to check for evictable transactions 89 statsReportInterval = 10 * time.Second // Time interval to report transaction pool stats 90 ) 91 92 var ( 93 // Metrics for the pending pool 94 pendingGauge = metrics.NewRegisteredGauge("txpool/pending", nil) 95 pendingDiscardCounter = metrics.NewRegisteredCounter("txpool/pending/discard", nil) 96 pendingReplaceCounter = metrics.NewRegisteredCounter("txpool/pending/replace", nil) 97 pendingRateLimitCounter = metrics.NewRegisteredCounter("txpool/pending/ratelimit", nil) // Dropped due to rate limiting 98 pendingNofundsCounter = metrics.NewRegisteredCounter("txpool/pending/nofunds", nil) // Dropped due to out-of-funds 99 100 // Metrics for the queued pool 101 queuedGauge = metrics.NewRegisteredGauge("txpool/queued", nil) 102 queuedDiscardCounter = metrics.NewRegisteredCounter("txpool/queued/discard", nil) 103 queuedReplaceCounter = metrics.NewRegisteredCounter("txpool/queued/replace", nil) 104 queuedRateLimitCounter = metrics.NewRegisteredCounter("txpool/queued/ratelimit", nil) // Dropped due to rate limiting 105 queuedNofundsCounter = metrics.NewRegisteredCounter("txpool/queued/nofunds", nil) // Dropped due to out-of-funds 106 107 // General tx metrics 108 invalidTxCounter = metrics.NewRegisteredCounter("txpool/invalid", nil) 109 underpricedTxCounter = metrics.NewRegisteredCounter("txpool/underpriced", nil) 110 globalSlotsGauge = metrics.NewRegisteredGauge("txpool/slots", nil) 111 globalQueueGauge = metrics.NewRegisteredGauge("txpool/queue", nil) 112 poolAddTimer = metrics.NewRegisteredTimer("txpool/add", nil) 113 journalInsertTimer = metrics.NewRegisteredTimer("txpool/journal/insert", nil) 114 chainHeadGauge = metrics.NewRegisteredGauge("txpool/chain/head", nil) 115 chainHeadTxsGauge = metrics.NewRegisteredGauge("txpool/chain/head/txs", nil) 116 ) 117 118 // TxStatus is the current status of a transaction as seen by the pool. 119 type TxStatus uint 120 121 const ( 122 TxStatusUnknown TxStatus = iota 123 TxStatusQueued 124 TxStatusPending 125 TxStatusIncluded 126 ) 127 128 // blockChain provides the state of blockchain and current gas limit to do 129 // some pre checks in tx pool and event subscribers. 130 type blockChain interface { 131 CurrentBlock() *types.Block 132 GetBlock(hash common.Hash, number uint64) *types.Block 133 StateAt(root common.Hash) (*state.StateDB, error) 134 135 SubscribeChainHeadEvent(ch chan<- ChainHeadEvent, name string) 136 UnsubscribeChainHeadEvent(ch chan<- ChainHeadEvent) 137 } 138 139 // TxPoolConfig are the configuration parameters of the transaction pool. 140 type TxPoolConfig struct { 141 Locals []common.Address // Addresses that should be treated by default as local 142 NoLocals bool `toml:",omitempty"` // Whether local transaction handling should be disabled 143 Journal string `toml:",omitempty"` // Journal of local transactions to survive node restarts 144 Rejournal time.Duration `toml:",omitempty"` // Time interval to regenerate the local transaction journal 145 146 PriceLimit uint64 `toml:",omitempty"` // Minimum gas price to enforce for acceptance into the pool 147 PriceBump uint64 `toml:",omitempty"` // Minimum price bump percentage to replace an already existing transaction (nonce) 148 149 AccountSlots uint64 `toml:",omitempty"` // Minimum number of executable transaction slots guaranteed per account 150 GlobalSlots uint64 `toml:",omitempty"` // Maximum number of executable transaction slots for all accounts 151 AccountQueue uint64 `toml:",omitempty"` // Maximum number of non-executable transaction slots permitted per account 152 GlobalQueue uint64 `toml:",omitempty"` // Maximum number of non-executable transaction slots for all accounts 153 154 Lifetime time.Duration `toml:",omitempty"` // Maximum amount of time non-executable transaction are queued 155 } 156 157 // DefaultTxPoolConfig contains the default configurations for the transaction 158 // pool. 159 var DefaultTxPoolConfig = TxPoolConfig{ 160 Journal: "transactions.rlp", 161 Rejournal: time.Hour, 162 163 PriceLimit: gasprice.Default.Uint64(), 164 PriceBump: 10, 165 166 AccountSlots: 8192, 167 GlobalSlots: 131072, 168 AccountQueue: 4096, 169 GlobalQueue: 32768, 170 171 Lifetime: 3 * time.Hour, 172 } 173 174 // sanitize checks the provided user configurations and changes anything that's 175 // unreasonable or unworkable. 176 func (config *TxPoolConfig) sanitize() TxPoolConfig { 177 conf := *config 178 if conf.Rejournal < time.Second { 179 log.Warn("Sanitizing invalid txpool journal time", "provided", conf.Rejournal, "updated", time.Second) 180 conf.Rejournal = time.Second 181 } 182 if conf.PriceLimit < 1 { 183 log.Warn("Sanitizing invalid txpool price limit", "provided", conf.PriceLimit, "updated", DefaultTxPoolConfig.PriceLimit) 184 conf.PriceLimit = DefaultTxPoolConfig.PriceLimit 185 } 186 if conf.PriceBump < 1 { 187 log.Warn("Sanitizing invalid txpool price bump", "provided", conf.PriceBump, "updated", DefaultTxPoolConfig.PriceBump) 188 conf.PriceBump = DefaultTxPoolConfig.PriceBump 189 } 190 if conf.AccountSlots <= 0 { 191 log.Warn("Sanitizing invalid txpool account slots", "provided", conf.AccountSlots, "updated", DefaultTxPoolConfig.AccountSlots) 192 conf.AccountSlots = DefaultTxPoolConfig.AccountSlots 193 } 194 if conf.GlobalSlots <= 0 { 195 log.Warn("Sanitizing invalid txpool global slots", "provided", conf.GlobalSlots, "updated", DefaultTxPoolConfig.GlobalSlots) 196 conf.GlobalSlots = DefaultTxPoolConfig.GlobalSlots 197 } 198 if conf.AccountQueue <= 0 { 199 log.Warn("Sanitizing invalid txpool account queue", "provided", conf.AccountQueue, "updated", DefaultTxPoolConfig.AccountQueue) 200 conf.AccountQueue = DefaultTxPoolConfig.AccountQueue 201 } 202 if conf.GlobalQueue <= 0 { 203 log.Warn("Sanitizing invalid txpool global queue", "provided", conf.GlobalQueue, "updated", DefaultTxPoolConfig.GlobalQueue) 204 conf.GlobalQueue = DefaultTxPoolConfig.GlobalQueue 205 } 206 if conf.Lifetime <= 0 { 207 log.Warn("Sanitizing invalid txpool lifetime", "provided", conf.Lifetime, "updated", DefaultTxPoolConfig.Lifetime) 208 conf.Lifetime = DefaultTxPoolConfig.Lifetime 209 } 210 return conf 211 } 212 213 // TxPool contains all currently known transactions. Transactions 214 // enter the pool when they are received from the network or submitted 215 // locally. They exit the pool when they are included in the blockchain. 216 // 217 // The pool separates processable transactions (which can be applied to the 218 // current state) and future transactions. Transactions move between those 219 // two states over time as they are received and processed. 220 type TxPool struct { 221 config TxPoolConfig 222 chainconfig *params.ChainConfig 223 224 chain blockChain 225 gasPrice *big.Int 226 227 txFeedBuf chan *types.Transaction 228 229 txFeed NewTxsFeed 230 231 chainHeadCh chan ChainHeadEvent 232 233 signer types.Signer 234 mu sync.RWMutex 235 236 currentState *state.StateDB // Current state in the blockchain head 237 pendingState *state.ManagedState // Pending state tracking virtual nonces 238 currentMaxGas uint64 // Current gas limit for transaction caps 239 240 locals *accountSet // Set of local transaction to exempt from eviction rules 241 journal *txJournal // Journal of local transaction to back up to disk 242 243 pending map[common.Address]*txList // All currently processable transactions 244 queue map[common.Address]*txList // Queued but non-processable transactions 245 beats map[common.Address]time.Time // Last heartbeat from each known account 246 all *txLookup // All transactions to allow lookups 247 248 wg sync.WaitGroup // for shutdown sync 249 250 homestead bool 251 252 stop chan struct{} 253 } 254 255 // NewTxPool creates a new transaction pool to gather, sort and filter inbound 256 // transactions from the network. 257 func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain) *TxPool { 258 ctx, span := trace.StartSpan(context.Background(), "NewTxPool") 259 defer span.End() 260 261 // Sanitize the input to ensure no vulnerable gas prices are set 262 config = (&config).sanitize() 263 264 // Create the transaction pool with its initial settings 265 pool := &TxPool{ 266 config: config, 267 chainconfig: chainconfig, 268 chain: chain, 269 signer: types.NewEIP155Signer(chainconfig.ChainId), 270 pending: make(map[common.Address]*txList), 271 queue: make(map[common.Address]*txList), 272 beats: make(map[common.Address]time.Time), 273 all: newTxLookup(int(config.GlobalSlots / 2)), 274 chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize), 275 gasPrice: new(big.Int).SetUint64(config.PriceLimit), 276 txFeedBuf: make(chan *types.Transaction, config.GlobalSlots/4), 277 } 278 pool.locals = newAccountSet(pool.signer) 279 pool.reset(ctx, nil, chain.CurrentBlock()) 280 281 // If local transactions and journaling is enabled, load from disk 282 if !config.NoLocals && config.Journal != "" { 283 ctx, span := trace.StartSpan(ctx, "NewTxPool-journal") 284 pool.journal = newTxJournal(config.Journal) 285 if err := pool.journal.load(func(txs types.Transactions) []error { 286 // No need to lock since we're still setting up. 287 return pool.addTxsLocked(ctx, txs, !pool.config.NoLocals) 288 }); err != nil { 289 log.Warn("Failed to load transaction journal", "err", err) 290 } 291 if err := pool.journal.rotate(pool.local()); err != nil { 292 log.Warn("Failed to rotate transaction journal", "err", err) 293 } 294 span.End() 295 } 296 297 // Subscribe events from blockchain. 298 pool.chain.SubscribeChainHeadEvent(pool.chainHeadCh, "core.TxPool") 299 // Spawn worker routines to run until chainHeadSub unsub. 300 pool.wg.Add(2) 301 pool.stop = make(chan struct{}) 302 go pool.loop() 303 go pool.feedLoop() 304 305 return pool 306 } 307 308 // loop is the transaction pool's main event loop, waiting for and reacting to 309 // outside blockchain events as well as for various reporting and transaction 310 // eviction events. 311 func (pool *TxPool) loop() { 312 defer pool.wg.Done() 313 314 // Start the stats reporting and transaction eviction tickers 315 var prevPending, prevQueued int 316 317 report := time.NewTicker(statsReportInterval) 318 defer report.Stop() 319 320 evict := time.NewTicker(evictionInterval) 321 defer evict.Stop() 322 323 journal := time.NewTicker(pool.config.Rejournal) 324 defer journal.Stop() 325 326 globalSlotsGauge.Update(int64(pool.config.GlobalSlots)) 327 globalQueueGauge.Update(int64(pool.config.GlobalQueue)) 328 329 // Track the previous head block for resets. 330 head := pool.chain.CurrentBlock() 331 chainHeadGauge.Update(int64(head.NumberU64())) 332 chainHeadTxsGauge.Update(int64(len(head.Transactions()))) 333 334 // Keep waiting for and reacting to the various events. 335 for { 336 select { 337 case <-pool.stop: 338 return 339 340 // Handle ChainHeadEvent 341 case ev, ok := <-pool.chainHeadCh: 342 if !ok { 343 return 344 } 345 if ev.Block != nil { 346 ctx, span := trace.StartSpan(context.Background(), "TxPool.loop-reset") 347 pool.mu.Lock() 348 if pool.chainconfig.IsHomestead(ev.Block.Number()) { 349 pool.homestead = true 350 } 351 pool.reset(ctx, head, ev.Block) 352 head = ev.Block 353 pool.mu.Unlock() 354 355 chainHeadGauge.Update(int64(head.NumberU64())) 356 chainHeadTxsGauge.Update(int64(len(head.Transactions()))) 357 span.End() 358 } 359 360 // Handle stats reporting ticks 361 case <-report.C: 362 ctx, span := trace.StartSpan(context.Background(), "TxPool.loop-report") 363 pending, queued := pool.StatsCtx(ctx) 364 365 pendingGauge.Update(int64(pending)) 366 queuedGauge.Update(int64(queued)) 367 368 if pending != prevPending || queued != prevQueued { 369 log.Debug("Transaction pool status report", "executable", pending, "queued", queued) 370 prevPending, prevQueued = pending, queued 371 } 372 span.End() 373 374 // Handle inactive account transaction eviction 375 case <-evict.C: 376 _, span := trace.StartSpan(context.Background(), "TxPool.loop-evict") 377 pool.mu.Lock() 378 for addr := range pool.queue { 379 // Skip local transactions from the eviction mechanism 380 if pool.locals.contains(addr) { 381 continue 382 } 383 // Any non-locals old enough should be removed 384 if time.Since(pool.beats[addr]) > pool.config.Lifetime { 385 queued := pool.queue[addr] 386 for _, tx := range queued.txs.items { 387 pool.all.Remove(tx.Hash()) 388 } 389 delete(pool.queue, addr) 390 } 391 } 392 pool.mu.Unlock() 393 span.End() 394 395 // Handle local transaction journal rotation 396 case <-journal.C: 397 if pool.journal != nil { 398 _, span := trace.StartSpan(context.Background(), "TxPool.loop-journal") 399 pool.mu.Lock() 400 if err := pool.journal.rotate(pool.local()); err != nil { 401 log.Warn("Failed to rotate local tx journal", "err", err) 402 } 403 pool.mu.Unlock() 404 span.End() 405 } 406 } 407 } 408 } 409 410 // queueFeedSend queues tx to eventually be sent on the txFeed. 411 func (pool *TxPool) queueFeedSend(tx *types.Transaction) { 412 select { 413 case <-pool.stop: 414 return 415 case pool.txFeedBuf <- tx: 416 return 417 default: 418 go func() { 419 select { 420 case <-pool.stop: 421 return 422 case pool.txFeedBuf <- tx: 423 } 424 }() 425 } 426 } 427 428 // feedLoop continuously sends batches of txs from the txFeedBuf to the txFeed. 429 func (pool *TxPool) feedLoop() { 430 defer pool.wg.Done() 431 432 const batchSize = 1000 433 for { 434 select { 435 case <-pool.stop: 436 return 437 case tx := <-pool.txFeedBuf: 438 var event NewTxsEvent 439 event.Txs = append(event.Txs, tx) 440 batchLoop: 441 for i := 1; i < batchSize; i++ { 442 select { 443 case tx := <-pool.txFeedBuf: 444 event.Txs = append(event.Txs, tx) 445 default: 446 break batchLoop 447 } 448 } 449 pool.txFeed.Send(event) 450 451 // Unless another full batch is ready, then wait a bit. 452 if len(pool.txFeedBuf) < batchSize { 453 select { 454 case <-pool.stop: 455 return 456 case <-time.After(50 * time.Millisecond): 457 } 458 } 459 } 460 } 461 } 462 463 const maxReorgDepth = 64 464 465 // reset retrieves the current state of the blockchain and ensures the content 466 // of the transaction pool is valid with regard to the chain state. 467 func (pool *TxPool) reset(ctx context.Context, oldBlock, newBlock *types.Block) { 468 ctx, span := trace.StartSpan(ctx, "TxPool.reset") 469 defer span.End() 470 471 significant := true 472 if oldBlock == nil { 473 if newBlock != nil { 474 log.Info("Resetting tx pool", "old", nil, "newnum", newBlock.NumberU64(), "newhash", newBlock.Hash()) 475 } 476 } else { 477 significant = newBlock.ParentHash() != oldBlock.Hash() 478 if significant { 479 log.Info("Resetting tx pool", "oldnum", oldBlock.NumberU64(), "newnum", newBlock.NumberU64(), "oldhash", oldBlock.Hash(), "newhash", newBlock.Hash(), "newparent", newBlock.ParentHash()) 480 } 481 } 482 start := time.Now() 483 484 // If we're reorging an old state, reinject all dropped transactions 485 reinject := make(map[common.Hash]*types.Transaction) 486 487 if oldBlock != nil && oldBlock.Hash() != newBlock.ParentHash() { 488 // If the reorg is too deep, avoid doing it (will happen during fast sync) 489 branchNum := oldBlock.NumberU64() 490 mainNum := newBlock.NumberU64() 491 492 var depth uint64 493 if branchNum > mainNum { 494 depth = branchNum - mainNum 495 } else { 496 depth = mainNum - branchNum 497 } 498 if depth > maxReorgDepth { 499 // Too deep to pull all transactions into memory. 500 log.Warn("Skipping deep transaction reorg", "depth", depth) 501 } else { 502 // Set of txs included in the main chain. 503 included := make(map[common.Hash]struct{}) 504 var ( 505 branch = oldBlock 506 main = newBlock 507 ) 508 // Rewind main up the chain to a possible common ancestor. 509 for main.NumberU64() > branchNum { 510 for _, tx := range main.Transactions() { 511 included[tx.Hash()] = struct{}{} 512 } 513 if main = pool.chain.GetBlock(main.ParentHash(), main.NumberU64()-1); main == nil { 514 log.Error("Unrooted new chain seen by tx pool", "block", mainNum, "hash", newBlock.Hash()) 515 return 516 } 517 } 518 // Rewind branch up the chain to a possible common ancestor. 519 for branch.NumberU64() > mainNum { 520 for _, tx := range branch.Transactions() { 521 if _, ok := included[tx.Hash()]; !ok { 522 reinject[tx.Hash()] = tx 523 } 524 } 525 if branch = pool.chain.GetBlock(branch.ParentHash(), branch.NumberU64()-1); branch == nil { 526 log.Error("Unrooted old chain seen by tx pool", "block", branchNum, "hash", oldBlock.Hash()) 527 return 528 } 529 } 530 // Continue up the chain until a common ancestor is found. 531 for branch.Hash() != main.Hash() { 532 for _, tx := range main.Transactions() { 533 hash := tx.Hash() 534 if _, ok := reinject[hash]; ok { 535 delete(reinject, hash) 536 } 537 included[hash] = struct{}{} 538 } 539 if main = pool.chain.GetBlock(main.ParentHash(), main.NumberU64()-1); main == nil { 540 log.Error("Unrooted new chain seen by tx pool", "block", mainNum, "hash", newBlock.Hash()) 541 return 542 } 543 for _, tx := range branch.Transactions() { 544 if _, ok := included[tx.Hash()]; !ok { 545 reinject[tx.Hash()] = tx 546 } 547 } 548 if branch = pool.chain.GetBlock(branch.ParentHash(), branch.NumberU64()-1); branch == nil { 549 log.Error("Unrooted old chain seen by tx pool", "block", branchNum, "hash", oldBlock.Hash()) 550 return 551 } 552 } 553 } 554 } 555 // Initialize the internal state to the current head 556 if newBlock == nil { 557 newBlock = pool.chain.CurrentBlock() // Special case during testing 558 } 559 statedb, err := pool.chain.StateAt(newBlock.Root()) 560 if err != nil { 561 log.Error("Failed to reset txpool state", "err", err) 562 return 563 } 564 pool.currentState = statedb 565 pool.pendingState = state.ManageState(ctx, statedb) 566 pool.currentMaxGas = newBlock.GasLimit() 567 568 if l := len(reinject); l > 0 { 569 // Inject any transactions discarded due to reorgs. 570 log.Debug("Reinjecting stale transactions", "count", l) 571 if errs := pool.reinject(ctx, reinject); len(errs) > 0 { 572 log.Error("Failed to reinject txs during pool reset", "total", l, "errs", len(errs)) 573 if log.Tracing() { 574 for i, err := range errs { 575 log.Trace("Failed to reinject tx", "num", i, "err", err) 576 } 577 } 578 } 579 } 580 581 // validate the pool of pending transactions, this will remove 582 // any transactions that have been included in the block or 583 // have been invalidated because of another transaction (e.g. 584 // higher gas price) 585 pool.demoteUnexecutables(ctx) 586 587 // Update all accounts to the latest known pending nonce 588 for addr, list := range pool.pending { 589 pool.pendingState.SetNonce(addr, list.Last().Nonce()+1) 590 } 591 // Check the queue and move transactions over to the pending if possible 592 // or remove those that have become invalid 593 pool.promoteExecutablesAll(ctx) 594 595 if significant { 596 dur := time.Since(start) 597 log.Info("Reset tx pool", "dur", common.PrettyDuration(dur)) 598 } 599 } 600 601 // Stop terminates the transaction pool. 602 func (pool *TxPool) Stop() { 603 close(pool.stop) 604 // Unsubscribe all subscriptions. 605 pool.txFeed.Close() 606 pool.chain.UnsubscribeChainHeadEvent(pool.chainHeadCh) 607 pool.wg.Wait() 608 609 if pool.journal != nil { 610 if err := pool.journal.close(); err != nil { 611 log.Error("Cannot close tx pool journal", "err", err) 612 } 613 } 614 log.Info("Transaction pool stopped") 615 } 616 617 // SubscribeNewTxsEvent registers a subscription of NewTxsEvent and 618 // starts sending event to the given channel. 619 func (pool *TxPool) SubscribeNewTxsEvent(ch chan<- NewTxsEvent, name string) { 620 pool.txFeed.Subscribe(ch, name) 621 } 622 623 func (pool *TxPool) UnsubscribeNewTxsEvent(ch chan<- NewTxsEvent) { 624 pool.txFeed.Unsubscribe(ch) 625 } 626 627 // SetGasPrice updates the minimum price required by the transaction pool for a 628 // new transaction, and drops all transactions below this threshold. 629 func (pool *TxPool) SetGasPrice(ctx context.Context, price *big.Int) { 630 ctx, span := trace.StartSpan(ctx, "TxPool.SetGasPrice") 631 defer span.End() 632 633 pool.mu.Lock() 634 defer pool.mu.Unlock() 635 636 pool.gasPrice = price 637 pool.all.ForEach(func(tx *types.Transaction) { 638 if tx.CmpGasPrice(price) < 0 && !pool.locals.containsTx(ctx, tx) { 639 pool.removeTx(ctx, tx) 640 } 641 }) 642 log.Info("Transaction pool price threshold updated", "price", price) 643 } 644 645 // State returns the virtual managed state of the transaction pool. 646 func (pool *TxPool) State() *state.ManagedState { 647 pool.mu.RLock() 648 defer pool.mu.RUnlock() 649 650 return pool.pendingState 651 } 652 653 // Stats retrieves the current pool stats, namely the number of pending and the 654 // number of queued (non-executable) transactions. 655 func (pool *TxPool) Stats() (int, int) { 656 return pool.StatsCtx(context.Background()) 657 } 658 func (pool *TxPool) StatsCtx(ctx context.Context) (int, int) { 659 ctx, span := trace.StartSpan(ctx, "TxPool.StatsCtx") 660 defer span.End() 661 662 pool.mu.RLock() 663 defer pool.mu.RUnlock() 664 665 return pool.stats(ctx) 666 } 667 668 // stats retrieves the current pool stats, namely the number of pending and the 669 // number of queued (non-executable) transactions. 670 func (pool *TxPool) stats(ctx context.Context) (int, int) { 671 ctx, span := trace.StartSpan(ctx, "TxPool.stats") 672 defer span.End() 673 674 pending := 0 675 for _, list := range pool.pending { 676 pending += list.Len() 677 } 678 queued := 0 679 for _, list := range pool.queue { 680 queued += list.Len() 681 } 682 return pending, queued 683 } 684 685 // Content retrieves the data content of the transaction pool, returning all the 686 // pending as well as queued transactions, grouped by account and sorted by nonce. 687 func (pool *TxPool) Content(ctx context.Context) (map[common.Address]types.Transactions, map[common.Address]types.Transactions) { 688 ctx, span := trace.StartSpan(ctx, "TxPool.Content") 689 defer span.End() 690 pool.mu.Lock() 691 defer pool.mu.Unlock() 692 693 pending := make(map[common.Address]types.Transactions) 694 for addr, list := range pool.pending { 695 pending[addr] = list.Flatten() 696 } 697 queued := make(map[common.Address]types.Transactions) 698 for addr, list := range pool.queue { 699 queued[addr] = list.Flatten() 700 } 701 return pending, queued 702 } 703 704 // Pending retrieves all currently processable transactions, groupped by origin 705 // account and sorted by nonce. The returned transaction set is a copy and can be 706 // freely modified by calling code. 707 func (pool *TxPool) Pending(ctx context.Context) map[common.Address]types.Transactions { 708 ctx, span := trace.StartSpan(ctx, "TxPool.Pending") 709 defer span.End() 710 pool.mu.Lock() 711 defer pool.mu.Unlock() 712 713 pending := make(map[common.Address]types.Transactions, len(pool.pending)) 714 for addr, list := range pool.pending { 715 pending[addr] = list.Flatten() 716 } 717 return pending 718 } 719 720 // PendingList is like Pending, but only txs. 721 func (pool *TxPool) PendingList(ctx context.Context) types.Transactions { 722 ctx, span := trace.StartSpan(ctx, "TxPool.PendingList") 723 defer span.End() 724 pool.mu.Lock() 725 defer pool.mu.Unlock() 726 727 var pending types.Transactions 728 for _, list := range pool.pending { 729 list.txs.ensureCache() 730 pending = append(pending, list.txs.cache...) 731 } 732 return pending 733 } 734 735 // Locals retrieves the accounts currently considered local by the pool. 736 func (pool *TxPool) Locals() []common.Address { 737 pool.mu.Lock() 738 defer pool.mu.Unlock() 739 740 return pool.locals.flatten() 741 } 742 743 // local retrieves all currently known local transactions. The returned 744 // transaction set is a copy and can be freely modified by calling code. 745 func (pool *TxPool) local() (int, types.Transactions) { 746 var acts int 747 var txs types.Transactions 748 for addr := range pool.locals.accounts { 749 var ok bool 750 if pending := pool.pending[addr]; pending != nil { 751 ok = true 752 pending.txs.ensureCache() 753 txs = append(txs, pending.txs.cache...) 754 } 755 if queued := pool.queue[addr]; queued != nil { 756 ok = true 757 queued.txs.ensureCache() 758 txs = append(txs, queued.txs.cache...) 759 } 760 if ok { 761 acts++ 762 } 763 } 764 return acts, txs 765 } 766 767 // preValidateTx does preliminary transaction validation (a subset of validateTx), without requiring pool.mu to be held. 768 func (pool *TxPool) preValidateTx(ctx context.Context, tx *types.Transaction, local bool) error { 769 // Heuristic limit, reject transactions over 32KB to prevent DOS attacks 770 if tx.Size() > 32*1024 { 771 return ErrOversizedData 772 } 773 // Transactions can't be negative. This may never happen using RLP decoded 774 // transactions but may occur if you create a transaction using the RPC. 775 if tx.Value().Sign() < 0 { 776 return ErrNegativeValue 777 } 778 // Make sure the transaction is signed properly 779 _, err := types.Sender(pool.signer, tx) 780 if err != nil { 781 return ErrInvalidSender 782 } 783 return nil 784 } 785 786 // validateTx checks whether a transaction is valid according to the consensus 787 // rules and adheres to some heuristic limits of the local node (price and size). 788 // The caller must hold pool.mu. 789 func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction, local bool) error { 790 ctx, span := trace.StartSpan(ctx, "TxPool.validateTx") 791 defer span.End() 792 793 // Heuristic limit, reject transactions over 32KB to prevent DOS attacks 794 if tx.Size() > 32*1024 { 795 return ErrOversizedData 796 } 797 // Transactions can't be negative. This may never happen using RLP decoded 798 // transactions but may occur if you create a transaction using the RPC. 799 if tx.Value().Sign() < 0 { 800 return ErrNegativeValue 801 } 802 // Ensure the transaction doesn't exceed the current block limit gas. 803 if pool.currentMaxGas < tx.Gas() { 804 return ErrGasLimit 805 } 806 // Make sure the transaction is signed properly 807 from, err := types.Sender(pool.signer, tx) 808 if err != nil { 809 return ErrInvalidSender 810 } 811 // Drop non-local transactions under our own minimal accepted gas price 812 local = local || pool.locals.contains(from) // account may be local even if the transaction arrived from the network 813 if !local && tx.CmpGasPrice(pool.gasPrice) < 0 { 814 return ErrUnderpriced 815 } 816 // Ensure the transaction adheres to nonce ordering 817 if pool.currentState.GetNonce(from) > tx.Nonce() { 818 return ErrNonceTooLow 819 } 820 // Transactor should have enough funds to cover the costs 821 // cost == V + GP * GL 822 if pool.currentState.GetBalance(from).Cmp(tx.Cost()) < 0 { 823 return ErrInsufficientFunds 824 } 825 intrGas, err := IntrinsicGas(tx.Data(), tx.To() == nil, pool.homestead) 826 if err != nil { 827 return err 828 } 829 if tx.Gas() < intrGas { 830 return ErrIntrinsicGas 831 } 832 return nil 833 } 834 835 // add validates a transaction and inserts it into the non-executable queue for 836 // later pending promotion and execution. If the transaction is a replacement for 837 // an already pending or queued one, it overwrites the previous and returns this 838 // so outer code doesn't uselessly call promote. 839 // 840 // If a newly added transaction is marked as local, its sending account will be 841 // whitelisted, preventing any associated transaction from being dropped out of 842 // the pool due to pricing constraints. 843 func (pool *TxPool) add(ctx context.Context, tx *types.Transaction, local bool) (bool, error) { 844 ctx, span := trace.StartSpan(ctx, "TxPool.add") 845 defer span.End() 846 847 t := time.Now() 848 // If the transaction is already known, discard it. 849 hash := tx.Hash() 850 if pool.all.Get(hash) != nil { 851 if log.Tracing() { 852 log.Trace("Discarding already known transaction", "hash", hash) 853 } 854 return false, fmt.Errorf("known transaction: %x", hash) 855 } 856 // If the transaction fails basic validation, discard it. 857 if err := pool.validateTx(ctx, tx, local); err != nil { 858 if log.Tracing() { 859 log.Trace("Discarding invalid transaction", "hash", hash, "err", err) 860 } 861 invalidTxCounter.Inc(1) 862 span.SetStatus(trace.Status{ 863 Code: trace.StatusCodeFailedPrecondition, 864 Message: err.Error(), 865 }) 866 return false, err 867 } 868 // If the transaction pool is full, reject. 869 if uint64(pool.all.Count()) >= pool.config.GlobalSlots+pool.config.GlobalQueue { 870 return false, ErrPoolLimit 871 } 872 // If the transaction is replacing an already pending one, do directly 873 from, _ := types.Sender(pool.signer, tx) // already validated 874 if pending := pool.pending[from]; pending != nil && pending.Overlaps(tx) { 875 // Nonce already pending, check if required price bump is met 876 inserted, old := pending.Add(tx, pool.config.PriceBump) 877 if !inserted { 878 pendingDiscardCounter.Inc(1) 879 return false, ErrReplaceUnderpriced 880 } 881 // New transaction is better, replace old one 882 if old != nil { 883 pool.all.Remove(old.Hash()) 884 pendingReplaceCounter.Inc(1) 885 } 886 pool.all.Add(tx) 887 pool.journalTx(from, tx) 888 889 if log.Tracing() { 890 log.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To()) 891 } 892 poolAddTimer.UpdateSince(t) 893 894 // We've directly injected a replacement transaction, notify subsystems 895 pool.queueFeedSend(tx) 896 897 return old != nil, nil 898 } 899 // New transaction isn't replacing a pending one, push into queue 900 replace, err := pool.enqueueTx(ctx, tx) 901 if err != nil { 902 return false, err 903 } 904 // Mark local addresses and journal local transactions 905 if local { 906 pool.locals.add(from) 907 } 908 pool.journalTx(from, tx) 909 910 if log.Tracing() { 911 log.Trace("Pooled new future transaction", "hash", hash, "from", from, "to", tx.To()) 912 } 913 poolAddTimer.UpdateSince(t) 914 915 return replace, nil 916 } 917 918 // enqueueTx inserts a new transaction into the non-executable transaction queue. 919 // 920 // Caller must hold pool.mu. 921 func (pool *TxPool) enqueueTx(ctx context.Context, tx *types.Transaction) (bool, error) { 922 ctx, span := trace.StartSpan(ctx, "TxPool.enqueueTx") 923 defer span.End() 924 925 // Try to insert the transaction into the future queue 926 from, _ := types.Sender(pool.signer, tx) // already validated 927 if pool.queue[from] == nil { 928 pool.queue[from] = newTxList(false) 929 } 930 inserted, old := pool.queue[from].Add(tx, pool.config.PriceBump) 931 if !inserted { 932 // An older transaction was better, discard this 933 queuedDiscardCounter.Inc(1) 934 return false, ErrReplaceUnderpriced 935 } 936 // Discard any previous transaction and mark this 937 if old != nil { 938 pool.all.Remove(old.Hash()) 939 queuedReplaceCounter.Inc(1) 940 } 941 pool.all.Add(tx) 942 return old != nil, nil 943 } 944 945 // journalTx adds the specified transaction to the local disk journal if it is 946 // deemed to have been sent from a local account. 947 func (pool *TxPool) journalTx(from common.Address, tx *types.Transaction) { 948 // Only journal if it's enabled and the transaction is local 949 if pool.journal == nil || !pool.locals.contains(from) { 950 return 951 } 952 953 t := time.Now() 954 if err := pool.journal.insert(tx); err != nil { 955 log.Warn("Failed to journal local transaction", "err", err) 956 return 957 } 958 journalInsertTimer.UpdateSince(t) 959 } 960 961 // promoteTx adds a transaction to the pending (processable) list of transactions 962 // and returns whether it was inserted or an older was better. 963 // 964 // Note, this method assumes the pool lock is held! 965 func (pool *TxPool) promoteTx(ctx context.Context, addr common.Address, hash common.Hash, tx *types.Transaction) bool { 966 ctx, span := trace.StartSpan(ctx, "TxPool.promoteTx") 967 defer span.End() 968 969 // Try to insert the transaction into the pending queue 970 if pool.pending[addr] == nil { 971 pool.pending[addr] = newTxList(true) 972 } 973 inserted, old := pool.pending[addr].Add(tx, pool.config.PriceBump) 974 if !inserted { 975 // An older transaction was better, discard this 976 pool.all.Remove(hash) 977 978 pendingDiscardCounter.Inc(1) 979 return false 980 } 981 // Otherwise discard any previous transaction and mark this 982 if old != nil { 983 pool.all.Remove(old.Hash()) 984 985 pendingReplaceCounter.Inc(1) 986 } 987 // Failsafe to work around direct pending inserts (tests) 988 if pool.all.Get(hash) == nil { 989 pool.all.Add(tx) 990 } 991 // Set the potentially new pending nonce and notify any subsystems of the new tx 992 pool.beats[addr] = time.Now() 993 pool.pendingState.SetNonce(addr, tx.Nonce()+1) 994 995 return true 996 } 997 998 // AddLocal enqueues a single transaction into the pool if it is valid, marking 999 // the sender as a local one in the mean time, ensuring it goes around the local 1000 // pricing constraints. 1001 func (pool *TxPool) AddLocal(ctx context.Context, tx *types.Transaction) error { 1002 return pool.addTx(ctx, tx, !pool.config.NoLocals) 1003 } 1004 1005 // AddRemote enqueues a single transaction into the pool if it is valid. If the 1006 // sender is not among the locally tracked ones, full pricing constraints will 1007 // apply. 1008 func (pool *TxPool) AddRemote(ctx context.Context, tx *types.Transaction) error { 1009 return pool.addTx(ctx, tx, false) 1010 } 1011 1012 // AddLocals enqueues a batch of transactions into the pool if they are valid, 1013 // marking the senders as a local ones in the mean time, ensuring they go around 1014 // the local pricing constraints. 1015 func (pool *TxPool) AddLocals(ctx context.Context, txs []*types.Transaction) []error { 1016 return pool.addTxs(ctx, txs, !pool.config.NoLocals) 1017 } 1018 1019 // AddRemotes enqueues a batch of transactions into the pool if they are valid. 1020 // If the senders are not among the locally tracked ones, full pricing constraints 1021 // will apply. 1022 func (pool *TxPool) AddRemotes(ctx context.Context, txs []*types.Transaction) []error { 1023 return pool.addTxs(ctx, txs, false) 1024 } 1025 1026 // addTx enqueues a single transaction into the pool if it is valid. 1027 func (pool *TxPool) addTx(ctx context.Context, tx *types.Transaction, local bool) error { 1028 ctx, span := trace.StartSpan(ctx, "TxPool.addTx") 1029 defer span.End() 1030 1031 // Check if the transaction is already known, before locking the whole pool. 1032 if pool.all.Get(tx.Hash()) != nil { 1033 return fmt.Errorf("known tx: %x", tx.Hash()) 1034 } 1035 // If the transaction fails basic validation, discard it. 1036 if err := pool.preValidateTx(ctx, tx, local); err != nil { 1037 if log.Tracing() { 1038 log.Trace("Discarding invalid transaction", "hash", tx.Hash(), "err", err) 1039 } 1040 invalidTxCounter.Inc(1) 1041 span.SetStatus(trace.Status{ 1042 Code: trace.StatusCodeFailedPrecondition, 1043 Message: err.Error(), 1044 }) 1045 return err 1046 } 1047 1048 pool.mu.Lock() 1049 defer pool.mu.Unlock() 1050 1051 // Try to inject the transaction and update any state 1052 replace, err := pool.add(ctx, tx, local) 1053 if err != nil { 1054 return err 1055 } 1056 // If we added a new transaction, run promotion checks and return 1057 if !replace { 1058 from, _ := types.Sender(pool.signer, tx) // already validated 1059 pool.promoteExecutables(ctx, from) 1060 } 1061 return nil 1062 } 1063 1064 // addTxs attempts to queue a batch of transactions if they are valid. 1065 func (pool *TxPool) addTxs(ctx context.Context, txs []*types.Transaction, local bool) []error { 1066 ctx, span := trace.StartSpan(ctx, "TxPool.addTxs") 1067 defer span.End() 1068 1069 var add []*types.Transaction 1070 // Filter out known, and pre-compute/cache signer before locking. 1071 for _, tx := range txs { 1072 // If the transaction is already known, discard it. 1073 if pool.all.Get(tx.Hash()) != nil { 1074 continue 1075 } 1076 // If the transaction fails basic validation, discard it. 1077 if err := pool.preValidateTx(ctx, tx, local); err != nil { 1078 if log.Tracing() { 1079 log.Trace("Discarding invalid transaction", "hash", tx.Hash(), "err", err) 1080 } 1081 invalidTxCounter.Inc(1) 1082 continue 1083 } 1084 add = append(add, tx) 1085 } 1086 if len(add) == 0 { 1087 return nil 1088 } 1089 1090 pool.mu.Lock() 1091 defer pool.mu.Unlock() 1092 1093 return pool.addTxsLocked(ctx, add, local) 1094 } 1095 1096 // addTxsLocked attempts to queue a batch of transactions if they are valid, 1097 // whilst assuming the transaction pool lock is already held. 1098 func (pool *TxPool) addTxsLocked(ctx context.Context, txs []*types.Transaction, local bool) []error { 1099 ctx, span := trace.StartSpan(ctx, "TxPool.addTxsLocked") 1100 defer span.End() 1101 1102 // Add the batch of transaction, tracking the accepted ones 1103 dirty := make(map[common.Address]struct{}) 1104 var errs []error 1105 1106 for _, tx := range txs { 1107 replace, err := pool.add(ctx, tx, local) 1108 if err != nil { 1109 errs = append(errs, err) 1110 continue 1111 } 1112 if !replace { 1113 from, _ := types.Sender(pool.signer, tx) // already validated 1114 dirty[from] = struct{}{} 1115 } 1116 } 1117 // Only reprocess the internal state if something was actually added 1118 if len(dirty) > 0 { 1119 addrs := make([]common.Address, 0, len(dirty)) 1120 for addr := range dirty { 1121 addrs = append(addrs, addr) 1122 } 1123 pool.promoteExecutables(ctx, addrs...) 1124 } 1125 return errs 1126 } 1127 1128 // reinject is like addTxsLocked but with a map and local false. 1129 func (pool *TxPool) reinject(ctx context.Context, txs map[common.Hash]*types.Transaction) []error { 1130 ctx, span := trace.StartSpan(ctx, "TxPool.reinject") 1131 defer span.End() 1132 1133 // Add the batch of transaction, tracking the accepted ones 1134 dirty := make(map[common.Address]struct{}) 1135 var errs []error 1136 1137 for _, tx := range txs { 1138 replace, err := pool.add(ctx, tx, false) 1139 if err != nil { 1140 errs = append(errs, err) 1141 continue 1142 } 1143 if !replace { 1144 from, _ := types.Sender(pool.signer, tx) // already validated 1145 dirty[from] = struct{}{} 1146 } 1147 } 1148 // Only reprocess the internal state if something was actually added 1149 if len(dirty) > 0 { 1150 addrs := make([]common.Address, 0, len(dirty)) 1151 for addr := range dirty { 1152 addrs = append(addrs, addr) 1153 } 1154 pool.promoteExecutables(ctx, addrs...) 1155 } 1156 return errs 1157 } 1158 1159 // Status returns the status (unknown/pending/queued) of a batch of transactions 1160 // identified by their hashes. 1161 func (pool *TxPool) Status(ctx context.Context, hashes []common.Hash) []TxStatus { 1162 ctx, span := trace.StartSpan(ctx, "TxPool.Status") 1163 defer span.End() 1164 1165 pool.mu.RLock() 1166 defer pool.mu.RUnlock() 1167 1168 status := make([]TxStatus, len(hashes)) 1169 for i, hash := range hashes { 1170 if tx := pool.all.Get(hash); tx != nil { 1171 from, _ := types.Sender(pool.signer, tx) // already validated 1172 if pool.pending[from] != nil && pool.pending[from].txs.items[tx.Nonce()] != nil { 1173 status[i] = TxStatusPending 1174 } else { 1175 status[i] = TxStatusQueued 1176 } 1177 } 1178 } 1179 return status 1180 } 1181 1182 // Get returns a transaction if it is contained in the pool 1183 // and nil otherwise. 1184 func (pool *TxPool) Get(hash common.Hash) *types.Transaction { 1185 return pool.all.Get(hash) 1186 } 1187 1188 // removeTx removes a single transaction from pending or queue, moving all subsequent 1189 // transactions back to the future queue. 1190 // The caller must hold pool.mu and pool.all.mu. 1191 func (pool *TxPool) removeTx(ctx context.Context, tx *types.Transaction) { 1192 ctx, span := trace.StartSpan(ctx, "TxPool.removeTx") 1193 defer span.End() 1194 1195 delete(pool.all.all, tx.Hash()) 1196 1197 addr, _ := types.Sender(pool.signer, tx) // already validated during insertion 1198 1199 // Remove the transaction from the pending lists and reset the account nonce. 1200 if pending := pool.pending[addr]; pending != nil { 1201 queue := pool.queue[addr] 1202 if queue == nil { 1203 // Create a new queue for any invalidated pending txs. Will be discarded before returning if unused. 1204 queue = newTxList(false) 1205 pool.queue[addr] = queue 1206 } 1207 // Remove from pending, and demote any invalidated to the queue. 1208 if pending.Remove(tx, queue.add) { 1209 // If no more transactions are left, remove the list. 1210 if pending.Empty() { 1211 delete(pool.pending, addr) 1212 delete(pool.beats, addr) 1213 } 1214 // If we created a new queue, but no txs were invalidated, then remove it. 1215 if queue.Empty() { 1216 delete(pool.queue, addr) 1217 } 1218 // Update the account nonce, if necessary. 1219 stNonce := pool.pendingState.GetNonce(addr) 1220 if nonce := tx.Nonce(); stNonce > nonce { 1221 pool.pendingState.SetNonce(addr, nonce) 1222 } 1223 return 1224 } 1225 } 1226 // Transaction is in the future queue. 1227 if queue := pool.queue[addr]; queue != nil { 1228 _ = queue.Remove(tx, func(tx *types.Transaction) {}) 1229 if queue.Empty() { 1230 delete(pool.queue, addr) 1231 } 1232 } 1233 } 1234 1235 // promoteExecutablesAll is like promoteExecutables, but for the entire queue. 1236 func (pool *TxPool) promoteExecutablesAll(ctx context.Context) { 1237 ctx, span := trace.StartSpan(ctx, "TxPool.promoteExecutablesAll") 1238 defer span.End() 1239 1240 for addr, queued := range pool.queue { 1241 pool.promoteExecutable(ctx, addr, queued) 1242 } 1243 pool.finishPromotion(ctx) 1244 } 1245 1246 // promoteExecutables moves transactions that have become processable from the 1247 // future queue to the set of pending transactions. During this process, all 1248 // invalidated transactions (low nonce, low balance) are deleted. 1249 func (pool *TxPool) promoteExecutables(ctx context.Context, accounts ...common.Address) { 1250 ctx, span := trace.StartSpan(ctx, "TxPool.promoteExecutables") 1251 defer span.End() 1252 1253 for _, addr := range accounts { 1254 queued := pool.queue[addr] 1255 if queued == nil { 1256 continue // Just in case someone calls with a non existing account 1257 } 1258 pool.promoteExecutable(ctx, addr, queued) 1259 } 1260 pool.finishPromotion(ctx) 1261 } 1262 1263 func (pool *TxPool) promoteExecutable(ctx context.Context, addr common.Address, queued *txList) { 1264 ctx, span := trace.StartSpan(ctx, "TxPool.promoteExecutable") 1265 defer span.End() 1266 1267 tracing := log.Tracing() 1268 // Drop all transactions that are deemed too old (low nonce) 1269 remove := func(tx *types.Transaction) { 1270 pool.all.Remove(tx.Hash()) 1271 } 1272 if tracing { 1273 remove = func(tx *types.Transaction) { 1274 hash := tx.Hash() 1275 pool.all.Remove(hash) 1276 log.Trace("Removed old queued transaction", "hash", hash) 1277 } 1278 } 1279 queued.Forward(pool.currentState.GetNonce(addr), remove) 1280 1281 // Drop all transactions that are too costly (low balance or out of gas) 1282 remove = func(tx *types.Transaction) { 1283 pool.all.Remove(tx.Hash()) 1284 queuedNofundsCounter.Inc(1) 1285 } 1286 if tracing { 1287 remove = func(tx *types.Transaction) { 1288 hash := tx.Hash() 1289 pool.all.Remove(hash) 1290 queuedNofundsCounter.Inc(1) 1291 log.Trace("Removed unpayable queued transaction", "hash", hash) 1292 } 1293 } 1294 queued.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas, remove, func(*types.Transaction) {}) 1295 1296 // Gather all executable transactions and promote them 1297 promote := func(tx *types.Transaction) { 1298 if pool.promoteTx(ctx, addr, tx.Hash(), tx) { 1299 pool.queueFeedSend(tx) 1300 } 1301 } 1302 if tracing { 1303 promote = func(tx *types.Transaction) { 1304 hash := tx.Hash() 1305 if pool.promoteTx(ctx, addr, hash, tx) { 1306 log.Trace("Promoting queued transaction", "hash", hash) 1307 pool.queueFeedSend(tx) 1308 } else { 1309 log.Trace("Removed old queued transaction", "hash", hash) 1310 } 1311 } 1312 } 1313 queued.Ready(pool.pendingState.GetNonce(addr), promote) 1314 1315 // Drop all transactions over the allowed limit 1316 if !pool.locals.contains(addr) { 1317 remove := func(tx *types.Transaction) { 1318 pool.all.Remove(tx.Hash()) 1319 queuedRateLimitCounter.Inc(1) 1320 } 1321 if tracing { 1322 remove = func(tx *types.Transaction) { 1323 hash := tx.Hash() 1324 pool.all.Remove(hash) 1325 queuedRateLimitCounter.Inc(1) 1326 log.Trace("Removed cap-exceeding queued transaction", "hash", hash) 1327 } 1328 } 1329 queued.Cap(int(pool.config.AccountQueue), remove) 1330 } 1331 1332 // Delete the entire queued entry if it became empty. 1333 if queued.Empty() { 1334 delete(pool.queue, addr) 1335 } 1336 } 1337 1338 func (pool *TxPool) finishPromotion(ctx context.Context) { 1339 ctx, span := trace.StartSpan(ctx, "TxPool.finishPromotion") 1340 defer span.End() 1341 1342 // If the pending limit is overflown, start equalizing allowances 1343 pending := uint64(0) 1344 for _, list := range pool.pending { 1345 pending += uint64(list.Len()) 1346 } 1347 if pending > pool.config.GlobalSlots { 1348 pendingBeforeCap := pending 1349 // Assemble a spam order to penalize large transactors first 1350 spammers := prque.New(nil) 1351 for addr, list := range pool.pending { 1352 // Only evict transactions from high rollers 1353 if !pool.locals.contains(addr) && uint64(list.Len()) > pool.config.AccountSlots { 1354 spammers.Push(addr, int64(list.Len())) 1355 } 1356 } 1357 tracing := log.Tracing() 1358 // Gradually drop transactions from offenders 1359 offenders := []common.Address{} 1360 for pending > pool.config.GlobalSlots && !spammers.Empty() { 1361 // Retrieve the next offender if not local address 1362 offender, _ := spammers.Pop() 1363 offenders = append(offenders, offender.(common.Address)) 1364 1365 // Equalize balances until all the same or below threshold 1366 if len(offenders) > 1 { 1367 // Calculate the equalization threshold for all current offenders 1368 threshold := pool.pending[offender.(common.Address)].Len() 1369 1370 // Iteratively reduce all offenders until below limit or threshold reached 1371 for pending > pool.config.GlobalSlots && pool.pending[offenders[len(offenders)-2]].Len() > threshold { 1372 pending -= pool.limitOffenders(offenders, tracing) 1373 } 1374 } 1375 } 1376 // If still above threshold, reduce to limit or min allowance 1377 if pending > pool.config.GlobalSlots && len(offenders) > 0 { 1378 for pending > pool.config.GlobalSlots && uint64(pool.pending[offenders[len(offenders)-1]].Len()) > pool.config.AccountSlots { 1379 pending -= pool.limitOffenders(offenders, tracing) 1380 } 1381 } 1382 pendingRateLimitCounter.Inc(int64(pendingBeforeCap - pending)) 1383 } 1384 // If we've queued more transactions than the hard limit, drop oldest ones 1385 queued := uint64(0) 1386 for _, list := range pool.queue { 1387 queued += uint64(list.Len()) 1388 } 1389 if queued > pool.config.GlobalQueue { 1390 // Sort all accounts with queued transactions by heartbeat 1391 addresses := make(addresssByHeartbeat, 0, len(pool.queue)) 1392 for addr := range pool.queue { 1393 if !pool.locals.contains(addr) { // don't drop locals 1394 addresses = append(addresses, addressByHeartbeat{addr, pool.beats[addr]}) 1395 } 1396 } 1397 sort.Sort(addresses) 1398 1399 // Drop transactions until the total is below the limit or only locals remain 1400 for drop := queued - pool.config.GlobalQueue; drop > 0 && len(addresses) > 0; { 1401 addr := addresses[len(addresses)-1] 1402 list := pool.queue[addr.address] 1403 1404 addresses = addresses[:len(addresses)-1] 1405 1406 // Drop all transactions if they are less than the overflow 1407 if size := uint64(list.Len()); size <= drop { 1408 for _, tx := range list.txs.items { 1409 pool.all.Remove(tx.Hash()) 1410 } 1411 delete(pool.queue, addr.address) 1412 drop -= size 1413 queuedRateLimitCounter.Inc(int64(size)) 1414 continue 1415 } 1416 // Otherwise drop only last few transactions 1417 list.ForLast(int(drop), func(tx *types.Transaction) { 1418 pool.all.Remove(tx.Hash()) 1419 drop-- 1420 queuedRateLimitCounter.Inc(1) 1421 }) 1422 } 1423 } 1424 } 1425 1426 func (pool *TxPool) limitOffenders(offenders []common.Address, tracing bool) (removed uint64) { 1427 var nonce uint64 1428 remove := func(tx *types.Transaction) { 1429 pool.all.Remove(tx.Hash()) 1430 if tx.Nonce() < nonce { 1431 nonce = tx.Nonce() 1432 } 1433 } 1434 if tracing { 1435 remove = func(tx *types.Transaction) { 1436 hash := tx.Hash() 1437 pool.all.Remove(hash) 1438 if tx.Nonce() < nonce { 1439 nonce = tx.Nonce() 1440 } 1441 log.Trace("Removed fairness-exceeding pending transaction", "hash", hash) 1442 } 1443 } 1444 for _, addr := range offenders { 1445 removed++ 1446 pending := pool.pending[addr] 1447 nonce = math.MaxUint64 1448 pending.Cap(pending.Len()-1, remove) 1449 // Update the account nonce to the dropped transaction 1450 stNonce := pool.pendingState.GetNonce(addr) 1451 if stNonce > nonce { 1452 pool.pendingState.SetNonce(addr, nonce) 1453 } 1454 } 1455 return 1456 } 1457 1458 // demoteUnexecutables removes invalid and processed transactions from the pools 1459 // executable/pending queue and any subsequent transactions that become unexecutable 1460 // are moved back into the future queue. 1461 func (pool *TxPool) demoteUnexecutables(ctx context.Context) { 1462 ctx, span := trace.StartSpan(ctx, "TxPool.demoteUnexecutables") 1463 defer span.End() 1464 1465 // Iterate over all accounts and demote any non-executable transactions 1466 for addr, pending := range pool.pending { 1467 nonce := pool.currentState.GetNonce(addr) 1468 1469 // Drop all transactions that are deemed too old (low nonce) 1470 tracing := log.Tracing() 1471 remove := func(tx *types.Transaction) { 1472 pool.all.Remove(tx.Hash()) 1473 } 1474 if tracing { 1475 remove = func(tx *types.Transaction) { 1476 hash := tx.Hash() 1477 pool.all.Remove(hash) 1478 log.Trace("Removed old pending transaction", "hash", hash) 1479 } 1480 } 1481 pending.Forward(nonce, remove) 1482 1483 // Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later 1484 bal := pool.currentState.GetBalance(addr) 1485 remove = func(tx *types.Transaction) { 1486 pool.all.Remove(tx.Hash()) 1487 pendingNofundsCounter.Inc(1) 1488 } 1489 queue := pool.queue[addr] 1490 if queue == nil { 1491 queue = newTxList(false) 1492 pool.queue[addr] = queue 1493 } 1494 invalid := queue.add 1495 if tracing { 1496 remove = func(tx *types.Transaction) { 1497 hash := tx.Hash() 1498 pool.all.Remove(hash) 1499 pendingNofundsCounter.Inc(1) 1500 log.Trace("Removed unpayable pending transaction", "hash", hash) 1501 } 1502 invalid = func(tx *types.Transaction) { 1503 log.Trace("Demoting pending transaction", "hash", tx.Hash()) 1504 queue.add(tx) 1505 } 1506 } 1507 pending.Filter(bal, pool.currentMaxGas, remove, invalid) 1508 1509 // If there's a gap in front, warn (should never happen) and postpone all transactions 1510 if pending.Len() > 0 && pending.txs.Get(nonce) == nil { 1511 for _, tx := range pending.txs.items { 1512 log.Trace("Demoting invalidated transaction", "hash", tx.Hash()) 1513 queue.add(tx) 1514 } 1515 delete(pool.pending, addr) 1516 delete(pool.beats, addr) 1517 continue 1518 } 1519 if pending.Empty() { 1520 delete(pool.pending, addr) 1521 delete(pool.beats, addr) 1522 } 1523 if queue.Empty() { 1524 delete(pool.queue, addr) 1525 } 1526 } 1527 } 1528 1529 // addressByHeartbeat is an account address tagged with its last activity timestamp. 1530 type addressByHeartbeat struct { 1531 address common.Address 1532 heartbeat time.Time 1533 } 1534 1535 type addresssByHeartbeat []addressByHeartbeat 1536 1537 func (a addresssByHeartbeat) Len() int { return len(a) } 1538 func (a addresssByHeartbeat) Less(i, j int) bool { return a[i].heartbeat.Before(a[j].heartbeat) } 1539 func (a addresssByHeartbeat) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 1540 1541 // accountSet is simply a set of addresses to check for existence, and a signer 1542 // capable of deriving addresses from transactions. 1543 type accountSet struct { 1544 accounts map[common.Address]struct{} 1545 signer types.Signer 1546 cache *[]common.Address 1547 } 1548 1549 // newAccountSet creates a new address set with an associated signer for sender 1550 // derivations. 1551 func newAccountSet(signer types.Signer) *accountSet { 1552 return &accountSet{ 1553 accounts: make(map[common.Address]struct{}), 1554 signer: signer, 1555 } 1556 } 1557 1558 // contains checks if a given address is contained within the set. 1559 func (as *accountSet) contains(addr common.Address) bool { 1560 _, exist := as.accounts[addr] 1561 return exist 1562 } 1563 1564 // containsTx checks if the sender of a given tx is within the set. If the sender 1565 // cannot be derived, this method returns false. 1566 func (as *accountSet) containsTx(ctx context.Context, tx *types.Transaction) bool { 1567 if addr, err := types.Sender(as.signer, tx); err == nil { 1568 return as.contains(addr) 1569 } 1570 return false 1571 } 1572 1573 // add inserts a new address into the set to track. 1574 func (as *accountSet) add(addr common.Address) { 1575 as.accounts[addr] = struct{}{} 1576 as.cache = nil 1577 } 1578 1579 // flatten returns the list of addresses within this set, also caching it for later 1580 // reuse. The returned slice should not be changed! 1581 func (as *accountSet) flatten() []common.Address { 1582 if as.cache == nil { 1583 accounts := make([]common.Address, 0, len(as.accounts)) 1584 for account := range as.accounts { 1585 accounts = append(accounts, account) 1586 } 1587 as.cache = &accounts 1588 } 1589 return *as.cache 1590 } 1591 1592 // txLookup is used internally by TxPool to track transactions while allowing lookup without 1593 // mutex contention. 1594 // 1595 // Note, although this type is properly protected against concurrent access, it 1596 // is **not** a type that should ever be mutated or even exposed outside of the 1597 // transaction pool, since its internal state is tightly coupled with the pools 1598 // internal mechanisms. The sole purpose of the type is to permit out-of-bound 1599 // peeking into the pool in TxPool.Get without having to acquire the widely scoped 1600 // TxPool.mu mutex. 1601 type txLookup struct { 1602 all map[common.Hash]*types.Transaction 1603 mu sync.RWMutex 1604 } 1605 1606 // newTxLookup returns a new txLookup structure. 1607 func newTxLookup(cap int) *txLookup { 1608 return &txLookup{ 1609 all: make(map[common.Hash]*types.Transaction, cap), 1610 } 1611 } 1612 1613 // ForEach calls f for each tx, while holding the write lock. 1614 func (t *txLookup) ForEach(f func(tx *types.Transaction)) { 1615 t.mu.Lock() 1616 defer t.mu.Unlock() 1617 1618 for _, value := range t.all { 1619 f(value) 1620 } 1621 } 1622 1623 // Get returns a transaction if it exists in the lookup, or nil if not found. 1624 func (t *txLookup) Get(hash common.Hash) *types.Transaction { 1625 t.mu.RLock() 1626 tx := t.all[hash] 1627 t.mu.RUnlock() 1628 return tx 1629 } 1630 1631 // Count returns the current number of items in the lookup. 1632 func (t *txLookup) Count() int { 1633 t.mu.RLock() 1634 l := len(t.all) 1635 t.mu.RUnlock() 1636 return l 1637 } 1638 1639 // Add adds a transaction to the lookup. 1640 func (t *txLookup) Add(tx *types.Transaction) { 1641 t.mu.Lock() 1642 t.all[tx.Hash()] = tx 1643 t.mu.Unlock() 1644 } 1645 1646 // Remove removes a transaction from the lookup. 1647 func (t *txLookup) Remove(hash common.Hash) { 1648 t.mu.Lock() 1649 delete(t.all, hash) 1650 t.mu.Unlock() 1651 }