github.com/etherite/go-etherite@v0.0.0-20171015192807-5f4dd87b2f6e/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 "fmt" 22 "math" 23 "math/big" 24 "sort" 25 "sync" 26 "time" 27 28 "github.com/etherite/go-etherite/common" 29 "github.com/etherite/go-etherite/core/state" 30 "github.com/etherite/go-etherite/core/types" 31 "github.com/etherite/go-etherite/event" 32 "github.com/etherite/go-etherite/log" 33 "github.com/etherite/go-etherite/metrics" 34 "github.com/etherite/go-etherite/params" 35 "gopkg.in/karalabe/cookiejar.v2/collections/prque" 36 ) 37 38 const ( 39 // chainHeadChanSize is the size of channel listening to ChainHeadEvent. 40 chainHeadChanSize = 10 41 // rmTxChanSize is the size of channel listening to RemovedTransactionEvent. 42 rmTxChanSize = 10 43 ) 44 45 var ( 46 // ErrInvalidSender is returned if the transaction contains an invalid signature. 47 ErrInvalidSender = errors.New("invalid sender") 48 49 // ErrNonceTooLow is returned if the nonce of a transaction is lower than the 50 // one present in the local chain. 51 ErrNonceTooLow = errors.New("nonce too low") 52 53 // ErrUnderpriced is returned if a transaction's gas price is below the minimum 54 // configured for the transaction pool. 55 ErrUnderpriced = errors.New("transaction underpriced") 56 57 // ErrReplaceUnderpriced is returned if a transaction is attempted to be replaced 58 // with a different one without the required price bump. 59 ErrReplaceUnderpriced = errors.New("replacement transaction underpriced") 60 61 // ErrInsufficientFunds is returned if the total cost of executing a transaction 62 // is higher than the balance of the user's account. 63 ErrInsufficientFunds = errors.New("insufficient funds for gas * price + value") 64 65 // ErrIntrinsicGas is returned if the transaction is specified to use less gas 66 // than required to start the invocation. 67 ErrIntrinsicGas = errors.New("intrinsic gas too low") 68 69 // ErrGasLimit is returned if a transaction's requested gas limit exceeds the 70 // maximum allowance of the current block. 71 ErrGasLimit = errors.New("exceeds block gas limit") 72 73 // ErrNegativeValue is a sanity error to ensure noone is able to specify a 74 // transaction with a negative value. 75 ErrNegativeValue = errors.New("negative value") 76 77 // ErrOversizedData is returned if the input data of a transaction is greater 78 // than some meaningful limit a user might use. This is not a consensus error 79 // making the transaction invalid, rather a DOS protection. 80 ErrOversizedData = errors.New("oversized data") 81 ) 82 83 var ( 84 evictionInterval = time.Minute // Time interval to check for evictable transactions 85 statsReportInterval = 8 * time.Second // Time interval to report transaction pool stats 86 ) 87 88 var ( 89 // Metrics for the pending pool 90 pendingDiscardCounter = metrics.NewCounter("txpool/pending/discard") 91 pendingReplaceCounter = metrics.NewCounter("txpool/pending/replace") 92 pendingRateLimitCounter = metrics.NewCounter("txpool/pending/ratelimit") // Dropped due to rate limiting 93 pendingNofundsCounter = metrics.NewCounter("txpool/pending/nofunds") // Dropped due to out-of-funds 94 95 // Metrics for the queued pool 96 queuedDiscardCounter = metrics.NewCounter("txpool/queued/discard") 97 queuedReplaceCounter = metrics.NewCounter("txpool/queued/replace") 98 queuedRateLimitCounter = metrics.NewCounter("txpool/queued/ratelimit") // Dropped due to rate limiting 99 queuedNofundsCounter = metrics.NewCounter("txpool/queued/nofunds") // Dropped due to out-of-funds 100 101 // General tx metrics 102 invalidTxCounter = metrics.NewCounter("txpool/invalid") 103 underpricedTxCounter = metrics.NewCounter("txpool/underpriced") 104 ) 105 106 // blockChain provides the state of blockchain and current gas limit to do 107 // some pre checks in tx pool and event subscribers. 108 type blockChain interface { 109 CurrentBlock() *types.Block 110 GetBlock(hash common.Hash, number uint64) *types.Block 111 StateAt(root common.Hash) (*state.StateDB, error) 112 113 SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription 114 } 115 116 // TxPoolConfig are the configuration parameters of the transaction pool. 117 type TxPoolConfig struct { 118 NoLocals bool // Whether local transaction handling should be disabled 119 Journal string // Journal of local transactions to survive node restarts 120 Rejournal time.Duration // Time interval to regenerate the local transaction journal 121 122 PriceLimit uint64 // Minimum gas price to enforce for acceptance into the pool 123 PriceBump uint64 // Minimum price bump percentage to replace an already existing transaction (nonce) 124 125 AccountSlots uint64 // Minimum number of executable transaction slots guaranteed per account 126 GlobalSlots uint64 // Maximum number of executable transaction slots for all accounts 127 AccountQueue uint64 // Maximum number of non-executable transaction slots permitted per account 128 GlobalQueue uint64 // Maximum number of non-executable transaction slots for all accounts 129 130 Lifetime time.Duration // Maximum amount of time non-executable transaction are queued 131 } 132 133 // DefaultTxPoolConfig contains the default configurations for the transaction 134 // pool. 135 var DefaultTxPoolConfig = TxPoolConfig{ 136 Journal: "transactions.rlp", 137 Rejournal: time.Hour, 138 139 PriceLimit: 1, 140 PriceBump: 10, 141 142 AccountSlots: 16, 143 GlobalSlots: 4096, 144 AccountQueue: 64, 145 GlobalQueue: 1024, 146 147 Lifetime: 3 * time.Hour, 148 } 149 150 // sanitize checks the provided user configurations and changes anything that's 151 // unreasonable or unworkable. 152 func (config *TxPoolConfig) sanitize() TxPoolConfig { 153 conf := *config 154 if conf.Rejournal < time.Second { 155 log.Warn("Sanitizing invalid txpool journal time", "provided", conf.Rejournal, "updated", time.Second) 156 conf.Rejournal = time.Second 157 } 158 if conf.PriceLimit < 1 { 159 log.Warn("Sanitizing invalid txpool price limit", "provided", conf.PriceLimit, "updated", DefaultTxPoolConfig.PriceLimit) 160 conf.PriceLimit = DefaultTxPoolConfig.PriceLimit 161 } 162 if conf.PriceBump < 1 { 163 log.Warn("Sanitizing invalid txpool price bump", "provided", conf.PriceBump, "updated", DefaultTxPoolConfig.PriceBump) 164 conf.PriceBump = DefaultTxPoolConfig.PriceBump 165 } 166 return conf 167 } 168 169 // TxPool contains all currently known transactions. Transactions 170 // enter the pool when they are received from the network or submitted 171 // locally. They exit the pool when they are included in the blockchain. 172 // 173 // The pool separates processable transactions (which can be applied to the 174 // current state) and future transactions. Transactions move between those 175 // two states over time as they are received and processed. 176 type TxPool struct { 177 config TxPoolConfig 178 chainconfig *params.ChainConfig 179 chain blockChain 180 gasPrice *big.Int 181 txFeed event.Feed 182 scope event.SubscriptionScope 183 chainHeadCh chan ChainHeadEvent 184 chainHeadSub event.Subscription 185 signer types.Signer 186 mu sync.RWMutex 187 188 currentState *state.StateDB // Current state in the blockchain head 189 pendingState *state.ManagedState // Pending state tracking virtual nonces 190 currentMaxGas *big.Int // Current gas limit for transaction caps 191 192 locals *accountSet // Set of local transaction to exepmt from evicion rules 193 journal *txJournal // Journal of local transaction to back up to disk 194 195 pending map[common.Address]*txList // All currently processable transactions 196 queue map[common.Address]*txList // Queued but non-processable transactions 197 beats map[common.Address]time.Time // Last heartbeat from each known account 198 all map[common.Hash]*types.Transaction // All transactions to allow lookups 199 priced *txPricedList // All transactions sorted by price 200 201 wg sync.WaitGroup // for shutdown sync 202 203 homestead bool 204 } 205 206 // NewTxPool creates a new transaction pool to gather, sort and filter inbound 207 // trnsactions from the network. 208 func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain) *TxPool { 209 // Sanitize the input to ensure no vulnerable gas prices are set 210 config = (&config).sanitize() 211 212 // Create the transaction pool with its initial settings 213 pool := &TxPool{ 214 config: config, 215 chainconfig: chainconfig, 216 chain: chain, 217 signer: types.NewEIP155Signer(chainconfig.ChainId), 218 pending: make(map[common.Address]*txList), 219 queue: make(map[common.Address]*txList), 220 beats: make(map[common.Address]time.Time), 221 all: make(map[common.Hash]*types.Transaction), 222 chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize), 223 gasPrice: new(big.Int).SetUint64(config.PriceLimit), 224 } 225 pool.locals = newAccountSet(pool.signer) 226 pool.priced = newTxPricedList(&pool.all) 227 pool.reset(nil, chain.CurrentBlock().Header()) 228 229 // If local transactions and journaling is enabled, load from disk 230 if !config.NoLocals && config.Journal != "" { 231 pool.journal = newTxJournal(config.Journal) 232 233 if err := pool.journal.load(pool.AddLocal); err != nil { 234 log.Debug("Failed to load transaction journal", "err", err) 235 } 236 if err := pool.journal.rotate(pool.local()); err != nil { 237 log.Debug("Failed to rotate transaction journal", "err", err) 238 } 239 } 240 // Subscribe events from blockchain 241 pool.chainHeadSub = pool.chain.SubscribeChainHeadEvent(pool.chainHeadCh) 242 243 // Start the event loop and return 244 pool.wg.Add(1) 245 go pool.loop() 246 247 return pool 248 } 249 250 // loop is the transaction pool's main event loop, waiting for and reacting to 251 // outside blockchain events as well as for various reporting and transaction 252 // eviction events. 253 func (pool *TxPool) loop() { 254 defer pool.wg.Done() 255 256 // Start the stats reporting and transaction eviction tickers 257 var prevPending, prevQueued, prevStales int 258 259 report := time.NewTicker(statsReportInterval) 260 defer report.Stop() 261 262 evict := time.NewTicker(evictionInterval) 263 defer evict.Stop() 264 265 journal := time.NewTicker(pool.config.Rejournal) 266 defer journal.Stop() 267 268 // Track the previous head headers for transaction reorgs 269 head := pool.chain.CurrentBlock() 270 271 // Keep waiting for and reacting to the various events 272 for { 273 select { 274 // Handle ChainHeadEvent 275 case ev := <-pool.chainHeadCh: 276 if ev.Block != nil { 277 pool.mu.Lock() 278 if pool.chainconfig.IsHomestead(ev.Block.Number()) { 279 pool.homestead = true 280 } 281 pool.reset(head.Header(), ev.Block.Header()) 282 head = ev.Block 283 284 pool.mu.Unlock() 285 } 286 // Be unsubscribed due to system stopped 287 case <-pool.chainHeadSub.Err(): 288 return 289 290 // Handle stats reporting ticks 291 case <-report.C: 292 pool.mu.RLock() 293 pending, queued := pool.stats() 294 stales := pool.priced.stales 295 pool.mu.RUnlock() 296 297 if pending != prevPending || queued != prevQueued || stales != prevStales { 298 log.Debug("Transaction pool status report", "executable", pending, "queued", queued, "stales", stales) 299 prevPending, prevQueued, prevStales = pending, queued, stales 300 } 301 302 // Handle inactive account transaction eviction 303 case <-evict.C: 304 pool.mu.Lock() 305 for addr := range pool.queue { 306 // Skip local transactions from the eviction mechanism 307 if pool.locals.contains(addr) { 308 continue 309 } 310 // Any non-locals old enough should be removed 311 if time.Since(pool.beats[addr]) > pool.config.Lifetime { 312 for _, tx := range pool.queue[addr].Flatten() { 313 pool.removeTx(tx.Hash()) 314 } 315 } 316 } 317 pool.mu.Unlock() 318 319 // Handle local transaction journal rotation 320 case <-journal.C: 321 if pool.journal != nil { 322 pool.mu.Lock() 323 if err := pool.journal.rotate(pool.local()); err != nil { 324 log.Warn("Failed to rotate local tx journal", "err", err) 325 } 326 pool.mu.Unlock() 327 } 328 } 329 } 330 } 331 332 // lockedReset is a wrapper around reset to allow calling it in a thread safe 333 // manner. This method is only ever used in the tester! 334 func (pool *TxPool) lockedReset(oldHead, newHead *types.Header) { 335 pool.mu.Lock() 336 defer pool.mu.Unlock() 337 338 pool.reset(oldHead, newHead) 339 } 340 341 // reset retrieves the current state of the blockchain and ensures the content 342 // of the transaction pool is valid with regard to the chain state. 343 func (pool *TxPool) reset(oldHead, newHead *types.Header) { 344 // If we're reorging an old state, reinject all dropped transactions 345 var reinject types.Transactions 346 347 if oldHead != nil && oldHead.Hash() != newHead.ParentHash { 348 // If the reorg is too deep, avoid doing it (will happen during fast sync) 349 oldNum := oldHead.Number.Uint64() 350 newNum := newHead.Number.Uint64() 351 352 if depth := uint64(math.Abs(float64(oldNum) - float64(newNum))); depth > 64 { 353 log.Warn("Skipping deep transaction reorg", "depth", depth) 354 } else { 355 // Reorg seems shallow enough to pull in all transactions into memory 356 var discarded, included types.Transactions 357 358 var ( 359 rem = pool.chain.GetBlock(oldHead.Hash(), oldHead.Number.Uint64()) 360 add = pool.chain.GetBlock(newHead.Hash(), newHead.Number.Uint64()) 361 ) 362 for rem.NumberU64() > add.NumberU64() { 363 discarded = append(discarded, rem.Transactions()...) 364 if rem = pool.chain.GetBlock(rem.ParentHash(), rem.NumberU64()-1); rem == nil { 365 log.Error("Unrooted old chain seen by tx pool", "block", oldHead.Number, "hash", oldHead.Hash()) 366 return 367 } 368 } 369 for add.NumberU64() > rem.NumberU64() { 370 included = append(included, add.Transactions()...) 371 if add = pool.chain.GetBlock(add.ParentHash(), add.NumberU64()-1); add == nil { 372 log.Error("Unrooted new chain seen by tx pool", "block", newHead.Number, "hash", newHead.Hash()) 373 return 374 } 375 } 376 for rem.Hash() != add.Hash() { 377 discarded = append(discarded, rem.Transactions()...) 378 if rem = pool.chain.GetBlock(rem.ParentHash(), rem.NumberU64()-1); rem == nil { 379 log.Error("Unrooted old chain seen by tx pool", "block", oldHead.Number, "hash", oldHead.Hash()) 380 return 381 } 382 included = append(included, add.Transactions()...) 383 if add = pool.chain.GetBlock(add.ParentHash(), add.NumberU64()-1); add == nil { 384 log.Error("Unrooted new chain seen by tx pool", "block", newHead.Number, "hash", newHead.Hash()) 385 return 386 } 387 } 388 reinject = types.TxDifference(discarded, included) 389 } 390 } 391 // Initialize the internal state to the current head 392 if newHead == nil { 393 newHead = pool.chain.CurrentBlock().Header() // Special case during testing 394 } 395 statedb, err := pool.chain.StateAt(newHead.Root) 396 if err != nil { 397 log.Error("Failed to reset txpool state", "err", err) 398 return 399 } 400 pool.currentState = statedb 401 pool.pendingState = state.ManageState(statedb) 402 pool.currentMaxGas = newHead.GasLimit 403 404 // Inject any transactions discarded due to reorgs 405 log.Debug("Reinjecting stale transactions", "count", len(reinject)) 406 pool.addTxsLocked(reinject, false) 407 408 // validate the pool of pending transactions, this will remove 409 // any transactions that have been included in the block or 410 // have been invalidated because of another transaction (e.g. 411 // higher gas price) 412 pool.demoteUnexecutables() 413 414 // Update all accounts to the latest known pending nonce 415 for addr, list := range pool.pending { 416 txs := list.Flatten() // Heavy but will be cached and is needed by the miner anyway 417 pool.pendingState.SetNonce(addr, txs[len(txs)-1].Nonce()+1) 418 } 419 // Check the queue and move transactions over to the pending if possible 420 // or remove those that have become invalid 421 pool.promoteExecutables(nil) 422 } 423 424 // Stop terminates the transaction pool. 425 func (pool *TxPool) Stop() { 426 // Unsubscribe all subscriptions registered from txpool 427 pool.scope.Close() 428 429 // Unsubscribe subscriptions registered from blockchain 430 pool.chainHeadSub.Unsubscribe() 431 pool.wg.Wait() 432 433 if pool.journal != nil { 434 pool.journal.close() 435 } 436 log.Info("Transaction pool stopped") 437 } 438 439 // SubscribeTxPreEvent registers a subscription of TxPreEvent and 440 // starts sending event to the given channel. 441 func (pool *TxPool) SubscribeTxPreEvent(ch chan<- TxPreEvent) event.Subscription { 442 return pool.scope.Track(pool.txFeed.Subscribe(ch)) 443 } 444 445 // GasPrice returns the current gas price enforced by the transaction pool. 446 func (pool *TxPool) GasPrice() *big.Int { 447 pool.mu.RLock() 448 defer pool.mu.RUnlock() 449 450 return new(big.Int).Set(pool.gasPrice) 451 } 452 453 // SetGasPrice updates the minimum price required by the transaction pool for a 454 // new transaction, and drops all transactions below this threshold. 455 func (pool *TxPool) SetGasPrice(price *big.Int) { 456 pool.mu.Lock() 457 defer pool.mu.Unlock() 458 459 pool.gasPrice = price 460 for _, tx := range pool.priced.Cap(price, pool.locals) { 461 pool.removeTx(tx.Hash()) 462 } 463 log.Info("Transaction pool price threshold updated", "price", price) 464 } 465 466 // State returns the virtual managed state of the transaction pool. 467 func (pool *TxPool) State() *state.ManagedState { 468 pool.mu.RLock() 469 defer pool.mu.RUnlock() 470 471 return pool.pendingState 472 } 473 474 // Stats retrieves the current pool stats, namely the number of pending and the 475 // number of queued (non-executable) transactions. 476 func (pool *TxPool) Stats() (int, int) { 477 pool.mu.RLock() 478 defer pool.mu.RUnlock() 479 480 return pool.stats() 481 } 482 483 // stats retrieves the current pool stats, namely the number of pending and the 484 // number of queued (non-executable) transactions. 485 func (pool *TxPool) stats() (int, int) { 486 pending := 0 487 for _, list := range pool.pending { 488 pending += list.Len() 489 } 490 queued := 0 491 for _, list := range pool.queue { 492 queued += list.Len() 493 } 494 return pending, queued 495 } 496 497 // Content retrieves the data content of the transaction pool, returning all the 498 // pending as well as queued transactions, grouped by account and sorted by nonce. 499 func (pool *TxPool) Content() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) { 500 pool.mu.Lock() 501 defer pool.mu.Unlock() 502 503 pending := make(map[common.Address]types.Transactions) 504 for addr, list := range pool.pending { 505 pending[addr] = list.Flatten() 506 } 507 queued := make(map[common.Address]types.Transactions) 508 for addr, list := range pool.queue { 509 queued[addr] = list.Flatten() 510 } 511 return pending, queued 512 } 513 514 // Pending retrieves all currently processable transactions, groupped 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 func (pool *TxPool) Pending() (map[common.Address]types.Transactions, error) { 518 pool.mu.Lock() 519 defer pool.mu.Unlock() 520 521 pending := make(map[common.Address]types.Transactions) 522 for addr, list := range pool.pending { 523 pending[addr] = list.Flatten() 524 } 525 return pending, nil 526 } 527 528 // local retrieves all currently known local transactions, groupped by origin 529 // account and sorted by nonce. The returned transaction set is a copy and can be 530 // freely modified by calling code. 531 func (pool *TxPool) local() map[common.Address]types.Transactions { 532 txs := make(map[common.Address]types.Transactions) 533 for addr := range pool.locals.accounts { 534 if pending := pool.pending[addr]; pending != nil { 535 txs[addr] = append(txs[addr], pending.Flatten()...) 536 } 537 if queued := pool.queue[addr]; queued != nil { 538 txs[addr] = append(txs[addr], queued.Flatten()...) 539 } 540 } 541 return txs 542 } 543 544 // validateTx checks whether a transaction is valid according to the consensus 545 // rules and adheres to some heuristic limits of the local node (price and size). 546 func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { 547 // Heuristic limit, reject transactions over 32KB to prevent DOS attacks 548 if tx.Size() > 32*1024 { 549 return ErrOversizedData 550 } 551 // Transactions can't be negative. This may never happen using RLP decoded 552 // transactions but may occur if you create a transaction using the RPC. 553 if tx.Value().Sign() < 0 { 554 return ErrNegativeValue 555 } 556 // Ensure the transaction doesn't exceed the current block limit gas. 557 if pool.currentMaxGas.Cmp(tx.Gas()) < 0 { 558 return ErrGasLimit 559 } 560 // Make sure the transaction is signed properly 561 from, err := types.Sender(pool.signer, tx) 562 if err != nil { 563 return ErrInvalidSender 564 } 565 // Drop non-local transactions under our own minimal accepted gas price 566 local = local || pool.locals.contains(from) // account may be local even if the transaction arrived from the network 567 if !local && pool.gasPrice.Cmp(tx.GasPrice()) > 0 { 568 return ErrUnderpriced 569 } 570 // Ensure the transaction adheres to nonce ordering 571 if pool.currentState.GetNonce(from) > tx.Nonce() { 572 return ErrNonceTooLow 573 } 574 // Transactor should have enough funds to cover the costs 575 // cost == V + GP * GL 576 if pool.currentState.GetBalance(from).Cmp(tx.Cost()) < 0 { 577 return ErrInsufficientFunds 578 } 579 intrGas := IntrinsicGas(tx.Data(), tx.To() == nil, pool.homestead) 580 if tx.Gas().Cmp(intrGas) < 0 { 581 return ErrIntrinsicGas 582 } 583 return nil 584 } 585 586 // add validates a transaction and inserts it into the non-executable queue for 587 // later pending promotion and execution. If the transaction is a replacement for 588 // an already pending or queued one, it overwrites the previous and returns this 589 // so outer code doesn't uselessly call promote. 590 // 591 // If a newly added transaction is marked as local, its sending account will be 592 // whitelisted, preventing any associated transaction from being dropped out of 593 // the pool due to pricing constraints. 594 func (pool *TxPool) add(tx *types.Transaction, local bool) (bool, error) { 595 // If the transaction is already known, discard it 596 hash := tx.Hash() 597 if pool.all[hash] != nil { 598 log.Trace("Discarding already known transaction", "hash", hash) 599 return false, fmt.Errorf("known transaction: %x", hash) 600 } 601 // If the transaction fails basic validation, discard it 602 if err := pool.validateTx(tx, local); err != nil { 603 log.Trace("Discarding invalid transaction", "hash", hash, "err", err) 604 invalidTxCounter.Inc(1) 605 return false, err 606 } 607 // If the transaction pool is full, discard underpriced transactions 608 if uint64(len(pool.all)) >= pool.config.GlobalSlots+pool.config.GlobalQueue { 609 // If the new transaction is underpriced, don't accept it 610 if pool.priced.Underpriced(tx, pool.locals) { 611 log.Trace("Discarding underpriced transaction", "hash", hash, "price", tx.GasPrice()) 612 underpricedTxCounter.Inc(1) 613 return false, ErrUnderpriced 614 } 615 // New transaction is better than our worse ones, make room for it 616 drop := pool.priced.Discard(len(pool.all)-int(pool.config.GlobalSlots+pool.config.GlobalQueue-1), pool.locals) 617 for _, tx := range drop { 618 log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "price", tx.GasPrice()) 619 underpricedTxCounter.Inc(1) 620 pool.removeTx(tx.Hash()) 621 } 622 } 623 // If the transaction is replacing an already pending one, do directly 624 from, _ := types.Sender(pool.signer, tx) // already validated 625 if list := pool.pending[from]; list != nil && list.Overlaps(tx) { 626 // Nonce already pending, check if required price bump is met 627 inserted, old := list.Add(tx, pool.config.PriceBump) 628 if !inserted { 629 pendingDiscardCounter.Inc(1) 630 return false, ErrReplaceUnderpriced 631 } 632 // New transaction is better, replace old one 633 if old != nil { 634 delete(pool.all, old.Hash()) 635 pool.priced.Removed() 636 pendingReplaceCounter.Inc(1) 637 } 638 pool.all[tx.Hash()] = tx 639 pool.priced.Put(tx) 640 pool.journalTx(from, tx) 641 642 log.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To()) 643 return old != nil, nil 644 } 645 // New transaction isn't replacing a pending one, push into queue 646 replace, err := pool.enqueueTx(hash, tx) 647 if err != nil { 648 return false, err 649 } 650 // Mark local addresses and journal local transactions 651 if local { 652 pool.locals.add(from) 653 } 654 pool.journalTx(from, tx) 655 656 log.Trace("Pooled new future transaction", "hash", hash, "from", from, "to", tx.To()) 657 return replace, nil 658 } 659 660 // enqueueTx inserts a new transaction into the non-executable transaction queue. 661 // 662 // Note, this method assumes the pool lock is held! 663 func (pool *TxPool) enqueueTx(hash common.Hash, tx *types.Transaction) (bool, error) { 664 // Try to insert the transaction into the future queue 665 from, _ := types.Sender(pool.signer, tx) // already validated 666 if pool.queue[from] == nil { 667 pool.queue[from] = newTxList(false) 668 } 669 inserted, old := pool.queue[from].Add(tx, pool.config.PriceBump) 670 if !inserted { 671 // An older transaction was better, discard this 672 queuedDiscardCounter.Inc(1) 673 return false, ErrReplaceUnderpriced 674 } 675 // Discard any previous transaction and mark this 676 if old != nil { 677 delete(pool.all, old.Hash()) 678 pool.priced.Removed() 679 queuedReplaceCounter.Inc(1) 680 } 681 pool.all[hash] = tx 682 pool.priced.Put(tx) 683 return old != nil, nil 684 } 685 686 // journalTx adds the specified transaction to the local disk journal if it is 687 // deemed to have been sent from a local account. 688 func (pool *TxPool) journalTx(from common.Address, tx *types.Transaction) { 689 // Only journal if it's enabled and the transaction is local 690 if pool.journal == nil || !pool.locals.contains(from) { 691 return 692 } 693 if err := pool.journal.insert(tx); err != nil { 694 log.Warn("Failed to journal local transaction", "err", err) 695 } 696 } 697 698 // promoteTx adds a transaction to the pending (processable) list of transactions. 699 // 700 // Note, this method assumes the pool lock is held! 701 func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.Transaction) { 702 // Try to insert the transaction into the pending queue 703 if pool.pending[addr] == nil { 704 pool.pending[addr] = newTxList(true) 705 } 706 list := pool.pending[addr] 707 708 inserted, old := list.Add(tx, pool.config.PriceBump) 709 if !inserted { 710 // An older transaction was better, discard this 711 delete(pool.all, hash) 712 pool.priced.Removed() 713 714 pendingDiscardCounter.Inc(1) 715 return 716 } 717 // Otherwise discard any previous transaction and mark this 718 if old != nil { 719 delete(pool.all, old.Hash()) 720 pool.priced.Removed() 721 722 pendingReplaceCounter.Inc(1) 723 } 724 // Failsafe to work around direct pending inserts (tests) 725 if pool.all[hash] == nil { 726 pool.all[hash] = tx 727 pool.priced.Put(tx) 728 } 729 // Set the potentially new pending nonce and notify any subsystems of the new tx 730 pool.beats[addr] = time.Now() 731 pool.pendingState.SetNonce(addr, tx.Nonce()+1) 732 go pool.txFeed.Send(TxPreEvent{tx}) 733 } 734 735 // AddLocal enqueues a single transaction into the pool if it is valid, marking 736 // the sender as a local one in the mean time, ensuring it goes around the local 737 // pricing constraints. 738 func (pool *TxPool) AddLocal(tx *types.Transaction) error { 739 return pool.addTx(tx, !pool.config.NoLocals) 740 } 741 742 // AddRemote enqueues a single transaction into the pool if it is valid. If the 743 // sender is not among the locally tracked ones, full pricing constraints will 744 // apply. 745 func (pool *TxPool) AddRemote(tx *types.Transaction) error { 746 return pool.addTx(tx, false) 747 } 748 749 // AddLocals enqueues a batch of transactions into the pool if they are valid, 750 // marking the senders as a local ones in the mean time, ensuring they go around 751 // the local pricing constraints. 752 func (pool *TxPool) AddLocals(txs []*types.Transaction) error { 753 return pool.addTxs(txs, !pool.config.NoLocals) 754 } 755 756 // AddRemotes enqueues a batch of transactions into the pool if they are valid. 757 // If the senders are not among the locally tracked ones, full pricing constraints 758 // will apply. 759 func (pool *TxPool) AddRemotes(txs []*types.Transaction) error { 760 return pool.addTxs(txs, false) 761 } 762 763 // addTx enqueues a single transaction into the pool if it is valid. 764 func (pool *TxPool) addTx(tx *types.Transaction, local bool) error { 765 pool.mu.Lock() 766 defer pool.mu.Unlock() 767 768 // Try to inject the transaction and update any state 769 replace, err := pool.add(tx, local) 770 if err != nil { 771 return err 772 } 773 // If we added a new transaction, run promotion checks and return 774 if !replace { 775 from, _ := types.Sender(pool.signer, tx) // already validated 776 pool.promoteExecutables([]common.Address{from}) 777 } 778 return nil 779 } 780 781 // addTxs attempts to queue a batch of transactions if they are valid. 782 func (pool *TxPool) addTxs(txs []*types.Transaction, local bool) error { 783 pool.mu.Lock() 784 defer pool.mu.Unlock() 785 786 return pool.addTxsLocked(txs, local) 787 } 788 789 // addTxsLocked attempts to queue a batch of transactions if they are valid, 790 // whilst assuming the transaction pool lock is already held. 791 func (pool *TxPool) addTxsLocked(txs []*types.Transaction, local bool) error { 792 // Add the batch of transaction, tracking the accepted ones 793 dirty := make(map[common.Address]struct{}) 794 for _, tx := range txs { 795 if replace, err := pool.add(tx, local); err == nil { 796 if !replace { 797 from, _ := types.Sender(pool.signer, tx) // already validated 798 dirty[from] = struct{}{} 799 } 800 } 801 } 802 // Only reprocess the internal state if something was actually added 803 if len(dirty) > 0 { 804 addrs := make([]common.Address, 0, len(dirty)) 805 for addr, _ := range dirty { 806 addrs = append(addrs, addr) 807 } 808 pool.promoteExecutables(addrs) 809 } 810 return nil 811 } 812 813 // Get returns a transaction if it is contained in the pool 814 // and nil otherwise. 815 func (pool *TxPool) Get(hash common.Hash) *types.Transaction { 816 pool.mu.RLock() 817 defer pool.mu.RUnlock() 818 819 return pool.all[hash] 820 } 821 822 // removeTx removes a single transaction from the queue, moving all subsequent 823 // transactions back to the future queue. 824 func (pool *TxPool) removeTx(hash common.Hash) { 825 // Fetch the transaction we wish to delete 826 tx, ok := pool.all[hash] 827 if !ok { 828 return 829 } 830 addr, _ := types.Sender(pool.signer, tx) // already validated during insertion 831 832 // Remove it from the list of known transactions 833 delete(pool.all, hash) 834 pool.priced.Removed() 835 836 // Remove the transaction from the pending lists and reset the account nonce 837 if pending := pool.pending[addr]; pending != nil { 838 if removed, invalids := pending.Remove(tx); removed { 839 // If no more transactions are left, remove the list 840 if pending.Empty() { 841 delete(pool.pending, addr) 842 delete(pool.beats, addr) 843 } else { 844 // Otherwise postpone any invalidated transactions 845 for _, tx := range invalids { 846 pool.enqueueTx(tx.Hash(), tx) 847 } 848 } 849 // Update the account nonce if needed 850 if nonce := tx.Nonce(); pool.pendingState.GetNonce(addr) > nonce { 851 pool.pendingState.SetNonce(addr, nonce) 852 } 853 return 854 } 855 } 856 // Transaction is in the future queue 857 if future := pool.queue[addr]; future != nil { 858 future.Remove(tx) 859 if future.Empty() { 860 delete(pool.queue, addr) 861 } 862 } 863 } 864 865 // promoteExecutables moves transactions that have become processable from the 866 // future queue to the set of pending transactions. During this process, all 867 // invalidated transactions (low nonce, low balance) are deleted. 868 func (pool *TxPool) promoteExecutables(accounts []common.Address) { 869 // Gather all the accounts potentially needing updates 870 if accounts == nil { 871 accounts = make([]common.Address, 0, len(pool.queue)) 872 for addr, _ := range pool.queue { 873 accounts = append(accounts, addr) 874 } 875 } 876 // Iterate over all accounts and promote any executable transactions 877 for _, addr := range accounts { 878 list := pool.queue[addr] 879 if list == nil { 880 continue // Just in case someone calls with a non existing account 881 } 882 // Drop all transactions that are deemed too old (low nonce) 883 for _, tx := range list.Forward(pool.currentState.GetNonce(addr)) { 884 hash := tx.Hash() 885 log.Trace("Removed old queued transaction", "hash", hash) 886 delete(pool.all, hash) 887 pool.priced.Removed() 888 } 889 // Drop all transactions that are too costly (low balance or out of gas) 890 drops, _ := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas) 891 for _, tx := range drops { 892 hash := tx.Hash() 893 log.Trace("Removed unpayable queued transaction", "hash", hash) 894 delete(pool.all, hash) 895 pool.priced.Removed() 896 queuedNofundsCounter.Inc(1) 897 } 898 // Gather all executable transactions and promote them 899 for _, tx := range list.Ready(pool.pendingState.GetNonce(addr)) { 900 hash := tx.Hash() 901 log.Trace("Promoting queued transaction", "hash", hash) 902 pool.promoteTx(addr, hash, tx) 903 } 904 // Drop all transactions over the allowed limit 905 if !pool.locals.contains(addr) { 906 for _, tx := range list.Cap(int(pool.config.AccountQueue)) { 907 hash := tx.Hash() 908 delete(pool.all, hash) 909 pool.priced.Removed() 910 queuedRateLimitCounter.Inc(1) 911 log.Trace("Removed cap-exceeding queued transaction", "hash", hash) 912 } 913 } 914 // Delete the entire queue entry if it became empty. 915 if list.Empty() { 916 delete(pool.queue, addr) 917 } 918 } 919 // If the pending limit is overflown, start equalizing allowances 920 pending := uint64(0) 921 for _, list := range pool.pending { 922 pending += uint64(list.Len()) 923 } 924 if pending > pool.config.GlobalSlots { 925 pendingBeforeCap := pending 926 // Assemble a spam order to penalize large transactors first 927 spammers := prque.New() 928 for addr, list := range pool.pending { 929 // Only evict transactions from high rollers 930 if !pool.locals.contains(addr) && uint64(list.Len()) > pool.config.AccountSlots { 931 spammers.Push(addr, float32(list.Len())) 932 } 933 } 934 // Gradually drop transactions from offenders 935 offenders := []common.Address{} 936 for pending > pool.config.GlobalSlots && !spammers.Empty() { 937 // Retrieve the next offender if not local address 938 offender, _ := spammers.Pop() 939 offenders = append(offenders, offender.(common.Address)) 940 941 // Equalize balances until all the same or below threshold 942 if len(offenders) > 1 { 943 // Calculate the equalization threshold for all current offenders 944 threshold := pool.pending[offender.(common.Address)].Len() 945 946 // Iteratively reduce all offenders until below limit or threshold reached 947 for pending > pool.config.GlobalSlots && pool.pending[offenders[len(offenders)-2]].Len() > threshold { 948 for i := 0; i < len(offenders)-1; i++ { 949 list := pool.pending[offenders[i]] 950 for _, tx := range list.Cap(list.Len() - 1) { 951 // Drop the transaction from the global pools too 952 hash := tx.Hash() 953 delete(pool.all, hash) 954 pool.priced.Removed() 955 956 // Update the account nonce to the dropped transaction 957 if nonce := tx.Nonce(); pool.pendingState.GetNonce(offenders[i]) > nonce { 958 pool.pendingState.SetNonce(offenders[i], nonce) 959 } 960 log.Trace("Removed fairness-exceeding pending transaction", "hash", hash) 961 } 962 pending-- 963 } 964 } 965 } 966 } 967 // If still above threshold, reduce to limit or min allowance 968 if pending > pool.config.GlobalSlots && len(offenders) > 0 { 969 for pending > pool.config.GlobalSlots && uint64(pool.pending[offenders[len(offenders)-1]].Len()) > pool.config.AccountSlots { 970 for _, addr := range offenders { 971 list := pool.pending[addr] 972 for _, tx := range list.Cap(list.Len() - 1) { 973 // Drop the transaction from the global pools too 974 hash := tx.Hash() 975 delete(pool.all, hash) 976 pool.priced.Removed() 977 978 // Update the account nonce to the dropped transaction 979 if nonce := tx.Nonce(); pool.pendingState.GetNonce(addr) > nonce { 980 pool.pendingState.SetNonce(addr, nonce) 981 } 982 log.Trace("Removed fairness-exceeding pending transaction", "hash", hash) 983 } 984 pending-- 985 } 986 } 987 } 988 pendingRateLimitCounter.Inc(int64(pendingBeforeCap - pending)) 989 } 990 // If we've queued more transactions than the hard limit, drop oldest ones 991 queued := uint64(0) 992 for _, list := range pool.queue { 993 queued += uint64(list.Len()) 994 } 995 if queued > pool.config.GlobalQueue { 996 // Sort all accounts with queued transactions by heartbeat 997 addresses := make(addresssByHeartbeat, 0, len(pool.queue)) 998 for addr := range pool.queue { 999 if !pool.locals.contains(addr) { // don't drop locals 1000 addresses = append(addresses, addressByHeartbeat{addr, pool.beats[addr]}) 1001 } 1002 } 1003 sort.Sort(addresses) 1004 1005 // Drop transactions until the total is below the limit or only locals remain 1006 for drop := queued - pool.config.GlobalQueue; drop > 0 && len(addresses) > 0; { 1007 addr := addresses[len(addresses)-1] 1008 list := pool.queue[addr.address] 1009 1010 addresses = addresses[:len(addresses)-1] 1011 1012 // Drop all transactions if they are less than the overflow 1013 if size := uint64(list.Len()); size <= drop { 1014 for _, tx := range list.Flatten() { 1015 pool.removeTx(tx.Hash()) 1016 } 1017 drop -= size 1018 queuedRateLimitCounter.Inc(int64(size)) 1019 continue 1020 } 1021 // Otherwise drop only last few transactions 1022 txs := list.Flatten() 1023 for i := len(txs) - 1; i >= 0 && drop > 0; i-- { 1024 pool.removeTx(txs[i].Hash()) 1025 drop-- 1026 queuedRateLimitCounter.Inc(1) 1027 } 1028 } 1029 } 1030 } 1031 1032 // demoteUnexecutables removes invalid and processed transactions from the pools 1033 // executable/pending queue and any subsequent transactions that become unexecutable 1034 // are moved back into the future queue. 1035 func (pool *TxPool) demoteUnexecutables() { 1036 // Iterate over all accounts and demote any non-executable transactions 1037 for addr, list := range pool.pending { 1038 nonce := pool.currentState.GetNonce(addr) 1039 1040 // Drop all transactions that are deemed too old (low nonce) 1041 for _, tx := range list.Forward(nonce) { 1042 hash := tx.Hash() 1043 log.Trace("Removed old pending transaction", "hash", hash) 1044 delete(pool.all, hash) 1045 pool.priced.Removed() 1046 } 1047 // Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later 1048 drops, invalids := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas) 1049 for _, tx := range drops { 1050 hash := tx.Hash() 1051 log.Trace("Removed unpayable pending transaction", "hash", hash) 1052 delete(pool.all, hash) 1053 pool.priced.Removed() 1054 pendingNofundsCounter.Inc(1) 1055 } 1056 for _, tx := range invalids { 1057 hash := tx.Hash() 1058 log.Trace("Demoting pending transaction", "hash", hash) 1059 pool.enqueueTx(hash, tx) 1060 } 1061 // If there's a gap in front, warn (should never happen) and postpone all transactions 1062 if list.Len() > 0 && list.txs.Get(nonce) == nil { 1063 for _, tx := range list.Cap(0) { 1064 hash := tx.Hash() 1065 log.Error("Demoting invalidated transaction", "hash", hash) 1066 pool.enqueueTx(hash, tx) 1067 } 1068 } 1069 // Delete the entire queue entry if it became empty. 1070 if list.Empty() { 1071 delete(pool.pending, addr) 1072 delete(pool.beats, addr) 1073 } 1074 } 1075 } 1076 1077 // addressByHeartbeat is an account address tagged with its last activity timestamp. 1078 type addressByHeartbeat struct { 1079 address common.Address 1080 heartbeat time.Time 1081 } 1082 1083 type addresssByHeartbeat []addressByHeartbeat 1084 1085 func (a addresssByHeartbeat) Len() int { return len(a) } 1086 func (a addresssByHeartbeat) Less(i, j int) bool { return a[i].heartbeat.Before(a[j].heartbeat) } 1087 func (a addresssByHeartbeat) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 1088 1089 // accountSet is simply a set of addresses to check for existence, and a signer 1090 // capable of deriving addresses from transactions. 1091 type accountSet struct { 1092 accounts map[common.Address]struct{} 1093 signer types.Signer 1094 } 1095 1096 // newAccountSet creates a new address set with an associated signer for sender 1097 // derivations. 1098 func newAccountSet(signer types.Signer) *accountSet { 1099 return &accountSet{ 1100 accounts: make(map[common.Address]struct{}), 1101 signer: signer, 1102 } 1103 } 1104 1105 // contains checks if a given address is contained within the set. 1106 func (as *accountSet) contains(addr common.Address) bool { 1107 _, exist := as.accounts[addr] 1108 return exist 1109 } 1110 1111 // containsTx checks if the sender of a given tx is within the set. If the sender 1112 // cannot be derived, this method returns false. 1113 func (as *accountSet) containsTx(tx *types.Transaction) bool { 1114 if addr, err := types.Sender(as.signer, tx); err == nil { 1115 return as.contains(addr) 1116 } 1117 return false 1118 } 1119 1120 // add inserts a new address into the set to track. 1121 func (as *accountSet) add(addr common.Address) { 1122 as.accounts[addr] = struct{}{} 1123 }