github.com/ethereum/go-ethereum@v1.14.4-0.20240516095835-473ee8fc07a3/core/txpool/subpool.go (about) 1 // Copyright 2023 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package txpool 18 19 import ( 20 "math/big" 21 "time" 22 23 "github.com/ethereum/go-ethereum/common" 24 "github.com/ethereum/go-ethereum/core" 25 "github.com/ethereum/go-ethereum/core/types" 26 "github.com/ethereum/go-ethereum/event" 27 "github.com/holiman/uint256" 28 ) 29 30 // LazyTransaction contains a small subset of the transaction properties that is 31 // enough for the miner and other APIs to handle large batches of transactions; 32 // and supports pulling up the entire transaction when really needed. 33 type LazyTransaction struct { 34 Pool LazyResolver // Transaction resolver to pull the real transaction up 35 Hash common.Hash // Transaction hash to pull up if needed 36 Tx *types.Transaction // Transaction if already resolved 37 38 Time time.Time // Time when the transaction was first seen 39 GasFeeCap *uint256.Int // Maximum fee per gas the transaction may consume 40 GasTipCap *uint256.Int // Maximum miner tip per gas the transaction can pay 41 42 Gas uint64 // Amount of gas required by the transaction 43 BlobGas uint64 // Amount of blob gas required by the transaction 44 } 45 46 // Resolve retrieves the full transaction belonging to a lazy handle if it is still 47 // maintained by the transaction pool. 48 // 49 // Note, the method will *not* cache the retrieved transaction if the original 50 // pool has not cached it. The idea being, that if the tx was too big to insert 51 // originally, silently saving it will cause more trouble down the line (and 52 // indeed seems to have caused a memory bloat in the original implementation 53 // which did just that). 54 func (ltx *LazyTransaction) Resolve() *types.Transaction { 55 if ltx.Tx != nil { 56 return ltx.Tx 57 } 58 return ltx.Pool.Get(ltx.Hash) 59 } 60 61 // LazyResolver is a minimal interface needed for a transaction pool to satisfy 62 // resolving lazy transactions. It's mostly a helper to avoid the entire sub- 63 // pool being injected into the lazy transaction. 64 type LazyResolver interface { 65 // Get returns a transaction if it is contained in the pool, or nil otherwise. 66 Get(hash common.Hash) *types.Transaction 67 } 68 69 // AddressReserver is passed by the main transaction pool to subpools, so they 70 // may request (and relinquish) exclusive access to certain addresses. 71 type AddressReserver func(addr common.Address, reserve bool) error 72 73 // PendingFilter is a collection of filter rules to allow retrieving a subset 74 // of transactions for announcement or mining. 75 // 76 // Note, the entries here are not arbitrary useful filters, rather each one has 77 // a very specific call site in mind and each one can be evaluated very cheaply 78 // by the pool implementations. Only add new ones that satisfy those constraints. 79 type PendingFilter struct { 80 MinTip *uint256.Int // Minimum miner tip required to include a transaction 81 BaseFee *uint256.Int // Minimum 1559 basefee needed to include a transaction 82 BlobFee *uint256.Int // Minimum 4844 blobfee needed to include a blob transaction 83 84 OnlyPlainTxs bool // Return only plain EVM transactions (peer-join announces, block space filling) 85 OnlyBlobTxs bool // Return only blob transactions (block blob-space filling) 86 } 87 88 // SubPool represents a specialized transaction pool that lives on its own (e.g. 89 // blob pool). Since independent of how many specialized pools we have, they do 90 // need to be updated in lockstep and assemble into one coherent view for block 91 // production, this interface defines the common methods that allow the primary 92 // transaction pool to manage the subpools. 93 type SubPool interface { 94 // Filter is a selector used to decide whether a transaction would be added 95 // to this particular subpool. 96 Filter(tx *types.Transaction) bool 97 98 // Init sets the base parameters of the subpool, allowing it to load any saved 99 // transactions from disk and also permitting internal maintenance routines to 100 // start up. 101 // 102 // These should not be passed as a constructor argument - nor should the pools 103 // start by themselves - in order to keep multiple subpools in lockstep with 104 // one another. 105 Init(gasTip uint64, head *types.Header, reserve AddressReserver) error 106 107 // Close terminates any background processing threads and releases any held 108 // resources. 109 Close() error 110 111 // Reset retrieves the current state of the blockchain and ensures the content 112 // of the transaction pool is valid with regard to the chain state. 113 Reset(oldHead, newHead *types.Header) 114 115 // SetGasTip updates the minimum price required by the subpool for a new 116 // transaction, and drops all transactions below this threshold. 117 SetGasTip(tip *big.Int) 118 119 // Has returns an indicator whether subpool has a transaction cached with the 120 // given hash. 121 Has(hash common.Hash) bool 122 123 // Get returns a transaction if it is contained in the pool, or nil otherwise. 124 Get(hash common.Hash) *types.Transaction 125 126 // Add enqueues a batch of transactions into the pool if they are valid. Due 127 // to the large transaction churn, add may postpone fully integrating the tx 128 // to a later point to batch multiple ones together. 129 Add(txs []*types.Transaction, local bool, sync bool) []error 130 131 // Pending retrieves all currently processable transactions, grouped by origin 132 // account and sorted by nonce. 133 // 134 // The transactions can also be pre-filtered by the dynamic fee components to 135 // reduce allocations and load on downstream subsystems. 136 Pending(filter PendingFilter) map[common.Address][]*LazyTransaction 137 138 // SubscribeTransactions subscribes to new transaction events. The subscriber 139 // can decide whether to receive notifications only for newly seen transactions 140 // or also for reorged out ones. 141 SubscribeTransactions(ch chan<- core.NewTxsEvent, reorgs bool) event.Subscription 142 143 // Nonce returns the next nonce of an account, with all transactions executable 144 // by the pool already applied on top. 145 Nonce(addr common.Address) uint64 146 147 // Stats retrieves the current pool stats, namely the number of pending and the 148 // number of queued (non-executable) transactions. 149 Stats() (int, int) 150 151 // Content retrieves the data content of the transaction pool, returning all the 152 // pending as well as queued transactions, grouped by account and sorted by nonce. 153 Content() (map[common.Address][]*types.Transaction, map[common.Address][]*types.Transaction) 154 155 // ContentFrom retrieves the data content of the transaction pool, returning the 156 // pending as well as queued transactions of this address, grouped by nonce. 157 ContentFrom(addr common.Address) ([]*types.Transaction, []*types.Transaction) 158 159 // Locals retrieves the accounts currently considered local by the pool. 160 Locals() []common.Address 161 162 // Status returns the known status (unknown/pending/queued) of a transaction 163 // identified by their hashes. 164 Status(hash common.Hash) TxStatus 165 }