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