miner: limit block size to eth protocol msg size (#2696)

This commit is contained in:
buddho 2024-09-10 16:24:29 +08:00 committed by GitHub
parent 7de27ca9e9
commit a28262b3ec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 32 additions and 1 deletions

@ -25,6 +25,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/forkid" "github.com/ethereum/go-ethereum/core/forkid"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
) )
@ -46,7 +47,7 @@ var ProtocolVersions = []uint{ETH68}
var protocolLengths = map[uint]uint64{ETH68: 17} var protocolLengths = map[uint]uint64{ETH68: 17}
// maxMessageSize is the maximum cap on the size of a protocol message. // maxMessageSize is the maximum cap on the size of a protocol message.
const maxMessageSize = 10 * 1024 * 1024 var maxMessageSize = params.MaxMessageSize
const ( const (
StatusMsg = 0x00 StatusMsg = 0x00

@ -692,6 +692,14 @@ func (b *bidSimulator) simBid(interruptCh chan int32, bidRuntime *BidRuntime) {
return return
} }
// check bid size
if bidRuntime.env.size+blockReserveSize > params.MaxMessageSize {
log.Error("BidSimulator: failed to check bid size", "builder", bidRuntime.bid.Builder,
"bidHash", bidRuntime.bid.Hash(), "env.size", bidRuntime.env.size)
err = errors.New("invalid bid size")
return
}
bestBid := b.GetBestBid(parentHash) bestBid := b.GetBestBid(parentHash)
if bestBid == nil { if bestBid == nil {
log.Info("[BID RESULT]", "win", "true[first]", "builder", bidRuntime.bid.Builder, "hash", bidRuntime.bid.Hash().TerminalString()) log.Info("[BID RESULT]", "win", "true[first]", "builder", bidRuntime.bid.Builder, "hash", bidRuntime.bid.Hash().TerminalString())
@ -858,6 +866,7 @@ func (r *BidRuntime) commitTransaction(chain *core.BlockChain, chainConfig *para
} }
r.env.tcount++ r.env.tcount++
r.env.size += uint32(tx.Size())
return nil return nil
} }

@ -70,6 +70,12 @@ const (
// the default to wait for the mev miner to finish // the default to wait for the mev miner to finish
waitMEVMinerEndTimeLimit = 50 * time.Millisecond waitMEVMinerEndTimeLimit = 50 * time.Millisecond
// Reserve block size for the following 3 components:
// a. System transactions at the end of the block
// b. Seal in the block header
// c. Overhead from RLP encoding
blockReserveSize = 100 * 1024
) )
var ( var (
@ -89,6 +95,7 @@ type environment struct {
signer types.Signer signer types.Signer
state *state.StateDB // apply state changes here state *state.StateDB // apply state changes here
tcount int // tx count in cycle tcount int // tx count in cycle
size uint32 // almost accurate block size,
gasPool *core.GasPool // available gas used to pack transactions gasPool *core.GasPool // available gas used to pack transactions
coinbase common.Address coinbase common.Address
@ -105,6 +112,7 @@ func (env *environment) copy() *environment {
signer: env.signer, signer: env.signer,
state: env.state.Copy(), state: env.state.Copy(),
tcount: env.tcount, tcount: env.tcount,
size: env.size,
coinbase: env.coinbase, coinbase: env.coinbase,
header: types.CopyHeader(env.header), header: types.CopyHeader(env.header),
receipts: copyReceipts(env.receipts), receipts: copyReceipts(env.receipts),
@ -895,6 +903,13 @@ LOOP:
txs.Pop() txs.Pop()
continue continue
} }
// If we don't have enough size left for the next transaction, skip it.
if env.size+uint32(tx.Size())+blockReserveSize > params.MaxMessageSize {
log.Trace("Not enough size left for transaction", "hash", ltx.Hash,
"env.size", env.size, "needed", uint32(tx.Size()))
txs.Pop()
continue
}
// Error may be ignored here. The error has already been checked // Error may be ignored here. The error has already been checked
// during transaction acceptance is the transaction pool. // during transaction acceptance is the transaction pool.
from, _ := types.Sender(env.signer, tx) from, _ := types.Sender(env.signer, tx)
@ -920,6 +935,7 @@ LOOP:
// Everything ok, collect the logs and shift in the next transaction from the same account // Everything ok, collect the logs and shift in the next transaction from the same account
coalescedLogs = append(coalescedLogs, logs...) coalescedLogs = append(coalescedLogs, logs...)
env.tcount++ env.tcount++
env.size += uint32(tx.Size()) // size of BlobTxSidecar included
txs.Shift() txs.Shift()
default: default:
@ -1055,6 +1071,9 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
vmenv := vm.NewEVM(context, vm.TxContext{}, env.state, w.chainConfig, vm.Config{}) vmenv := vm.NewEVM(context, vm.TxContext{}, env.state, w.chainConfig, vm.Config{})
core.ProcessBeaconBlockRoot(*header.ParentBeaconRoot, vmenv, env.state) core.ProcessBeaconBlockRoot(*header.ParentBeaconRoot, vmenv, env.state)
} }
env.size = uint32(env.header.Size())
return env, nil return env, nil
} }

@ -29,6 +29,8 @@ const (
GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block. GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block.
PayBidTxGasLimit uint64 = 25000 // Gas limit of the PayBidTx in the types.BidArgs. PayBidTxGasLimit uint64 = 25000 // Gas limit of the PayBidTx in the types.BidArgs.
MaxMessageSize uint32 = 10 * 1024 * 1024 // MaxMessageSize is the maximum cap on the size of a eth protocol message.
MaximumExtraDataSize uint64 = 32 // Maximum size extra data may be after Genesis. MaximumExtraDataSize uint64 = 32 // Maximum size extra data may be after Genesis.
ForkIDSize uint64 = 4 // The length of fork id ForkIDSize uint64 = 4 // The length of fork id
ExpByteGas uint64 = 10 // Times ceil(log256(exponent)) for the EXP instruction. ExpByteGas uint64 = 10 // Times ceil(log256(exponent)) for the EXP instruction.