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