mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 15:47:21 +00:00
miner, core, core/txpool: implement EIP 7825 - TX Gas Limit Cap (#31824)
Implements EIP-7825 --------- Co-authored-by: Gary Rong <garyrong0905@gmail.com> Co-authored-by: lightclient <lightclient@protonmail.com> Co-authored-by: MariusVanDerWijden <m.vanderwijden@live.de>
This commit is contained in:
parent
43832e65fd
commit
1cbcebcf47
9 changed files with 54 additions and 7 deletions
|
|
@ -183,6 +183,9 @@ func Transaction(ctx *cli.Context) error {
|
|||
if chainConfig.IsShanghai(new(big.Int), 0) && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize {
|
||||
r.Error = errors.New("max initcode size exceeded")
|
||||
}
|
||||
if chainConfig.IsOsaka(new(big.Int), 0) && tx.Gas() > params.MaxTxGas {
|
||||
r.Error = errors.New("gas limit exceeds maximum")
|
||||
}
|
||||
results = append(results, r)
|
||||
}
|
||||
out, err := json.MarshalIndent(results, "", " ")
|
||||
|
|
|
|||
|
|
@ -122,6 +122,9 @@ var (
|
|||
// Message validation errors:
|
||||
ErrEmptyAuthList = errors.New("EIP-7702 transaction with empty auth list")
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -394,6 +394,10 @@ func (st *stateTransition) preCheck() error {
|
|||
return fmt.Errorf("%w (sender %v)", ErrEmptyAuthList, msg.From)
|
||||
}
|
||||
}
|
||||
// Verify tx gas limit does not exceed EIP-7825 cap.
|
||||
if st.evm.ChainConfig().IsOsaka(st.evm.Context.BlockNumber, st.evm.Context.Time) && msg.GasLimit > params.MaxTxGas {
|
||||
return fmt.Errorf("%w (cap: %d, tx: %d)", ErrGasLimitTooHigh, params.MaxTxGas, msg.GasLimit)
|
||||
}
|
||||
return st.buyGas()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
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
|
||||
lazies = append(lazies, &txpool.LazyTransaction{
|
||||
Pool: p,
|
||||
|
|
|
|||
|
|
@ -530,11 +530,19 @@ func (pool *LegacyPool) Pending(filter txpool.PendingFilter) map[common.Address]
|
|||
txs := list.Flatten()
|
||||
|
||||
// If the miner requests tip enforcement, cap the lists now
|
||||
if minTipBig != nil {
|
||||
if minTipBig != nil || filter.GasLimitCap != 0 {
|
||||
for i, tx := range txs {
|
||||
if tx.EffectiveGasTipIntCmp(minTipBig, baseFeeBig) < 0 {
|
||||
txs = txs[:i]
|
||||
break
|
||||
if minTipBig != nil {
|
||||
if tx.EffectiveGasTipIntCmp(minTipBig, baseFeeBig) < 0 {
|
||||
txs = txs[:i]
|
||||
break
|
||||
}
|
||||
}
|
||||
if filter.GasLimitCap != 0 {
|
||||
if tx.Gas() > filter.GasLimitCap {
|
||||
txs = txs[:i]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1255,6 +1263,21 @@ func (pool *LegacyPool) runReorg(done chan struct{}, reset *txpoolResetRequest,
|
|||
}
|
||||
pool.mu.Lock()
|
||||
if reset != 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) {
|
||||
var hashes []common.Hash
|
||||
pool.all.Range(func(hash common.Hash, tx *types.Transaction) bool {
|
||||
if tx.Gas() > params.MaxTxGas {
|
||||
hashes = append(hashes, hash)
|
||||
}
|
||||
return true
|
||||
})
|
||||
for _, hash := range hashes {
|
||||
pool.removeTx(hash, true, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Reset from the old head to the new, rescheduling any reorged transactions
|
||||
pool.reset(reset.oldHead, reset.newHead)
|
||||
|
||||
|
|
|
|||
|
|
@ -73,9 +73,10 @@ type LazyResolver interface {
|
|||
// a very specific call site in mind and each one can be evaluated very cheaply
|
||||
// by the pool implementations. Only add new ones that satisfy those constraints.
|
||||
type PendingFilter struct {
|
||||
MinTip *uint256.Int // Minimum miner tip required 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
|
||||
MinTip *uint256.Int // Minimum miner tip required 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
|
||||
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)
|
||||
OnlyBlobTxs bool // Return only blob transactions (block blob-space filling)
|
||||
|
|
|
|||
|
|
@ -90,6 +90,9 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
|
|||
if rules.IsShanghai && tx.To() == nil && 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 {
|
||||
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 but may occur for transactions created using the RPC.
|
||||
if tx.Value().Sign() < 0 {
|
||||
|
|
|
|||
|
|
@ -462,6 +462,9 @@ func (miner *Miner) fillTransactions(interrupt *atomic.Int32, env *environment)
|
|||
if env.header.ExcessBlobGas != nil {
|
||||
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
|
||||
pendingPlainTxs := miner.txpool.Pending(filter)
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ const (
|
|||
MaxGasLimit uint64 = 0x7fffffffffffffff // Maximum the gas limit (2^63-1).
|
||||
GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block.
|
||||
|
||||
MaxTxGas uint64 = 30_000_000 // Maximum transaction gas limit after eip-7825.
|
||||
|
||||
MaximumExtraDataSize uint64 = 32 // Maximum size extra data may be after Genesis.
|
||||
ExpByteGas uint64 = 10 // Times ceil(log256(exponent)) for the EXP instruction.
|
||||
SloadGas uint64 = 50 // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added.
|
||||
|
|
|
|||
Loading…
Reference in a new issue