github.com/arjunbeliever/ignite@v0.0.0-20220406110515-46bbbbec2587/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 "errors" 21 "math" 22 "math/big" 23 "sort" 24 "sync" 25 "time" 26 27 "github.com/arjunbeliever/ignite/common" 28 "github.com/arjunbeliever/ignite/common/prque" 29 "github.com/arjunbeliever/ignite/consensus/misc" 30 "github.com/arjunbeliever/ignite/core/state" 31 "github.com/arjunbeliever/ignite/core/types" 32 "github.com/arjunbeliever/ignite/event" 33 "github.com/arjunbeliever/ignite/log" 34 "github.com/arjunbeliever/ignite/metrics" 35 "github.com/arjunbeliever/ignite/params" 36 ) 37 38 const ( 39 // chainHeadChanSize is the size of channel listening to ChainHeadEvent. 40 chainHeadChanSize = 10 41 42 // txSlotSize is used to calculate how many data slots a single transaction 43 // takes up based on its size. The slots are used as DoS protection, ensuring 44 // that validating a new transaction remains a constant operation (in reality 45 // O(maxslots), where max slots are 4 currently). 46 txSlotSize = 32 * 1024 47 48 // txMaxSize is the maximum size a single transaction can have. This field has 49 // non-trivial consequences: larger transactions are significantly harder and 50 // more expensive to propagate; larger transactions also take more resources 51 // to validate whether they fit into the pool or not. 52 txMaxSize = 4 * txSlotSize // 128KB 53 ) 54 55 var ( 56 // ErrAlreadyKnown is returned if the transactions is already contained 57 // within the pool. 58 ErrAlreadyKnown = errors.New("already known") 59 60 // ErrInvalidSender is returned if the transaction contains an invalid signature. 61 ErrInvalidSender = errors.New("invalid sender") 62 63 // ErrUnderpriced is returned if a transaction's gas price is below the minimum 64 // configured for the transaction pool. 65 ErrUnderpriced = errors.New("transaction underpriced") 66 67 // ErrTxPoolOverflow is returned if the transaction pool is full and can't accpet 68 // another remote transaction. 69 ErrTxPoolOverflow = errors.New("txpool is full") 70 71 // ErrReplaceUnderpriced is returned if a transaction is attempted to be replaced 72 // with a different one without the required price bump. 73 ErrReplaceUnderpriced = errors.New("replacement transaction underpriced") 74 75 // ErrGasLimit is returned if a transaction's requested gas limit exceeds the 76 // maximum allowance of the current block. 77 ErrGasLimit = errors.New("exceeds block gas limit") 78 79 // ErrNegativeValue is a sanity error to ensure no one is able to specify a 80 // transaction with a negative value. 81 ErrNegativeValue = errors.New("negative value") 82 83 // ErrOversizedData is returned if the input data of a transaction is greater 84 // than some meaningful limit a user might use. This is not a consensus error 85 // making the transaction invalid, rather a DOS protection. 86 ErrOversizedData = errors.New("oversized data") 87 ) 88 89 var ( 90 evictionInterval = time.Minute // Time interval to check for evictable transactions 91 statsReportInterval = 8 * time.Second // Time interval to report transaction pool stats 92 ) 93 94 var ( 95 // Metrics for the pending pool 96 pendingDiscardMeter = metrics.NewRegisteredMeter("txpool/pending/discard", nil) 97 pendingReplaceMeter = metrics.NewRegisteredMeter("txpool/pending/replace", nil) 98 pendingRateLimitMeter = metrics.NewRegisteredMeter("txpool/pending/ratelimit", nil) // Dropped due to rate limiting 99 pendingNofundsMeter = metrics.NewRegisteredMeter("txpool/pending/nofunds", nil) // Dropped due to out-of-funds 100 101 // Metrics for the queued pool 102 queuedDiscardMeter = metrics.NewRegisteredMeter("txpool/queued/discard", nil) 103 queuedReplaceMeter = metrics.NewRegisteredMeter("txpool/queued/replace", nil) 104 queuedRateLimitMeter = metrics.NewRegisteredMeter("txpool/queued/ratelimit", nil) // Dropped due to rate limiting 105 queuedNofundsMeter = metrics.NewRegisteredMeter("txpool/queued/nofunds", nil) // Dropped due to out-of-funds 106 queuedEvictionMeter = metrics.NewRegisteredMeter("txpool/queued/eviction", nil) // Dropped due to lifetime 107 108 // General tx metrics 109 knownTxMeter = metrics.NewRegisteredMeter("txpool/known", nil) 110 validTxMeter = metrics.NewRegisteredMeter("txpool/valid", nil) 111 invalidTxMeter = metrics.NewRegisteredMeter("txpool/invalid", nil) 112 underpricedTxMeter = metrics.NewRegisteredMeter("txpool/underpriced", nil) 113 overflowedTxMeter = metrics.NewRegisteredMeter("txpool/overflowed", nil) 114 115 pendingGauge = metrics.NewRegisteredGauge("txpool/pending", nil) 116 queuedGauge = metrics.NewRegisteredGauge("txpool/queued", nil) 117 localGauge = metrics.NewRegisteredGauge("txpool/local", nil) 118 slotsGauge = metrics.NewRegisteredGauge("txpool/slots", nil) 119 120 reheapTimer = metrics.NewRegisteredTimer("txpool/reheap", nil) 121 ) 122 123 // TxStatus is the current status of a transaction as seen by the pool. 124 type TxStatus uint 125 126 const ( 127 TxStatusUnknown TxStatus = iota 128 TxStatusQueued 129 TxStatusPending 130 TxStatusIncluded 131 ) 132 133 // blockChain provides the state of blockchain and current gas limit to do 134 // some pre checks in tx pool and event subscribers. 135 type blockChain interface { 136 CurrentBlock() *types.Block 137 GetBlock(hash common.Hash, number uint64) *types.Block 138 StateAt(root common.Hash) (*state.StateDB, error) 139 140 SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription 141 } 142 143 // TxPoolConfig are the configuration parameters of the transaction pool. 144 type TxPoolConfig struct { 145 Locals []common.Address // Addresses that should be treated by default as local 146 NoLocals bool // Whether local transaction handling should be disabled 147 Journal string // Journal of local transactions to survive node restarts 148 Rejournal time.Duration // Time interval to regenerate the local transaction journal 149 150 PriceLimit uint64 // Minimum gas price to enforce for acceptance into the pool 151 PriceBump uint64 // Minimum price bump percentage to replace an already existing transaction (nonce) 152 153 AccountSlots uint64 // Number of executable transaction slots guaranteed per account 154 GlobalSlots uint64 // Maximum number of executable transaction slots for all accounts 155 AccountQueue uint64 // Maximum number of non-executable transaction slots permitted per account 156 GlobalQueue uint64 // Maximum number of non-executable transaction slots for all accounts 157 158 Lifetime time.Duration // Maximum amount of time non-executable transaction are queued 159 } 160 161 // DefaultTxPoolConfig contains the default configurations for the transaction 162 // pool. 163 var DefaultTxPoolConfig = TxPoolConfig{ 164 Journal: "transactions.rlp", 165 Rejournal: time.Hour, 166 167 PriceLimit: 1, 168 PriceBump: 10, 169 170 AccountSlots: 16, 171 GlobalSlots: 4096 + 1024, // urgent + floating queue capacity with 4:1 ratio 172 AccountQueue: 64, 173 GlobalQueue: 1024, 174 175 Lifetime: 3 * time.Hour, 176 } 177 178 // sanitize checks the provided user configurations and changes anything that's 179 // unreasonable or unworkable. 180 func (config *TxPoolConfig) sanitize() TxPoolConfig { 181 conf := *config 182 if conf.Rejournal < time.Second { 183 log.Warn("Sanitizing invalid txpool journal time", "provided", conf.Rejournal, "updated", time.Second) 184 conf.Rejournal = time.Second 185 } 186 if conf.PriceLimit < 1 { 187 log.Warn("Sanitizing invalid txpool price limit", "provided", conf.PriceLimit, "updated", DefaultTxPoolConfig.PriceLimit) 188 conf.PriceLimit = DefaultTxPoolConfig.PriceLimit 189 } 190 if conf.PriceBump < 1 { 191 log.Warn("Sanitizing invalid txpool price bump", "provided", conf.PriceBump, "updated", DefaultTxPoolConfig.PriceBump) 192 conf.PriceBump = DefaultTxPoolConfig.PriceBump 193 } 194 if conf.AccountSlots < 1 { 195 log.Warn("Sanitizing invalid txpool account slots", "provided", conf.AccountSlots, "updated", DefaultTxPoolConfig.AccountSlots) 196 conf.AccountSlots = DefaultTxPoolConfig.AccountSlots 197 } 198 if conf.GlobalSlots < 1 { 199 log.Warn("Sanitizing invalid txpool global slots", "provided", conf.GlobalSlots, "updated", DefaultTxPoolConfig.GlobalSlots) 200 conf.GlobalSlots = DefaultTxPoolConfig.GlobalSlots 201 } 202 if conf.AccountQueue < 1 { 203 log.Warn("Sanitizing invalid txpool account queue", "provided", conf.AccountQueue, "updated", DefaultTxPoolConfig.AccountQueue) 204 conf.AccountQueue = DefaultTxPoolConfig.AccountQueue 205 } 206 if conf.GlobalQueue < 1 { 207 log.Warn("Sanitizing invalid txpool global queue", "provided", conf.GlobalQueue, "updated", DefaultTxPoolConfig.GlobalQueue) 208 conf.GlobalQueue = DefaultTxPoolConfig.GlobalQueue 209 } 210 if conf.Lifetime < 1 { 211 log.Warn("Sanitizing invalid txpool lifetime", "provided", conf.Lifetime, "updated", DefaultTxPoolConfig.Lifetime) 212 conf.Lifetime = DefaultTxPoolConfig.Lifetime 213 } 214 return conf 215 } 216 217 // TxPool contains all currently known transactions. Transactions 218 // enter the pool when they are received from the network or submitted 219 // locally. They exit the pool when they are included in the blockchain. 220 // 221 // The pool separates processable transactions (which can be applied to the 222 // current state) and future transactions. Transactions move between those 223 // two states over time as they are received and processed. 224 type TxPool struct { 225 config TxPoolConfig 226 chainconfig *params.ChainConfig 227 chain blockChain 228 gasPrice *big.Int 229 txFeed event.Feed 230 scope event.SubscriptionScope 231 signer types.Signer 232 mu sync.RWMutex 233 234 istanbul bool // Fork indicator whether we are in the istanbul stage. 235 eip2718 bool // Fork indicator whether we are using EIP-2718 type transactions. 236 eip1559 bool // Fork indicator whether we are using EIP-1559 type transactions. 237 238 currentState *state.StateDB // Current state in the blockchain head 239 pendingNonces *txNoncer // Pending state tracking virtual nonces 240 currentMaxGas uint64 // Current gas limit for transaction caps 241 242 locals *accountSet // Set of local transaction to exempt from eviction rules 243 journal *txJournal // Journal of local transaction to back up to disk 244 245 pending map[common.Address]*txList // All currently processable transactions 246 queue map[common.Address]*txList // Queued but non-processable transactions 247 beats map[common.Address]time.Time // Last heartbeat from each known account 248 all *txLookup // All transactions to allow lookups 249 priced *txPricedList // All transactions sorted by price 250 251 chainHeadCh chan ChainHeadEvent 252 chainHeadSub event.Subscription 253 reqResetCh chan *txpoolResetRequest 254 reqPromoteCh chan *accountSet 255 queueTxEventCh chan *types.Transaction 256 reorgDoneCh chan chan struct{} 257 reorgShutdownCh chan struct{} // requests shutdown of scheduleReorgLoop 258 wg sync.WaitGroup // tracks loop, scheduleReorgLoop 259 } 260 261 type txpoolResetRequest struct { 262 oldHead, newHead *types.Header 263 } 264 265 // NewTxPool creates a new transaction pool to gather, sort and filter inbound 266 // transactions from the network. 267 func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain) *TxPool { 268 // Sanitize the input to ensure no vulnerable gas prices are set 269 config = (&config).sanitize() 270 271 // Create the transaction pool with its initial settings 272 pool := &TxPool{ 273 config: config, 274 chainconfig: chainconfig, 275 chain: chain, 276 signer: types.LatestSigner(chainconfig), 277 pending: make(map[common.Address]*txList), 278 queue: make(map[common.Address]*txList), 279 beats: make(map[common.Address]time.Time), 280 all: newTxLookup(), 281 chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize), 282 reqResetCh: make(chan *txpoolResetRequest), 283 reqPromoteCh: make(chan *accountSet), 284 queueTxEventCh: make(chan *types.Transaction), 285 reorgDoneCh: make(chan chan struct{}), 286 reorgShutdownCh: make(chan struct{}), 287 gasPrice: new(big.Int).SetUint64(config.PriceLimit), 288 } 289 pool.locals = newAccountSet(pool.signer) 290 for _, addr := range config.Locals { 291 log.Info("Setting new local account", "address", addr) 292 pool.locals.add(addr) 293 } 294 pool.priced = newTxPricedList(pool.all) 295 pool.reset(nil, chain.CurrentBlock().Header()) 296 297 // Start the reorg loop early so it can handle requests generated during journal loading. 298 pool.wg.Add(1) 299 go pool.scheduleReorgLoop() 300 301 // If local transactions and journaling is enabled, load from disk 302 if !config.NoLocals && config.Journal != "" { 303 pool.journal = newTxJournal(config.Journal) 304 305 if err := pool.journal.load(pool.AddLocals); err != nil { 306 log.Warn("Failed to load transaction journal", "err", err) 307 } 308 if err := pool.journal.rotate(pool.local()); err != nil { 309 log.Warn("Failed to rotate transaction journal", "err", err) 310 } 311 } 312 313 // Subscribe events from blockchain and start the main event loop. 314 pool.chainHeadSub = pool.chain.SubscribeChainHeadEvent(pool.chainHeadCh) 315 pool.wg.Add(1) 316 go pool.loop() 317 318 return pool 319 } 320 321 // loop is the transaction pool's main event loop, waiting for and reacting to 322 // outside blockchain events as well as for various reporting and transaction 323 // eviction events. 324 func (pool *TxPool) loop() { 325 defer pool.wg.Done() 326 327 var ( 328 prevPending, prevQueued, prevStales int 329 // Start the stats reporting and transaction eviction tickers 330 report = time.NewTicker(statsReportInterval) 331 evict = time.NewTicker(evictionInterval) 332 journal = time.NewTicker(pool.config.Rejournal) 333 // Track the previous head headers for transaction reorgs 334 head = pool.chain.CurrentBlock() 335 ) 336 defer report.Stop() 337 defer evict.Stop() 338 defer journal.Stop() 339 340 for { 341 select { 342 // Handle ChainHeadEvent 343 case ev := <-pool.chainHeadCh: 344 if ev.Block != nil { 345 pool.requestReset(head.Header(), ev.Block.Header()) 346 head = ev.Block 347 } 348 349 // System shutdown. 350 case <-pool.chainHeadSub.Err(): 351 close(pool.reorgShutdownCh) 352 return 353 354 // Handle stats reporting ticks 355 case <-report.C: 356 pool.mu.RLock() 357 pending, queued := pool.stats() 358 stales := pool.priced.stales 359 pool.mu.RUnlock() 360 361 if pending != prevPending || queued != prevQueued || stales != prevStales { 362 log.Debug("Transaction pool status report", "executable", pending, "queued", queued, "stales", stales) 363 prevPending, prevQueued, prevStales = pending, queued, stales 364 } 365 366 // Handle inactive account transaction eviction 367 case <-evict.C: 368 pool.mu.Lock() 369 for addr := range pool.queue { 370 // Skip local transactions from the eviction mechanism 371 if pool.locals.contains(addr) { 372 continue 373 } 374 // Any non-locals old enough should be removed 375 if time.Since(pool.beats[addr]) > pool.config.Lifetime { 376 list := pool.queue[addr].Flatten() 377 for _, tx := range list { 378 pool.removeTx(tx.Hash(), true) 379 } 380 queuedEvictionMeter.Mark(int64(len(list))) 381 } 382 } 383 pool.mu.Unlock() 384 385 // Handle local transaction journal rotation 386 case <-journal.C: 387 if pool.journal != nil { 388 pool.mu.Lock() 389 if err := pool.journal.rotate(pool.local()); err != nil { 390 log.Warn("Failed to rotate local tx journal", "err", err) 391 } 392 pool.mu.Unlock() 393 } 394 } 395 } 396 } 397 398 // Stop terminates the transaction pool. 399 func (pool *TxPool) Stop() { 400 // Unsubscribe all subscriptions registered from txpool 401 pool.scope.Close() 402 403 // Unsubscribe subscriptions registered from blockchain 404 pool.chainHeadSub.Unsubscribe() 405 pool.wg.Wait() 406 407 if pool.journal != nil { 408 pool.journal.close() 409 } 410 log.Info("Transaction pool stopped") 411 } 412 413 // SubscribeNewTxsEvent registers a subscription of NewTxsEvent and 414 // starts sending event to the given channel. 415 func (pool *TxPool) SubscribeNewTxsEvent(ch chan<- NewTxsEvent) event.Subscription { 416 return pool.scope.Track(pool.txFeed.Subscribe(ch)) 417 } 418 419 // GasPrice returns the current gas price enforced by the transaction pool. 420 func (pool *TxPool) GasPrice() *big.Int { 421 pool.mu.RLock() 422 defer pool.mu.RUnlock() 423 424 return new(big.Int).Set(pool.gasPrice) 425 } 426 427 // SetGasPrice updates the minimum price required by the transaction pool for a 428 // new transaction, and drops all transactions below this threshold. 429 func (pool *TxPool) SetGasPrice(price *big.Int) { 430 pool.mu.Lock() 431 defer pool.mu.Unlock() 432 433 old := pool.gasPrice 434 pool.gasPrice = price 435 // if the min miner fee increased, remove transactions below the new threshold 436 if price.Cmp(old) > 0 { 437 // pool.priced is sorted by GasFeeCap, so we have to iterate through pool.all instead 438 drop := pool.all.RemotesBelowTip(price) 439 for _, tx := range drop { 440 pool.removeTx(tx.Hash(), false) 441 } 442 pool.priced.Removed(len(drop)) 443 } 444 445 log.Info("Transaction pool price threshold updated", "price", price) 446 } 447 448 // Nonce returns the next nonce of an account, with all transactions executable 449 // by the pool already applied on top. 450 func (pool *TxPool) Nonce(addr common.Address) uint64 { 451 pool.mu.RLock() 452 defer pool.mu.RUnlock() 453 454 return pool.pendingNonces.get(addr) 455 } 456 457 // Stats retrieves the current pool stats, namely the number of pending and the 458 // number of queued (non-executable) transactions. 459 func (pool *TxPool) Stats() (int, int) { 460 pool.mu.RLock() 461 defer pool.mu.RUnlock() 462 463 return pool.stats() 464 } 465 466 // stats retrieves the current pool stats, namely the number of pending and the 467 // number of queued (non-executable) transactions. 468 func (pool *TxPool) stats() (int, int) { 469 pending := 0 470 for _, list := range pool.pending { 471 pending += list.Len() 472 } 473 queued := 0 474 for _, list := range pool.queue { 475 queued += list.Len() 476 } 477 return pending, queued 478 } 479 480 // Content retrieves the data content of the transaction pool, returning all the 481 // pending as well as queued transactions, grouped by account and sorted by nonce. 482 func (pool *TxPool) Content() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) { 483 pool.mu.Lock() 484 defer pool.mu.Unlock() 485 486 pending := make(map[common.Address]types.Transactions) 487 for addr, list := range pool.pending { 488 pending[addr] = list.Flatten() 489 } 490 queued := make(map[common.Address]types.Transactions) 491 for addr, list := range pool.queue { 492 queued[addr] = list.Flatten() 493 } 494 return pending, queued 495 } 496 497 // ContentFrom retrieves the data content of the transaction pool, returning the 498 // pending as well as queued transactions of this address, grouped by nonce. 499 func (pool *TxPool) ContentFrom(addr common.Address) (types.Transactions, types.Transactions) { 500 pool.mu.RLock() 501 defer pool.mu.RUnlock() 502 503 var pending types.Transactions 504 if list, ok := pool.pending[addr]; ok { 505 pending = list.Flatten() 506 } 507 var queued types.Transactions 508 if list, ok := pool.queue[addr]; ok { 509 queued = list.Flatten() 510 } 511 return pending, queued 512 } 513 514 // Pending retrieves all currently processable transactions, grouped by origin 515 // account and sorted by nonce. The returned transaction set is a copy and can be 516 // freely modified by calling code. 517 // 518 // The enforceTips parameter can be used to do an extra filtering on the pending 519 // transactions and only return those whose **effective** tip is large enough in 520 // the next pending execution environment. 521 func (pool *TxPool) Pending(enforceTips bool) (map[common.Address]types.Transactions, error) { 522 pool.mu.Lock() 523 defer pool.mu.Unlock() 524 525 pending := make(map[common.Address]types.Transactions) 526 for addr, list := range pool.pending { 527 txs := list.Flatten() 528 529 // If the miner requests tip enforcement, cap the lists now 530 if enforceTips && !pool.locals.contains(addr) { 531 for i, tx := range txs { 532 if tx.EffectiveGasTipIntCmp(pool.gasPrice, pool.priced.urgent.baseFee) < 0 { 533 txs = txs[:i] 534 break 535 } 536 } 537 } 538 if len(txs) > 0 { 539 pending[addr] = txs 540 } 541 } 542 return pending, nil 543 } 544 545 // Locals retrieves the accounts currently considered local by the pool. 546 func (pool *TxPool) Locals() []common.Address { 547 pool.mu.Lock() 548 defer pool.mu.Unlock() 549 550 return pool.locals.flatten() 551 } 552 553 // local retrieves all currently known local transactions, grouped by origin 554 // account and sorted by nonce. The returned transaction set is a copy and can be 555 // freely modified by calling code. 556 func (pool *TxPool) local() map[common.Address]types.Transactions { 557 txs := make(map[common.Address]types.Transactions) 558 for addr := range pool.locals.accounts { 559 if pending := pool.pending[addr]; pending != nil { 560 txs[addr] = append(txs[addr], pending.Flatten()...) 561 } 562 if queued := pool.queue[addr]; queued != nil { 563 txs[addr] = append(txs[addr], queued.Flatten()...) 564 } 565 } 566 return txs 567 } 568 569 // validateTx checks whether a transaction is valid according to the consensus 570 // rules and adheres to some heuristic limits of the local node (price and size). 571 func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { 572 // Accept only legacy transactions until EIP-2718/2930 activates. 573 if !pool.eip2718 && tx.Type() != types.LegacyTxType { 574 return ErrTxTypeNotSupported 575 } 576 // Reject dynamic fee transactions until EIP-1559 activates. 577 if !pool.eip1559 && tx.Type() == types.DynamicFeeTxType { 578 return ErrTxTypeNotSupported 579 } 580 // Reject transactions over defined size to prevent DOS attacks 581 if uint64(tx.Size()) > txMaxSize { 582 return ErrOversizedData 583 } 584 // Transactions can't be negative. This may never happen using RLP decoded 585 // transactions but may occur if you create a transaction using the RPC. 586 if tx.Value().Sign() < 0 { 587 return ErrNegativeValue 588 } 589 // Ensure the transaction doesn't exceed the current block limit gas. 590 if pool.currentMaxGas < tx.Gas() { 591 return ErrGasLimit 592 } 593 // Sanity check for extremely large numbers 594 if tx.GasFeeCap().BitLen() > 256 { 595 return ErrFeeCapVeryHigh 596 } 597 if tx.GasTipCap().BitLen() > 256 { 598 return ErrTipVeryHigh 599 } 600 // Ensure gasFeeCap is greater than or equal to gasTipCap. 601 if tx.GasFeeCapIntCmp(tx.GasTipCap()) < 0 { 602 return ErrTipAboveFeeCap 603 } 604 // Make sure the transaction is signed properly. 605 from, err := types.Sender(pool.signer, tx) 606 if err != nil { 607 return ErrInvalidSender 608 } 609 // check if sender is in black list 610 if common.Blacklist[from] { 611 return ErrInvalidSender 612 } 613 // check if receiver is in black list 614 if tx.To() != nil && common.Blacklist[*tx.To()] { 615 return ErrInvalidSender 616 } 617 // Drop non-local transactions under our own minimal accepted gas price or tip 618 if !local && tx.GasTipCapIntCmp(pool.gasPrice) < 0 { 619 return ErrUnderpriced 620 } 621 // Ensure the transaction adheres to nonce ordering 622 if pool.currentState.GetNonce(from) > tx.Nonce() { 623 return ErrNonceTooLow 624 } 625 // Transactor should have enough funds to cover the costs 626 // cost == V + GP * GL 627 if pool.currentState.GetBalance(from).Cmp(tx.Cost()) < 0 { 628 return ErrInsufficientFunds 629 } 630 // Ensure the transaction has more gas than the basic tx fee. 631 intrGas, err := IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, true, pool.istanbul) 632 if err != nil { 633 return err 634 } 635 if tx.Gas() < intrGas { 636 return ErrIntrinsicGas 637 } 638 return nil 639 } 640 641 // add validates a transaction and inserts it into the non-executable queue for later 642 // pending promotion and execution. If the transaction is a replacement for an already 643 // pending or queued one, it overwrites the previous transaction if its price is higher. 644 // 645 // If a newly added transaction is marked as local, its sending account will be 646 // be added to the allowlist, preventing any associated transaction from being dropped 647 // out of the pool due to pricing constraints. 648 func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err error) { 649 // If the transaction is already known, discard it 650 hash := tx.Hash() 651 if pool.all.Get(hash) != nil { 652 log.Trace("Discarding already known transaction", "hash", hash) 653 knownTxMeter.Mark(1) 654 return false, ErrAlreadyKnown 655 } 656 // Make the local flag. If it's from local source or it's from the network but 657 // the sender is marked as local previously, treat it as the local transaction. 658 isLocal := local || pool.locals.containsTx(tx) 659 660 // If the transaction fails basic validation, discard it 661 if err := pool.validateTx(tx, isLocal); err != nil { 662 log.Trace("Discarding invalid transaction", "hash", hash, "err", err) 663 invalidTxMeter.Mark(1) 664 return false, err 665 } 666 // If the transaction pool is full, discard underpriced transactions 667 if uint64(pool.all.Slots()+numSlots(tx)) > pool.config.GlobalSlots+pool.config.GlobalQueue { 668 // If the new transaction is underpriced, don't accept it 669 if !isLocal && pool.priced.Underpriced(tx) { 670 log.Trace("Discarding underpriced transaction", "hash", hash, "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap()) 671 underpricedTxMeter.Mark(1) 672 return false, ErrUnderpriced 673 } 674 // New transaction is better than our worse ones, make room for it. 675 // If it's a local transaction, forcibly discard all available transactions. 676 // Otherwise if we can't make enough room for new one, abort the operation. 677 drop, success := pool.priced.Discard(pool.all.Slots()-int(pool.config.GlobalSlots+pool.config.GlobalQueue)+numSlots(tx), isLocal) 678 679 // Special case, we still can't make the room for the new remote one. 680 if !isLocal && !success { 681 log.Trace("Discarding overflown transaction", "hash", hash) 682 overflowedTxMeter.Mark(1) 683 return false, ErrTxPoolOverflow 684 } 685 // Kick out the underpriced remote transactions. 686 for _, tx := range drop { 687 log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap()) 688 underpricedTxMeter.Mark(1) 689 pool.removeTx(tx.Hash(), false) 690 } 691 } 692 // Try to replace an existing transaction in the pending pool 693 from, _ := types.Sender(pool.signer, tx) // already validated 694 if list := pool.pending[from]; list != nil && list.Overlaps(tx) { 695 // Nonce already pending, check if required price bump is met 696 inserted, old := list.Add(tx, pool.config.PriceBump) 697 if !inserted { 698 pendingDiscardMeter.Mark(1) 699 return false, ErrReplaceUnderpriced 700 } 701 // New transaction is better, replace old one 702 if old != nil { 703 pool.all.Remove(old.Hash()) 704 pool.priced.Removed(1) 705 pendingReplaceMeter.Mark(1) 706 } 707 pool.all.Add(tx, isLocal) 708 pool.priced.Put(tx, isLocal) 709 pool.journalTx(from, tx) 710 pool.queueTxEvent(tx) 711 log.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To()) 712 713 // Successful promotion, bump the heartbeat 714 pool.beats[from] = time.Now() 715 return old != nil, nil 716 } 717 // New transaction isn't replacing a pending one, push into queue 718 replaced, err = pool.enqueueTx(hash, tx, isLocal, true) 719 if err != nil { 720 return false, err 721 } 722 // Mark local addresses and journal local transactions 723 if local && !pool.locals.contains(from) { 724 log.Info("Setting new local account", "address", from) 725 pool.locals.add(from) 726 pool.priced.Removed(pool.all.RemoteToLocals(pool.locals)) // Migrate the remotes if it's marked as local first time. 727 } 728 if isLocal { 729 localGauge.Inc(1) 730 } 731 pool.journalTx(from, tx) 732 733 log.Trace("Pooled new future transaction", "hash", hash, "from", from, "to", tx.To()) 734 return replaced, nil 735 } 736 737 // enqueueTx inserts a new transaction into the non-executable transaction queue. 738 // 739 // Note, this method assumes the pool lock is held! 740 func (pool *TxPool) enqueueTx(hash common.Hash, tx *types.Transaction, local bool, addAll bool) (bool, error) { 741 // Try to insert the transaction into the future queue 742 from, _ := types.Sender(pool.signer, tx) // already validated 743 if pool.queue[from] == nil { 744 pool.queue[from] = newTxList(false) 745 } 746 inserted, old := pool.queue[from].Add(tx, pool.config.PriceBump) 747 if !inserted { 748 // An older transaction was better, discard this 749 queuedDiscardMeter.Mark(1) 750 return false, ErrReplaceUnderpriced 751 } 752 // Discard any previous transaction and mark this 753 if old != nil { 754 pool.all.Remove(old.Hash()) 755 pool.priced.Removed(1) 756 queuedReplaceMeter.Mark(1) 757 } else { 758 // Nothing was replaced, bump the queued counter 759 queuedGauge.Inc(1) 760 } 761 // If the transaction isn't in lookup set but it's expected to be there, 762 // show the error log. 763 if pool.all.Get(hash) == nil && !addAll { 764 log.Error("Missing transaction in lookup set, please report the issue", "hash", hash) 765 } 766 if addAll { 767 pool.all.Add(tx, local) 768 pool.priced.Put(tx, local) 769 } 770 // If we never record the heartbeat, do it right now. 771 if _, exist := pool.beats[from]; !exist { 772 pool.beats[from] = time.Now() 773 } 774 return old != nil, nil 775 } 776 777 // journalTx adds the specified transaction to the local disk journal if it is 778 // deemed to have been sent from a local account. 779 func (pool *TxPool) journalTx(from common.Address, tx *types.Transaction) { 780 // Only journal if it's enabled and the transaction is local 781 if pool.journal == nil || !pool.locals.contains(from) { 782 return 783 } 784 if err := pool.journal.insert(tx); err != nil { 785 log.Warn("Failed to journal local transaction", "err", err) 786 } 787 } 788 789 // promoteTx adds a transaction to the pending (processable) list of transactions 790 // and returns whether it was inserted or an older was better. 791 // 792 // Note, this method assumes the pool lock is held! 793 func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.Transaction) bool { 794 // Try to insert the transaction into the pending queue 795 if pool.pending[addr] == nil { 796 pool.pending[addr] = newTxList(true) 797 } 798 list := pool.pending[addr] 799 800 inserted, old := list.Add(tx, pool.config.PriceBump) 801 if !inserted { 802 // An older transaction was better, discard this 803 pool.all.Remove(hash) 804 pool.priced.Removed(1) 805 pendingDiscardMeter.Mark(1) 806 return false 807 } 808 // Otherwise discard any previous transaction and mark this 809 if old != nil { 810 pool.all.Remove(old.Hash()) 811 pool.priced.Removed(1) 812 pendingReplaceMeter.Mark(1) 813 } else { 814 // Nothing was replaced, bump the pending counter 815 pendingGauge.Inc(1) 816 } 817 // Set the potentially new pending nonce and notify any subsystems of the new tx 818 pool.pendingNonces.set(addr, tx.Nonce()+1) 819 820 // Successful promotion, bump the heartbeat 821 pool.beats[addr] = time.Now() 822 return true 823 } 824 825 // AddLocals enqueues a batch of transactions into the pool if they are valid, marking the 826 // senders as a local ones, ensuring they go around the local pricing constraints. 827 // 828 // This method is used to add transactions from the RPC API and performs synchronous pool 829 // reorganization and event propagation. 830 func (pool *TxPool) AddLocals(txs []*types.Transaction) []error { 831 return pool.addTxs(txs, !pool.config.NoLocals, true) 832 } 833 834 // AddLocal enqueues a single local transaction into the pool if it is valid. This is 835 // a convenience wrapper aroundd AddLocals. 836 func (pool *TxPool) AddLocal(tx *types.Transaction) error { 837 errs := pool.AddLocals([]*types.Transaction{tx}) 838 return errs[0] 839 } 840 841 // AddRemotes enqueues a batch of transactions into the pool if they are valid. If the 842 // senders are not among the locally tracked ones, full pricing constraints will apply. 843 // 844 // This method is used to add transactions from the p2p network and does not wait for pool 845 // reorganization and internal event propagation. 846 func (pool *TxPool) AddRemotes(txs []*types.Transaction) []error { 847 return pool.addTxs(txs, false, false) 848 } 849 850 // This is like AddRemotes, but waits for pool reorganization. Tests use this method. 851 func (pool *TxPool) AddRemotesSync(txs []*types.Transaction) []error { 852 return pool.addTxs(txs, false, true) 853 } 854 855 // This is like AddRemotes with a single transaction, but waits for pool reorganization. Tests use this method. 856 func (pool *TxPool) addRemoteSync(tx *types.Transaction) error { 857 errs := pool.AddRemotesSync([]*types.Transaction{tx}) 858 return errs[0] 859 } 860 861 // AddRemote enqueues a single transaction into the pool if it is valid. This is a convenience 862 // wrapper around AddRemotes. 863 // 864 // Deprecated: use AddRemotes 865 func (pool *TxPool) AddRemote(tx *types.Transaction) error { 866 errs := pool.AddRemotes([]*types.Transaction{tx}) 867 return errs[0] 868 } 869 870 // addTxs attempts to queue a batch of transactions if they are valid. 871 func (pool *TxPool) addTxs(txs []*types.Transaction, local, sync bool) []error { 872 // Filter out known ones without obtaining the pool lock or recovering signatures 873 var ( 874 errs = make([]error, len(txs)) 875 news = make([]*types.Transaction, 0, len(txs)) 876 ) 877 for i, tx := range txs { 878 // If the transaction is known, pre-set the error slot 879 if pool.all.Get(tx.Hash()) != nil { 880 errs[i] = ErrAlreadyKnown 881 knownTxMeter.Mark(1) 882 continue 883 } 884 // Exclude transactions with invalid signatures as soon as 885 // possible and cache senders in transactions before 886 // obtaining lock 887 _, err := types.Sender(pool.signer, tx) 888 if err != nil { 889 errs[i] = ErrInvalidSender 890 invalidTxMeter.Mark(1) 891 continue 892 } 893 // Accumulate all unknown transactions for deeper processing 894 news = append(news, tx) 895 } 896 if len(news) == 0 { 897 return errs 898 } 899 900 // Process all the new transaction and merge any errors into the original slice 901 pool.mu.Lock() 902 newErrs, dirtyAddrs := pool.addTxsLocked(news, local) 903 pool.mu.Unlock() 904 905 var nilSlot = 0 906 for _, err := range newErrs { 907 for errs[nilSlot] != nil { 908 nilSlot++ 909 } 910 errs[nilSlot] = err 911 nilSlot++ 912 } 913 // Reorg the pool internals if needed and return 914 done := pool.requestPromoteExecutables(dirtyAddrs) 915 if sync { 916 <-done 917 } 918 return errs 919 } 920 921 // addTxsLocked attempts to queue a batch of transactions if they are valid. 922 // The transaction pool lock must be held. 923 func (pool *TxPool) addTxsLocked(txs []*types.Transaction, local bool) ([]error, *accountSet) { 924 dirty := newAccountSet(pool.signer) 925 errs := make([]error, len(txs)) 926 for i, tx := range txs { 927 replaced, err := pool.add(tx, local) 928 errs[i] = err 929 if err == nil && !replaced { 930 dirty.addTx(tx) 931 } 932 } 933 validTxMeter.Mark(int64(len(dirty.accounts))) 934 return errs, dirty 935 } 936 937 // Status returns the status (unknown/pending/queued) of a batch of transactions 938 // identified by their hashes. 939 func (pool *TxPool) Status(hashes []common.Hash) []TxStatus { 940 status := make([]TxStatus, len(hashes)) 941 for i, hash := range hashes { 942 tx := pool.Get(hash) 943 if tx == nil { 944 continue 945 } 946 from, _ := types.Sender(pool.signer, tx) // already validated 947 pool.mu.RLock() 948 if txList := pool.pending[from]; txList != nil && txList.txs.items[tx.Nonce()] != nil { 949 status[i] = TxStatusPending 950 } else if txList := pool.queue[from]; txList != nil && txList.txs.items[tx.Nonce()] != nil { 951 status[i] = TxStatusQueued 952 } 953 // implicit else: the tx may have been included into a block between 954 // checking pool.Get and obtaining the lock. In that case, TxStatusUnknown is correct 955 pool.mu.RUnlock() 956 } 957 return status 958 } 959 960 // Get returns a transaction if it is contained in the pool and nil otherwise. 961 func (pool *TxPool) Get(hash common.Hash) *types.Transaction { 962 return pool.all.Get(hash) 963 } 964 965 // Has returns an indicator whether txpool has a transaction cached with the 966 // given hash. 967 func (pool *TxPool) Has(hash common.Hash) bool { 968 return pool.all.Get(hash) != nil 969 } 970 971 // removeTx removes a single transaction from the queue, moving all subsequent 972 // transactions back to the future queue. 973 func (pool *TxPool) removeTx(hash common.Hash, outofbound bool) { 974 // Fetch the transaction we wish to delete 975 tx := pool.all.Get(hash) 976 if tx == nil { 977 return 978 } 979 addr, _ := types.Sender(pool.signer, tx) // already validated during insertion 980 981 // Remove it from the list of known transactions 982 pool.all.Remove(hash) 983 if outofbound { 984 pool.priced.Removed(1) 985 } 986 if pool.locals.contains(addr) { 987 localGauge.Dec(1) 988 } 989 // Remove the transaction from the pending lists and reset the account nonce 990 if pending := pool.pending[addr]; pending != nil { 991 if removed, invalids := pending.Remove(tx); removed { 992 // If no more pending transactions are left, remove the list 993 if pending.Empty() { 994 delete(pool.pending, addr) 995 } 996 // Postpone any invalidated transactions 997 for _, tx := range invalids { 998 // Internal shuffle shouldn't touch the lookup set. 999 pool.enqueueTx(tx.Hash(), tx, false, false) 1000 } 1001 // Update the account nonce if needed 1002 pool.pendingNonces.setIfLower(addr, tx.Nonce()) 1003 // Reduce the pending counter 1004 pendingGauge.Dec(int64(1 + len(invalids))) 1005 return 1006 } 1007 } 1008 // Transaction is in the future queue 1009 if future := pool.queue[addr]; future != nil { 1010 if removed, _ := future.Remove(tx); removed { 1011 // Reduce the queued counter 1012 queuedGauge.Dec(1) 1013 } 1014 if future.Empty() { 1015 delete(pool.queue, addr) 1016 delete(pool.beats, addr) 1017 } 1018 } 1019 } 1020 1021 // requestReset requests a pool reset to the new head block. 1022 // The returned channel is closed when the reset has occurred. 1023 func (pool *TxPool) requestReset(oldHead *types.Header, newHead *types.Header) chan struct{} { 1024 select { 1025 case pool.reqResetCh <- &txpoolResetRequest{oldHead, newHead}: 1026 return <-pool.reorgDoneCh 1027 case <-pool.reorgShutdownCh: 1028 return pool.reorgShutdownCh 1029 } 1030 } 1031 1032 // requestPromoteExecutables requests transaction promotion checks for the given addresses. 1033 // The returned channel is closed when the promotion checks have occurred. 1034 func (pool *TxPool) requestPromoteExecutables(set *accountSet) chan struct{} { 1035 select { 1036 case pool.reqPromoteCh <- set: 1037 return <-pool.reorgDoneCh 1038 case <-pool.reorgShutdownCh: 1039 return pool.reorgShutdownCh 1040 } 1041 } 1042 1043 // queueTxEvent enqueues a transaction event to be sent in the next reorg run. 1044 func (pool *TxPool) queueTxEvent(tx *types.Transaction) { 1045 select { 1046 case pool.queueTxEventCh <- tx: 1047 case <-pool.reorgShutdownCh: 1048 } 1049 } 1050 1051 // scheduleReorgLoop schedules runs of reset and promoteExecutables. Code above should not 1052 // call those methods directly, but request them being run using requestReset and 1053 // requestPromoteExecutables instead. 1054 func (pool *TxPool) scheduleReorgLoop() { 1055 defer pool.wg.Done() 1056 1057 var ( 1058 curDone chan struct{} // non-nil while runReorg is active 1059 nextDone = make(chan struct{}) 1060 launchNextRun bool 1061 reset *txpoolResetRequest 1062 dirtyAccounts *accountSet 1063 queuedEvents = make(map[common.Address]*txSortedMap) 1064 ) 1065 for { 1066 // Launch next background reorg if needed 1067 if curDone == nil && launchNextRun { 1068 // Run the background reorg and announcements 1069 go pool.runReorg(nextDone, reset, dirtyAccounts, queuedEvents) 1070 1071 // Prepare everything for the next round of reorg 1072 curDone, nextDone = nextDone, make(chan struct{}) 1073 launchNextRun = false 1074 1075 reset, dirtyAccounts = nil, nil 1076 queuedEvents = make(map[common.Address]*txSortedMap) 1077 } 1078 1079 select { 1080 case req := <-pool.reqResetCh: 1081 // Reset request: update head if request is already pending. 1082 if reset == nil { 1083 reset = req 1084 } else { 1085 reset.newHead = req.newHead 1086 } 1087 launchNextRun = true 1088 pool.reorgDoneCh <- nextDone 1089 1090 case req := <-pool.reqPromoteCh: 1091 // Promote request: update address set if request is already pending. 1092 if dirtyAccounts == nil { 1093 dirtyAccounts = req 1094 } else { 1095 dirtyAccounts.merge(req) 1096 } 1097 launchNextRun = true 1098 pool.reorgDoneCh <- nextDone 1099 1100 case tx := <-pool.queueTxEventCh: 1101 // Queue up the event, but don't schedule a reorg. It's up to the caller to 1102 // request one later if they want the events sent. 1103 addr, _ := types.Sender(pool.signer, tx) 1104 if _, ok := queuedEvents[addr]; !ok { 1105 queuedEvents[addr] = newTxSortedMap() 1106 } 1107 queuedEvents[addr].Put(tx) 1108 1109 case <-curDone: 1110 curDone = nil 1111 1112 case <-pool.reorgShutdownCh: 1113 // Wait for current run to finish. 1114 if curDone != nil { 1115 <-curDone 1116 } 1117 close(nextDone) 1118 return 1119 } 1120 } 1121 } 1122 1123 // runReorg runs reset and promoteExecutables on behalf of scheduleReorgLoop. 1124 func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirtyAccounts *accountSet, events map[common.Address]*txSortedMap) { 1125 defer close(done) 1126 1127 var promoteAddrs []common.Address 1128 if dirtyAccounts != nil && reset == nil { 1129 // Only dirty accounts need to be promoted, unless we're resetting. 1130 // For resets, all addresses in the tx queue will be promoted and 1131 // the flatten operation can be avoided. 1132 promoteAddrs = dirtyAccounts.flatten() 1133 } 1134 pool.mu.Lock() 1135 if reset != nil { 1136 // Reset from the old head to the new, rescheduling any reorged transactions 1137 pool.reset(reset.oldHead, reset.newHead) 1138 1139 // Nonces were reset, discard any events that became stale 1140 for addr := range events { 1141 events[addr].Forward(pool.pendingNonces.get(addr)) 1142 if events[addr].Len() == 0 { 1143 delete(events, addr) 1144 } 1145 } 1146 // Reset needs promote for all addresses 1147 promoteAddrs = make([]common.Address, 0, len(pool.queue)) 1148 for addr := range pool.queue { 1149 promoteAddrs = append(promoteAddrs, addr) 1150 } 1151 } 1152 // Check for pending transactions for every account that sent new ones 1153 promoted := pool.promoteExecutables(promoteAddrs) 1154 1155 // If a new block appeared, validate the pool of pending transactions. This will 1156 // remove any transaction that has been included in the block or was invalidated 1157 // because of another transaction (e.g. higher gas price). 1158 if reset != nil { 1159 pool.demoteUnexecutables() 1160 if reset.newHead != nil && pool.chainconfig.IsLondon(new(big.Int).Add(reset.newHead.Number, big.NewInt(1))) { 1161 pendingBaseFee := misc.CalcBaseFee(pool.chainconfig, reset.newHead) 1162 pool.priced.SetBaseFee(pendingBaseFee) 1163 } 1164 } 1165 // Ensure pool.queue and pool.pending sizes stay within the configured limits. 1166 pool.truncatePending() 1167 pool.truncateQueue() 1168 1169 // Update all accounts to the latest known pending nonce 1170 for addr, list := range pool.pending { 1171 highestPending := list.LastElement() 1172 pool.pendingNonces.set(addr, highestPending.Nonce()+1) 1173 } 1174 pool.mu.Unlock() 1175 1176 // Notify subsystems for newly added transactions 1177 for _, tx := range promoted { 1178 addr, _ := types.Sender(pool.signer, tx) 1179 if _, ok := events[addr]; !ok { 1180 events[addr] = newTxSortedMap() 1181 } 1182 events[addr].Put(tx) 1183 } 1184 if len(events) > 0 { 1185 var txs []*types.Transaction 1186 for _, set := range events { 1187 txs = append(txs, set.Flatten()...) 1188 } 1189 pool.txFeed.Send(NewTxsEvent{txs}) 1190 } 1191 } 1192 1193 // reset retrieves the current state of the blockchain and ensures the content 1194 // of the transaction pool is valid with regard to the chain state. 1195 func (pool *TxPool) reset(oldHead, newHead *types.Header) { 1196 // If we're reorging an old state, reinject all dropped transactions 1197 var reinject types.Transactions 1198 1199 if oldHead != nil && oldHead.Hash() != newHead.ParentHash { 1200 // If the reorg is too deep, avoid doing it (will happen during fast sync) 1201 oldNum := oldHead.Number.Uint64() 1202 newNum := newHead.Number.Uint64() 1203 1204 if depth := uint64(math.Abs(float64(oldNum) - float64(newNum))); depth > 64 { 1205 log.Debug("Skipping deep transaction reorg", "depth", depth) 1206 } else { 1207 // Reorg seems shallow enough to pull in all transactions into memory 1208 var discarded, included types.Transactions 1209 var ( 1210 rem = pool.chain.GetBlock(oldHead.Hash(), oldHead.Number.Uint64()) 1211 add = pool.chain.GetBlock(newHead.Hash(), newHead.Number.Uint64()) 1212 ) 1213 if rem == nil { 1214 // This can happen if a setHead is performed, where we simply discard the old 1215 // head from the chain. 1216 // If that is the case, we don't have the lost transactions any more, and 1217 // there's nothing to add 1218 if newNum >= oldNum { 1219 // If we reorged to a same or higher number, then it's not a case of setHead 1220 log.Warn("Transaction pool reset with missing oldhead", 1221 "old", oldHead.Hash(), "oldnum", oldNum, "new", newHead.Hash(), "newnum", newNum) 1222 return 1223 } 1224 // If the reorg ended up on a lower number, it's indicative of setHead being the cause 1225 log.Debug("Skipping transaction reset caused by setHead", 1226 "old", oldHead.Hash(), "oldnum", oldNum, "new", newHead.Hash(), "newnum", newNum) 1227 // We still need to update the current state s.th. the lost transactions can be readded by the user 1228 } else { 1229 for rem.NumberU64() > add.NumberU64() { 1230 discarded = append(discarded, rem.Transactions()...) 1231 if rem = pool.chain.GetBlock(rem.ParentHash(), rem.NumberU64()-1); rem == nil { 1232 log.Error("Unrooted old chain seen by tx pool", "block", oldHead.Number, "hash", oldHead.Hash()) 1233 return 1234 } 1235 } 1236 for add.NumberU64() > rem.NumberU64() { 1237 included = append(included, add.Transactions()...) 1238 if add = pool.chain.GetBlock(add.ParentHash(), add.NumberU64()-1); add == nil { 1239 log.Error("Unrooted new chain seen by tx pool", "block", newHead.Number, "hash", newHead.Hash()) 1240 return 1241 } 1242 } 1243 for rem.Hash() != add.Hash() { 1244 discarded = append(discarded, rem.Transactions()...) 1245 if rem = pool.chain.GetBlock(rem.ParentHash(), rem.NumberU64()-1); rem == nil { 1246 log.Error("Unrooted old chain seen by tx pool", "block", oldHead.Number, "hash", oldHead.Hash()) 1247 return 1248 } 1249 included = append(included, add.Transactions()...) 1250 if add = pool.chain.GetBlock(add.ParentHash(), add.NumberU64()-1); add == nil { 1251 log.Error("Unrooted new chain seen by tx pool", "block", newHead.Number, "hash", newHead.Hash()) 1252 return 1253 } 1254 } 1255 reinject = types.TxDifference(discarded, included) 1256 } 1257 } 1258 } 1259 // Initialize the internal state to the current head 1260 if newHead == nil { 1261 newHead = pool.chain.CurrentBlock().Header() // Special case during testing 1262 } 1263 statedb, err := pool.chain.StateAt(newHead.Root) 1264 if err != nil { 1265 log.Error("Failed to reset txpool state", "err", err) 1266 return 1267 } 1268 pool.currentState = statedb 1269 pool.pendingNonces = newTxNoncer(statedb) 1270 pool.currentMaxGas = newHead.GasLimit 1271 1272 // Inject any transactions discarded due to reorgs 1273 log.Debug("Reinjecting stale transactions", "count", len(reinject)) 1274 senderCacher.recover(pool.signer, reinject) 1275 pool.addTxsLocked(reinject, false) 1276 1277 // Update all fork indicator by next pending block number. 1278 next := new(big.Int).Add(newHead.Number, big.NewInt(1)) 1279 pool.istanbul = pool.chainconfig.IsIstanbul(next) 1280 pool.eip2718 = pool.chainconfig.IsBerlin(next) 1281 pool.eip1559 = pool.chainconfig.IsLondon(next) 1282 } 1283 1284 // promoteExecutables moves transactions that have become processable from the 1285 // future queue to the set of pending transactions. During this process, all 1286 // invalidated transactions (low nonce, low balance) are deleted. 1287 func (pool *TxPool) promoteExecutables(accounts []common.Address) []*types.Transaction { 1288 // Track the promoted transactions to broadcast them at once 1289 var promoted []*types.Transaction 1290 1291 // Iterate over all accounts and promote any executable transactions 1292 for _, addr := range accounts { 1293 list := pool.queue[addr] 1294 if list == nil { 1295 continue // Just in case someone calls with a non existing account 1296 } 1297 // Drop all transactions that are deemed too old (low nonce) 1298 forwards := list.Forward(pool.currentState.GetNonce(addr)) 1299 for _, tx := range forwards { 1300 hash := tx.Hash() 1301 pool.all.Remove(hash) 1302 } 1303 log.Trace("Removed old queued transactions", "count", len(forwards)) 1304 // Drop all transactions that are too costly (low balance or out of gas) 1305 drops, _ := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas) 1306 for _, tx := range drops { 1307 hash := tx.Hash() 1308 pool.all.Remove(hash) 1309 } 1310 log.Trace("Removed unpayable queued transactions", "count", len(drops)) 1311 queuedNofundsMeter.Mark(int64(len(drops))) 1312 1313 // Gather all executable transactions and promote them 1314 readies := list.Ready(pool.pendingNonces.get(addr)) 1315 for _, tx := range readies { 1316 hash := tx.Hash() 1317 if pool.promoteTx(addr, hash, tx) { 1318 promoted = append(promoted, tx) 1319 } 1320 } 1321 log.Trace("Promoted queued transactions", "count", len(promoted)) 1322 queuedGauge.Dec(int64(len(readies))) 1323 1324 // Drop all transactions over the allowed limit 1325 var caps types.Transactions 1326 if !pool.locals.contains(addr) { 1327 caps = list.Cap(int(pool.config.AccountQueue)) 1328 for _, tx := range caps { 1329 hash := tx.Hash() 1330 pool.all.Remove(hash) 1331 log.Trace("Removed cap-exceeding queued transaction", "hash", hash) 1332 } 1333 queuedRateLimitMeter.Mark(int64(len(caps))) 1334 } 1335 // Mark all the items dropped as removed 1336 pool.priced.Removed(len(forwards) + len(drops) + len(caps)) 1337 queuedGauge.Dec(int64(len(forwards) + len(drops) + len(caps))) 1338 if pool.locals.contains(addr) { 1339 localGauge.Dec(int64(len(forwards) + len(drops) + len(caps))) 1340 } 1341 // Delete the entire queue entry if it became empty. 1342 if list.Empty() { 1343 delete(pool.queue, addr) 1344 delete(pool.beats, addr) 1345 } 1346 } 1347 return promoted 1348 } 1349 1350 // truncatePending removes transactions from the pending queue if the pool is above the 1351 // pending limit. The algorithm tries to reduce transaction counts by an approximately 1352 // equal number for all for accounts with many pending transactions. 1353 func (pool *TxPool) truncatePending() { 1354 pending := uint64(0) 1355 for _, list := range pool.pending { 1356 pending += uint64(list.Len()) 1357 } 1358 if pending <= pool.config.GlobalSlots { 1359 return 1360 } 1361 1362 pendingBeforeCap := pending 1363 // Assemble a spam order to penalize large transactors first 1364 spammers := prque.New(nil) 1365 for addr, list := range pool.pending { 1366 // Only evict transactions from high rollers 1367 if !pool.locals.contains(addr) && uint64(list.Len()) > pool.config.AccountSlots { 1368 spammers.Push(addr, int64(list.Len())) 1369 } 1370 } 1371 // Gradually drop transactions from offenders 1372 offenders := []common.Address{} 1373 for pending > pool.config.GlobalSlots && !spammers.Empty() { 1374 // Retrieve the next offender if not local address 1375 offender, _ := spammers.Pop() 1376 offenders = append(offenders, offender.(common.Address)) 1377 1378 // Equalize balances until all the same or below threshold 1379 if len(offenders) > 1 { 1380 // Calculate the equalization threshold for all current offenders 1381 threshold := pool.pending[offender.(common.Address)].Len() 1382 1383 // Iteratively reduce all offenders until below limit or threshold reached 1384 for pending > pool.config.GlobalSlots && pool.pending[offenders[len(offenders)-2]].Len() > threshold { 1385 for i := 0; i < len(offenders)-1; i++ { 1386 list := pool.pending[offenders[i]] 1387 1388 caps := list.Cap(list.Len() - 1) 1389 for _, tx := range caps { 1390 // Drop the transaction from the global pools too 1391 hash := tx.Hash() 1392 pool.all.Remove(hash) 1393 1394 // Update the account nonce to the dropped transaction 1395 pool.pendingNonces.setIfLower(offenders[i], tx.Nonce()) 1396 log.Trace("Removed fairness-exceeding pending transaction", "hash", hash) 1397 } 1398 pool.priced.Removed(len(caps)) 1399 pendingGauge.Dec(int64(len(caps))) 1400 if pool.locals.contains(offenders[i]) { 1401 localGauge.Dec(int64(len(caps))) 1402 } 1403 pending-- 1404 } 1405 } 1406 } 1407 } 1408 1409 // If still above threshold, reduce to limit or min allowance 1410 if pending > pool.config.GlobalSlots && len(offenders) > 0 { 1411 for pending > pool.config.GlobalSlots && uint64(pool.pending[offenders[len(offenders)-1]].Len()) > pool.config.AccountSlots { 1412 for _, addr := range offenders { 1413 list := pool.pending[addr] 1414 1415 caps := list.Cap(list.Len() - 1) 1416 for _, tx := range caps { 1417 // Drop the transaction from the global pools too 1418 hash := tx.Hash() 1419 pool.all.Remove(hash) 1420 1421 // Update the account nonce to the dropped transaction 1422 pool.pendingNonces.setIfLower(addr, tx.Nonce()) 1423 log.Trace("Removed fairness-exceeding pending transaction", "hash", hash) 1424 } 1425 pool.priced.Removed(len(caps)) 1426 pendingGauge.Dec(int64(len(caps))) 1427 if pool.locals.contains(addr) { 1428 localGauge.Dec(int64(len(caps))) 1429 } 1430 pending-- 1431 } 1432 } 1433 } 1434 pendingRateLimitMeter.Mark(int64(pendingBeforeCap - pending)) 1435 } 1436 1437 // truncateQueue drops the oldes transactions in the queue if the pool is above the global queue limit. 1438 func (pool *TxPool) truncateQueue() { 1439 queued := uint64(0) 1440 for _, list := range pool.queue { 1441 queued += uint64(list.Len()) 1442 } 1443 if queued <= pool.config.GlobalQueue { 1444 return 1445 } 1446 1447 // Sort all accounts with queued transactions by heartbeat 1448 addresses := make(addressesByHeartbeat, 0, len(pool.queue)) 1449 for addr := range pool.queue { 1450 if !pool.locals.contains(addr) { // don't drop locals 1451 addresses = append(addresses, addressByHeartbeat{addr, pool.beats[addr]}) 1452 } 1453 } 1454 sort.Sort(addresses) 1455 1456 // Drop transactions until the total is below the limit or only locals remain 1457 for drop := queued - pool.config.GlobalQueue; drop > 0 && len(addresses) > 0; { 1458 addr := addresses[len(addresses)-1] 1459 list := pool.queue[addr.address] 1460 1461 addresses = addresses[:len(addresses)-1] 1462 1463 // Drop all transactions if they are less than the overflow 1464 if size := uint64(list.Len()); size <= drop { 1465 for _, tx := range list.Flatten() { 1466 pool.removeTx(tx.Hash(), true) 1467 } 1468 drop -= size 1469 queuedRateLimitMeter.Mark(int64(size)) 1470 continue 1471 } 1472 // Otherwise drop only last few transactions 1473 txs := list.Flatten() 1474 for i := len(txs) - 1; i >= 0 && drop > 0; i-- { 1475 pool.removeTx(txs[i].Hash(), true) 1476 drop-- 1477 queuedRateLimitMeter.Mark(1) 1478 } 1479 } 1480 } 1481 1482 // demoteUnexecutables removes invalid and processed transactions from the pools 1483 // executable/pending queue and any subsequent transactions that become unexecutable 1484 // are moved back into the future queue. 1485 // 1486 // Note: transactions are not marked as removed in the priced list because re-heaping 1487 // is always explicitly triggered by SetBaseFee and it would be unnecessary and wasteful 1488 // to trigger a re-heap is this function 1489 func (pool *TxPool) demoteUnexecutables() { 1490 // Iterate over all accounts and demote any non-executable transactions 1491 for addr, list := range pool.pending { 1492 nonce := pool.currentState.GetNonce(addr) 1493 1494 // Drop all transactions that are deemed too old (low nonce) 1495 olds := list.Forward(nonce) 1496 for _, tx := range olds { 1497 hash := tx.Hash() 1498 pool.all.Remove(hash) 1499 log.Trace("Removed old pending transaction", "hash", hash) 1500 } 1501 // Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later 1502 drops, invalids := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas) 1503 for _, tx := range drops { 1504 hash := tx.Hash() 1505 log.Trace("Removed unpayable pending transaction", "hash", hash) 1506 pool.all.Remove(hash) 1507 } 1508 pendingNofundsMeter.Mark(int64(len(drops))) 1509 1510 for _, tx := range invalids { 1511 hash := tx.Hash() 1512 log.Trace("Demoting pending transaction", "hash", hash) 1513 1514 // Internal shuffle shouldn't touch the lookup set. 1515 pool.enqueueTx(hash, tx, false, false) 1516 } 1517 pendingGauge.Dec(int64(len(olds) + len(drops) + len(invalids))) 1518 if pool.locals.contains(addr) { 1519 localGauge.Dec(int64(len(olds) + len(drops) + len(invalids))) 1520 } 1521 // If there's a gap in front, alert (should never happen) and postpone all transactions 1522 if list.Len() > 0 && list.txs.Get(nonce) == nil { 1523 gapped := list.Cap(0) 1524 for _, tx := range gapped { 1525 hash := tx.Hash() 1526 log.Error("Demoting invalidated transaction", "hash", hash) 1527 1528 // Internal shuffle shouldn't touch the lookup set. 1529 pool.enqueueTx(hash, tx, false, false) 1530 } 1531 pendingGauge.Dec(int64(len(gapped))) 1532 // This might happen in a reorg, so log it to the metering 1533 blockReorgInvalidatedTx.Mark(int64(len(gapped))) 1534 } 1535 // Delete the entire pending entry if it became empty. 1536 if list.Empty() { 1537 delete(pool.pending, addr) 1538 } 1539 } 1540 } 1541 1542 // addressByHeartbeat is an account address tagged with its last activity timestamp. 1543 type addressByHeartbeat struct { 1544 address common.Address 1545 heartbeat time.Time 1546 } 1547 1548 type addressesByHeartbeat []addressByHeartbeat 1549 1550 func (a addressesByHeartbeat) Len() int { return len(a) } 1551 func (a addressesByHeartbeat) Less(i, j int) bool { return a[i].heartbeat.Before(a[j].heartbeat) } 1552 func (a addressesByHeartbeat) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 1553 1554 // accountSet is simply a set of addresses to check for existence, and a signer 1555 // capable of deriving addresses from transactions. 1556 type accountSet struct { 1557 accounts map[common.Address]struct{} 1558 signer types.Signer 1559 cache *[]common.Address 1560 } 1561 1562 // newAccountSet creates a new address set with an associated signer for sender 1563 // derivations. 1564 func newAccountSet(signer types.Signer, addrs ...common.Address) *accountSet { 1565 as := &accountSet{ 1566 accounts: make(map[common.Address]struct{}), 1567 signer: signer, 1568 } 1569 for _, addr := range addrs { 1570 as.add(addr) 1571 } 1572 return as 1573 } 1574 1575 // contains checks if a given address is contained within the set. 1576 func (as *accountSet) contains(addr common.Address) bool { 1577 _, exist := as.accounts[addr] 1578 return exist 1579 } 1580 1581 func (as *accountSet) empty() bool { 1582 return len(as.accounts) == 0 1583 } 1584 1585 // containsTx checks if the sender of a given tx is within the set. If the sender 1586 // cannot be derived, this method returns false. 1587 func (as *accountSet) containsTx(tx *types.Transaction) bool { 1588 if addr, err := types.Sender(as.signer, tx); err == nil { 1589 return as.contains(addr) 1590 } 1591 return false 1592 } 1593 1594 // add inserts a new address into the set to track. 1595 func (as *accountSet) add(addr common.Address) { 1596 as.accounts[addr] = struct{}{} 1597 as.cache = nil 1598 } 1599 1600 // addTx adds the sender of tx into the set. 1601 func (as *accountSet) addTx(tx *types.Transaction) { 1602 if addr, err := types.Sender(as.signer, tx); err == nil { 1603 as.add(addr) 1604 } 1605 } 1606 1607 // flatten returns the list of addresses within this set, also caching it for later 1608 // reuse. The returned slice should not be changed! 1609 func (as *accountSet) flatten() []common.Address { 1610 if as.cache == nil { 1611 accounts := make([]common.Address, 0, len(as.accounts)) 1612 for account := range as.accounts { 1613 accounts = append(accounts, account) 1614 } 1615 as.cache = &accounts 1616 } 1617 return *as.cache 1618 } 1619 1620 // merge adds all addresses from the 'other' set into 'as'. 1621 func (as *accountSet) merge(other *accountSet) { 1622 for addr := range other.accounts { 1623 as.accounts[addr] = struct{}{} 1624 } 1625 as.cache = nil 1626 } 1627 1628 // txLookup is used internally by TxPool to track transactions while allowing 1629 // lookup without mutex contention. 1630 // 1631 // Note, although this type is properly protected against concurrent access, it 1632 // is **not** a type that should ever be mutated or even exposed outside of the 1633 // transaction pool, since its internal state is tightly coupled with the pools 1634 // internal mechanisms. The sole purpose of the type is to permit out-of-bound 1635 // peeking into the pool in TxPool.Get without having to acquire the widely scoped 1636 // TxPool.mu mutex. 1637 // 1638 // This lookup set combines the notion of "local transactions", which is useful 1639 // to build upper-level structure. 1640 type txLookup struct { 1641 slots int 1642 lock sync.RWMutex 1643 locals map[common.Hash]*types.Transaction 1644 remotes map[common.Hash]*types.Transaction 1645 } 1646 1647 // newTxLookup returns a new txLookup structure. 1648 func newTxLookup() *txLookup { 1649 return &txLookup{ 1650 locals: make(map[common.Hash]*types.Transaction), 1651 remotes: make(map[common.Hash]*types.Transaction), 1652 } 1653 } 1654 1655 // Range calls f on each key and value present in the map. The callback passed 1656 // should return the indicator whether the iteration needs to be continued. 1657 // Callers need to specify which set (or both) to be iterated. 1658 func (t *txLookup) Range(f func(hash common.Hash, tx *types.Transaction, local bool) bool, local bool, remote bool) { 1659 t.lock.RLock() 1660 defer t.lock.RUnlock() 1661 1662 if local { 1663 for key, value := range t.locals { 1664 if !f(key, value, true) { 1665 return 1666 } 1667 } 1668 } 1669 if remote { 1670 for key, value := range t.remotes { 1671 if !f(key, value, false) { 1672 return 1673 } 1674 } 1675 } 1676 } 1677 1678 // Get returns a transaction if it exists in the lookup, or nil if not found. 1679 func (t *txLookup) Get(hash common.Hash) *types.Transaction { 1680 t.lock.RLock() 1681 defer t.lock.RUnlock() 1682 1683 if tx := t.locals[hash]; tx != nil { 1684 return tx 1685 } 1686 return t.remotes[hash] 1687 } 1688 1689 // GetLocal returns a transaction if it exists in the lookup, or nil if not found. 1690 func (t *txLookup) GetLocal(hash common.Hash) *types.Transaction { 1691 t.lock.RLock() 1692 defer t.lock.RUnlock() 1693 1694 return t.locals[hash] 1695 } 1696 1697 // GetRemote returns a transaction if it exists in the lookup, or nil if not found. 1698 func (t *txLookup) GetRemote(hash common.Hash) *types.Transaction { 1699 t.lock.RLock() 1700 defer t.lock.RUnlock() 1701 1702 return t.remotes[hash] 1703 } 1704 1705 // Count returns the current number of transactions in the lookup. 1706 func (t *txLookup) Count() int { 1707 t.lock.RLock() 1708 defer t.lock.RUnlock() 1709 1710 return len(t.locals) + len(t.remotes) 1711 } 1712 1713 // LocalCount returns the current number of local transactions in the lookup. 1714 func (t *txLookup) LocalCount() int { 1715 t.lock.RLock() 1716 defer t.lock.RUnlock() 1717 1718 return len(t.locals) 1719 } 1720 1721 // RemoteCount returns the current number of remote transactions in the lookup. 1722 func (t *txLookup) RemoteCount() int { 1723 t.lock.RLock() 1724 defer t.lock.RUnlock() 1725 1726 return len(t.remotes) 1727 } 1728 1729 // Slots returns the current number of slots used in the lookup. 1730 func (t *txLookup) Slots() int { 1731 t.lock.RLock() 1732 defer t.lock.RUnlock() 1733 1734 return t.slots 1735 } 1736 1737 // Add adds a transaction to the lookup. 1738 func (t *txLookup) Add(tx *types.Transaction, local bool) { 1739 t.lock.Lock() 1740 defer t.lock.Unlock() 1741 1742 t.slots += numSlots(tx) 1743 slotsGauge.Update(int64(t.slots)) 1744 1745 if local { 1746 t.locals[tx.Hash()] = tx 1747 } else { 1748 t.remotes[tx.Hash()] = tx 1749 } 1750 } 1751 1752 // Remove removes a transaction from the lookup. 1753 func (t *txLookup) Remove(hash common.Hash) { 1754 t.lock.Lock() 1755 defer t.lock.Unlock() 1756 1757 tx, ok := t.locals[hash] 1758 if !ok { 1759 tx, ok = t.remotes[hash] 1760 } 1761 if !ok { 1762 log.Error("No transaction found to be deleted", "hash", hash) 1763 return 1764 } 1765 t.slots -= numSlots(tx) 1766 slotsGauge.Update(int64(t.slots)) 1767 1768 delete(t.locals, hash) 1769 delete(t.remotes, hash) 1770 } 1771 1772 // RemoteToLocals migrates the transactions belongs to the given locals to locals 1773 // set. The assumption is held the locals set is thread-safe to be used. 1774 func (t *txLookup) RemoteToLocals(locals *accountSet) int { 1775 t.lock.Lock() 1776 defer t.lock.Unlock() 1777 1778 var migrated int 1779 for hash, tx := range t.remotes { 1780 if locals.containsTx(tx) { 1781 t.locals[hash] = tx 1782 delete(t.remotes, hash) 1783 migrated += 1 1784 } 1785 } 1786 return migrated 1787 } 1788 1789 // RemotesBelowTip finds all remote transactions below the given tip threshold. 1790 func (t *txLookup) RemotesBelowTip(threshold *big.Int) types.Transactions { 1791 found := make(types.Transactions, 0, 128) 1792 t.Range(func(hash common.Hash, tx *types.Transaction, local bool) bool { 1793 if tx.GasTipCapIntCmp(threshold) < 0 { 1794 found = append(found, tx) 1795 } 1796 return true 1797 }, false, true) // Only iterate remotes 1798 return found 1799 } 1800 1801 // numSlots calculates the number of slots needed for a single transaction. 1802 func numSlots(tx *types.Transaction) int { 1803 return int((tx.Size() + txSlotSize - 1) / txSlotSize) 1804 }