mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 14:16:44 +00:00
core, miner: polish
This commit is contained in:
parent
af879b0ebf
commit
e2420abbc3
8 changed files with 42 additions and 64 deletions
|
|
@ -85,7 +85,7 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
|
||||||
var blobs int
|
var blobs int
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
if v.config.IsOsaka(block.Number(), block.Time()) && tx.Gas() > params.MaxTxGas {
|
if v.config.IsOsaka(block.Number(), block.Time()) && tx.Gas() > params.MaxTxGas {
|
||||||
return fmt.Errorf("transaction exceeds maximum allowed gas limit (has %d gas)", tx.Gas())
|
return fmt.Errorf("%w (cap: %d, tx: %d)", ErrGasLimitTooHigh, params.MaxTxGas, tx.Gas())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count the number of blobs to validate against the header's blobGasUsed
|
// Count the number of blobs to validate against the header's blobGasUsed
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,9 @@ var (
|
||||||
// Message validation errors:
|
// Message validation errors:
|
||||||
ErrEmptyAuthList = errors.New("EIP-7702 transaction with empty auth list")
|
ErrEmptyAuthList = errors.New("EIP-7702 transaction with empty auth list")
|
||||||
ErrSetCodeTxCreate = errors.New("EIP-7702 transaction cannot be used to create contract")
|
ErrSetCodeTxCreate = errors.New("EIP-7702 transaction cannot be used to create contract")
|
||||||
|
|
||||||
|
// -- EIP-7825 errors --
|
||||||
|
ErrGasLimitTooHigh = errors.New("transaction gas limit too high")
|
||||||
)
|
)
|
||||||
|
|
||||||
// EIP-7702 state transition errors.
|
// EIP-7702 state transition errors.
|
||||||
|
|
|
||||||
|
|
@ -1638,6 +1638,11 @@ func (p *BlobPool) Pending(filter txpool.PendingFilter) map[common.Address][]*tx
|
||||||
break // blobfee too low, cannot be included, discard rest of txs from the account
|
break // blobfee too low, cannot be included, discard rest of txs from the account
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if filter.GasLimitCap != 0 {
|
||||||
|
if tx.execGas > filter.GasLimitCap {
|
||||||
|
break // execution gas limit is too high
|
||||||
|
}
|
||||||
|
}
|
||||||
// Transaction was accepted according to the filter, append to the pending list
|
// Transaction was accepted according to the filter, append to the pending list
|
||||||
lazies = append(lazies, &txpool.LazyTransaction{
|
lazies = append(lazies, &txpool.LazyTransaction{
|
||||||
Pool: p,
|
Pool: p,
|
||||||
|
|
|
||||||
|
|
@ -531,13 +531,21 @@ func (pool *LegacyPool) Pending(filter txpool.PendingFilter) map[common.Address]
|
||||||
txs := list.Flatten()
|
txs := list.Flatten()
|
||||||
|
|
||||||
// If the miner requests tip enforcement, cap the lists now
|
// If the miner requests tip enforcement, cap the lists now
|
||||||
if minTipBig != nil {
|
if minTipBig != nil || filter.GasLimitCap != 0 {
|
||||||
for i, tx := range txs {
|
for i, tx := range txs {
|
||||||
|
if minTipBig != nil {
|
||||||
if tx.EffectiveGasTipIntCmp(minTipBig, baseFeeBig) < 0 {
|
if tx.EffectiveGasTipIntCmp(minTipBig, baseFeeBig) < 0 {
|
||||||
txs = txs[:i]
|
txs = txs[:i]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if filter.GasLimitCap != 0 {
|
||||||
|
if tx.Gas() > filter.GasLimitCap {
|
||||||
|
txs = txs[:i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if len(txs) > 0 {
|
if len(txs) > 0 {
|
||||||
lazies := make([]*txpool.LazyTransaction, len(txs))
|
lazies := make([]*txpool.LazyTransaction, len(txs))
|
||||||
|
|
@ -1263,16 +1271,17 @@ func (pool *LegacyPool) runReorg(done chan struct{}, reset *txpoolResetRequest,
|
||||||
pool.mu.Lock()
|
pool.mu.Lock()
|
||||||
if reset != nil {
|
if reset != nil {
|
||||||
if reset.newHead != nil && reset.oldHead != nil {
|
if reset.newHead != nil && reset.oldHead != nil {
|
||||||
|
// Discard the transactions with the gas limit higher than the cap.
|
||||||
if pool.chainconfig.IsOsaka(reset.newHead.Number, reset.newHead.Time) && !pool.chainconfig.IsOsaka(reset.oldHead.Number, reset.oldHead.Time) {
|
if pool.chainconfig.IsOsaka(reset.newHead.Number, reset.newHead.Time) && !pool.chainconfig.IsOsaka(reset.oldHead.Number, reset.oldHead.Time) {
|
||||||
var removeHashes []common.Hash
|
var hashes []common.Hash
|
||||||
pool.all.Range(func(hash common.Hash, tx *types.Transaction) bool {
|
pool.all.Range(func(hash common.Hash, tx *types.Transaction) bool {
|
||||||
if tx.Gas() > params.MaxTxGas {
|
if tx.Gas() > params.MaxTxGas {
|
||||||
removeHashes = append(removeHashes, hash)
|
hashes = append(hashes, hash)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
for _, hash := range removeHashes {
|
for _, hash := range hashes {
|
||||||
pool.all.Remove(hash)
|
pool.removeTx(hash, true, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ type PendingFilter struct {
|
||||||
MinTip *uint256.Int // Minimum miner tip required to include a transaction
|
MinTip *uint256.Int // Minimum miner tip required to include a transaction
|
||||||
BaseFee *uint256.Int // Minimum 1559 basefee needed to include a transaction
|
BaseFee *uint256.Int // Minimum 1559 basefee needed to include a transaction
|
||||||
BlobFee *uint256.Int // Minimum 4844 blobfee needed to include a blob transaction
|
BlobFee *uint256.Int // Minimum 4844 blobfee needed to include a blob transaction
|
||||||
|
GasLimitCap uint64 // Maximum gas can be used for a single transaction execution (0 means no limit)
|
||||||
|
|
||||||
OnlyPlainTxs bool // Return only plain EVM transactions (peer-join announces, block space filling)
|
OnlyPlainTxs bool // Return only plain EVM transactions (peer-join announces, block space filling)
|
||||||
OnlyBlobTxs bool // Return only blob transactions (block blob-space filling)
|
OnlyBlobTxs bool // Return only blob transactions (block blob-space filling)
|
||||||
|
|
|
||||||
|
|
@ -76,9 +76,6 @@ type TxPool struct {
|
||||||
term chan struct{} // Termination channel to detect a closed pool
|
term chan struct{} // Termination channel to detect a closed pool
|
||||||
|
|
||||||
sync chan chan error // Testing / simulator channel to block until internal reset is done
|
sync chan chan error // Testing / simulator channel to block until internal reset is done
|
||||||
|
|
||||||
headLock sync.RWMutex
|
|
||||||
head *types.Header // this reflects the state from the latest pool reset
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new transaction pool to gather, sort and filter inbound
|
// New creates a new transaction pool to gather, sort and filter inbound
|
||||||
|
|
@ -107,7 +104,6 @@ func New(gasTip uint64, chain BlockChain, subpools []SubPool) (*TxPool, error) {
|
||||||
quit: make(chan chan error),
|
quit: make(chan chan error),
|
||||||
term: make(chan struct{}),
|
term: make(chan struct{}),
|
||||||
sync: make(chan chan error),
|
sync: make(chan chan error),
|
||||||
head: head,
|
|
||||||
}
|
}
|
||||||
reserver := NewReservationTracker()
|
reserver := NewReservationTracker()
|
||||||
for i, subpool := range subpools {
|
for i, subpool := range subpools {
|
||||||
|
|
@ -207,9 +203,6 @@ func (p *TxPool) loop(head *types.Header) {
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
case resetDone <- newHead:
|
case resetDone <- newHead:
|
||||||
p.headLock.Lock()
|
|
||||||
p.head = newHead
|
|
||||||
p.headLock.Unlock()
|
|
||||||
case <-p.term:
|
case <-p.term:
|
||||||
}
|
}
|
||||||
}(oldHead, newHead)
|
}(oldHead, newHead)
|
||||||
|
|
@ -264,14 +257,6 @@ func (p *TxPool) loop(head *types.Header) {
|
||||||
errc <- nil
|
errc <- nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Head returns the header which corresponds to the most recent successful pool
|
|
||||||
// reset.
|
|
||||||
func (p *TxPool) Head() *types.Header {
|
|
||||||
p.headLock.RLock()
|
|
||||||
defer p.headLock.RUnlock()
|
|
||||||
return types.CopyHeader(p.head)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetGasTip updates the minimum gas tip required by the transaction pool for a
|
// SetGasTip updates the minimum gas tip required by the transaction pool for a
|
||||||
// new transaction, and drops all transactions below this threshold.
|
// new transaction, and drops all transactions below this threshold.
|
||||||
func (p *TxPool) SetGasTip(tip *big.Int) {
|
func (p *TxPool) SetGasTip(tip *big.Int) {
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
|
||||||
return fmt.Errorf("%w: code size %v, limit %v", core.ErrMaxInitCodeSizeExceeded, len(tx.Data()), params.MaxInitCodeSize)
|
return fmt.Errorf("%w: code size %v, limit %v", core.ErrMaxInitCodeSizeExceeded, len(tx.Data()), params.MaxInitCodeSize)
|
||||||
}
|
}
|
||||||
if rules.IsOsaka && tx.Gas() > params.MaxTxGas {
|
if rules.IsOsaka && tx.Gas() > params.MaxTxGas {
|
||||||
return fmt.Errorf("transaction gas exceeded max allowed (%d): %d", params.MaxTxGas, tx.Gas())
|
return fmt.Errorf("%w (cap: %d, tx: %d)", core.ErrGasLimitTooHigh, params.MaxTxGas, tx.Gas())
|
||||||
}
|
}
|
||||||
// Transactions can't be negative. This may never happen using RLP decoded
|
// Transactions can't be negative. This may never happen using RLP decoded
|
||||||
// transactions but may occur for transactions created using the RPC.
|
// transactions but may occur for transactions created using the RPC.
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,6 @@ type environment struct {
|
||||||
blobs int
|
blobs int
|
||||||
|
|
||||||
witness *stateless.Witness
|
witness *stateless.Witness
|
||||||
chainConfig *params.ChainConfig
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -260,7 +259,6 @@ func (miner *Miner) makeEnv(parent *types.Header, header *types.Header, coinbase
|
||||||
header: header,
|
header: header,
|
||||||
witness: state.Witness(),
|
witness: state.Witness(),
|
||||||
evm: vm.NewEVM(core.NewEVMBlockContext(header, miner.chain, &coinbase), state, miner.chainConfig, vm.Config{}),
|
evm: vm.NewEVM(core.NewEVMBlockContext(header, miner.chain, &coinbase), state, miner.chainConfig, vm.Config{}),
|
||||||
chainConfig: miner.chainConfig,
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -427,23 +425,6 @@ func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *tran
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// fiterTxsAboveGas removes any transactions from the set which exceed a gas threshold.
|
|
||||||
// If a transaction is removed, all higher-nonce transactions from the same account
|
|
||||||
// will also be filtered out.
|
|
||||||
func filterTxsAboveGas(txs map[common.Address][]*txpool.LazyTransaction, maxGas uint64) {
|
|
||||||
for sender, senderTxs := range txs {
|
|
||||||
for i, tx := range senderTxs {
|
|
||||||
if tx.Gas > maxGas {
|
|
||||||
if i == 0 {
|
|
||||||
delete(txs, sender)
|
|
||||||
} else {
|
|
||||||
txs[sender] = txs[sender][:i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fillTransactions retrieves the pending transactions from the txpool and fills them
|
// fillTransactions retrieves the pending transactions from the txpool and fills them
|
||||||
// into the given sealing block. The transaction selection and ordering strategy can
|
// into the given sealing block. The transaction selection and ordering strategy can
|
||||||
// be customized with the plugin in the future.
|
// be customized with the plugin in the future.
|
||||||
|
|
@ -463,7 +444,11 @@ func (miner *Miner) fillTransactions(interrupt *atomic.Int32, env *environment)
|
||||||
if env.header.ExcessBlobGas != nil {
|
if env.header.ExcessBlobGas != nil {
|
||||||
filter.BlobFee = uint256.MustFromBig(eip4844.CalcBlobFee(miner.chainConfig, env.header))
|
filter.BlobFee = uint256.MustFromBig(eip4844.CalcBlobFee(miner.chainConfig, env.header))
|
||||||
}
|
}
|
||||||
|
if miner.chainConfig.IsOsaka(env.header.Number, env.header.Time) {
|
||||||
|
filter.GasLimitCap = params.MaxTxGas
|
||||||
|
}
|
||||||
filter.OnlyPlainTxs, filter.OnlyBlobTxs = true, false
|
filter.OnlyPlainTxs, filter.OnlyBlobTxs = true, false
|
||||||
|
|
||||||
pendingPlainTxs := miner.txpool.Pending(filter)
|
pendingPlainTxs := miner.txpool.Pending(filter)
|
||||||
|
|
||||||
filter.OnlyPlainTxs, filter.OnlyBlobTxs = false, true
|
filter.OnlyPlainTxs, filter.OnlyBlobTxs = false, true
|
||||||
|
|
@ -473,16 +458,6 @@ func (miner *Miner) fillTransactions(interrupt *atomic.Int32, env *environment)
|
||||||
prioPlainTxs, normalPlainTxs := make(map[common.Address][]*txpool.LazyTransaction), pendingPlainTxs
|
prioPlainTxs, normalPlainTxs := make(map[common.Address][]*txpool.LazyTransaction), pendingPlainTxs
|
||||||
prioBlobTxs, normalBlobTxs := make(map[common.Address][]*txpool.LazyTransaction), pendingBlobTxs
|
prioBlobTxs, normalBlobTxs := make(map[common.Address][]*txpool.LazyTransaction), pendingBlobTxs
|
||||||
|
|
||||||
// if we have just entered the Osaka fork, it is possible due to the async
|
|
||||||
// nature of txpool resets that the state of the pool has not finished resetting
|
|
||||||
// to a post-fork block. If so, it may not have removed txs that exceed the
|
|
||||||
// eip-7825 transaction maximum gas limit.
|
|
||||||
poolHead := miner.txpool.Head()
|
|
||||||
if env.chainConfig.IsOsaka(env.header.Number, env.header.Time) && !env.chainConfig.IsOsaka(poolHead.Number, poolHead.Time) {
|
|
||||||
filterTxsAboveGas(prioPlainTxs, params.MaxTxGas)
|
|
||||||
filterTxsAboveGas(prioBlobTxs, params.MaxTxGas)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, account := range prio {
|
for _, account := range prio {
|
||||||
if txs := normalPlainTxs[account]; len(txs) > 0 {
|
if txs := normalPlainTxs[account]; len(txs) > 0 {
|
||||||
delete(normalPlainTxs, account)
|
delete(normalPlainTxs, account)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue