From ed1d46b3d31f250e5385a4b8b8f97293acf8adee Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 5 Feb 2025 10:35:03 +0100 Subject: [PATCH] consensus/misc/eip4844: more changes for blob gas calculation (#31128) This PR changes the signature of `CalcExcessBlobGas` to take in just the header timestamp instead of the whole object. It also adds a sanity check for the parent->child block order to `VerifyEIP4844Header`. --- cmd/evm/internal/t8ntool/execution.go | 2 +- consensus/misc/eip4844/eip4844.go | 9 ++++++--- consensus/misc/eip4844/eip4844_test.go | 8 ++------ core/chain_makers.go | 7 ++++--- core/state_processor_test.go | 2 +- eth/gasprice/feehistory.go | 2 +- eth/tracers/internal/tracetest/util.go | 2 +- internal/ethapi/simulate.go | 2 +- miner/worker.go | 2 +- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 1613521b0d..793b2d425b 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -198,7 +198,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, Time: pre.Env.Timestamp, ExcessBlobGas: &excessBlobGas, } - excessBlobGas = eip4844.CalcExcessBlobGas(chainConfig, parent, header) + excessBlobGas = eip4844.CalcExcessBlobGas(chainConfig, parent, header.Time) vmContext.BlobBaseFee = eip4844.CalcBlobFee(chainConfig, header) } } diff --git a/consensus/misc/eip4844/eip4844.go b/consensus/misc/eip4844/eip4844.go index 148ea60274..4a2754b55c 100644 --- a/consensus/misc/eip4844/eip4844.go +++ b/consensus/misc/eip4844/eip4844.go @@ -34,6 +34,9 @@ var ( // if the current block contains no transactions, the excessBlobGas is updated // accordingly. func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Header) error { + if header.Number.Uint64() != parent.Number.Uint64()+1 { + panic("bad header pair") + } // Verify the header is not malformed if header.ExcessBlobGas == nil { return errors.New("header is missing excessBlobGas") @@ -50,7 +53,7 @@ func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Heade return fmt.Errorf("blob gas used %d not a multiple of blob gas per blob %d", header.BlobGasUsed, params.BlobTxBlobGasPerBlob) } // Verify the excessBlobGas is correct based on the parent header - expectedExcessBlobGas := CalcExcessBlobGas(config, parent, header) + expectedExcessBlobGas := CalcExcessBlobGas(config, parent, header.Time) if *header.ExcessBlobGas != expectedExcessBlobGas { return fmt.Errorf("invalid excessBlobGas: have %d, want %d", *header.ExcessBlobGas, expectedExcessBlobGas) } @@ -59,9 +62,8 @@ func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Heade // CalcExcessBlobGas calculates the excess blob gas after applying the set of // blobs on top of the excess blob gas. -func CalcExcessBlobGas(config *params.ChainConfig, parent, header *types.Header) uint64 { +func CalcExcessBlobGas(config *params.ChainConfig, parent *types.Header, headTimestamp uint64) uint64 { var ( - targetGas = uint64(targetBlobsPerBlock(config, header.Time)) * params.BlobTxBlobGasPerBlob parentExcessBlobGas uint64 parentBlobGasUsed uint64 ) @@ -70,6 +72,7 @@ func CalcExcessBlobGas(config *params.ChainConfig, parent, header *types.Header) parentBlobGasUsed = *parent.BlobGasUsed } excessBlobGas := parentExcessBlobGas + parentBlobGasUsed + targetGas := uint64(targetBlobsPerBlock(config, headTimestamp)) * params.BlobTxBlobGasPerBlob if excessBlobGas < targetGas { return 0 } diff --git a/consensus/misc/eip4844/eip4844_test.go b/consensus/misc/eip4844/eip4844_test.go index 7d221aa96e..f4e3cb3d9a 100644 --- a/consensus/misc/eip4844/eip4844_test.go +++ b/consensus/misc/eip4844/eip4844_test.go @@ -57,15 +57,11 @@ func TestCalcExcessBlobGas(t *testing.T) { } for i, tt := range tests { blobGasUsed := uint64(tt.blobs) * params.BlobTxBlobGasPerBlob - head := &types.Header{ - Time: *config.CancunTime, - } - parent := &types.Header{ - Time: *config.CancunTime, + header := &types.Header{ ExcessBlobGas: &tt.excess, BlobGasUsed: &blobGasUsed, } - result := CalcExcessBlobGas(config, parent, head) + result := CalcExcessBlobGas(config, header, *config.CancunTime) if result != tt.want { t.Errorf("test %d: excess blob gas mismatch: have %v, want %v", i, result, tt.want) } diff --git a/core/chain_makers.go b/core/chain_makers.go index 2ade70f175..8d09390b72 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -582,25 +582,26 @@ func GenerateVerkleChainWithGenesis(genesis *Genesis, engine consensus.Engine, n func (cm *chainMaker) makeHeader(parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header { time := parent.Time() + 10 // block time is fixed at 10 seconds + parentHeader := parent.Header() header := &types.Header{ Root: state.IntermediateRoot(cm.config.IsEIP158(parent.Number())), ParentHash: parent.Hash(), Coinbase: parent.Coinbase(), - Difficulty: engine.CalcDifficulty(cm, time, parent.Header()), + Difficulty: engine.CalcDifficulty(cm, time, parentHeader), GasLimit: parent.GasLimit(), Number: new(big.Int).Add(parent.Number(), common.Big1), Time: time, } if cm.config.IsLondon(header.Number) { - header.BaseFee = eip1559.CalcBaseFee(cm.config, parent.Header()) + header.BaseFee = eip1559.CalcBaseFee(cm.config, parentHeader) if !cm.config.IsLondon(parent.Number()) { parentGasLimit := parent.GasLimit() * cm.config.ElasticityMultiplier() header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit) } } if cm.config.IsCancun(header.Number, header.Time) { - excessBlobGas := eip4844.CalcExcessBlobGas(cm.config, parent.Header(), header) + excessBlobGas := eip4844.CalcExcessBlobGas(cm.config, parentHeader, time) header.ExcessBlobGas = &excessBlobGas header.BlobGasUsed = new(uint64) header.ParentBeaconRoot = new(common.Hash) diff --git a/core/state_processor_test.go b/core/state_processor_test.go index b0258ae37b..a6ca2781f8 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -407,7 +407,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr } header.Root = common.BytesToHash(hasher.Sum(nil)) if config.IsCancun(header.Number, header.Time) { - excess := eip4844.CalcExcessBlobGas(config, parent.Header(), header) + excess := eip4844.CalcExcessBlobGas(config, parent.Header(), header.Time) used := uint64(nBlobs * params.BlobTxBlobGasPerBlob) header.ExcessBlobGas = &excess header.BlobGasUsed = &used diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go index 94fc5b35f9..fe84950c50 100644 --- a/eth/gasprice/feehistory.go +++ b/eth/gasprice/feehistory.go @@ -97,7 +97,7 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) { // Fill in blob base fee and next blob base fee. if excessBlobGas := bf.header.ExcessBlobGas; excessBlobGas != nil { bf.results.blobBaseFee = eip4844.CalcBlobFee(config, bf.header) - excess := eip4844.CalcExcessBlobGas(config, bf.header, bf.header) + excess := eip4844.CalcExcessBlobGas(config, bf.header, bf.header.Time) next := &types.Header{Number: bf.header.Number, Time: bf.header.Time, ExcessBlobGas: &excess} bf.results.nextBlobBaseFee = eip4844.CalcBlobFee(config, next) } else { diff --git a/eth/tracers/internal/tracetest/util.go b/eth/tracers/internal/tracetest/util.go index 97896213b4..524a396d5c 100644 --- a/eth/tracers/internal/tracetest/util.go +++ b/eth/tracers/internal/tracetest/util.go @@ -55,7 +55,7 @@ func (c *callContext) toBlockContext(genesis *core.Genesis) vm.BlockContext { if genesis.ExcessBlobGas != nil && genesis.BlobGasUsed != nil { header := &types.Header{Number: genesis.Config.LondonBlock, Time: *genesis.Config.CancunTime} - excess := eip4844.CalcExcessBlobGas(genesis.Config, header, genesis.ToBlock().Header()) + excess := eip4844.CalcExcessBlobGas(genesis.Config, header, genesis.Timestamp) header.ExcessBlobGas = &excess context.BlobBaseFee = eip4844.CalcBlobFee(genesis.Config, header) } diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index 0262f69c02..c461b1f0a1 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -159,7 +159,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, if sim.chainConfig.IsCancun(header.Number, header.Time) { var excess uint64 if sim.chainConfig.IsCancun(parent.Number, parent.Time) { - excess = eip4844.CalcExcessBlobGas(sim.chainConfig, parent, header) + excess = eip4844.CalcExcessBlobGas(sim.chainConfig, parent, header.Time) } header.ExcessBlobGas = &excess } diff --git a/miner/worker.go b/miner/worker.go index 6ec23ec624..2c54421196 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -210,7 +210,7 @@ func (miner *Miner) prepareWork(genParams *generateParams, witness bool) (*envir if miner.chainConfig.IsCancun(header.Number, header.Time) { var excessBlobGas uint64 if miner.chainConfig.IsCancun(parent.Number, parent.Time) { - excessBlobGas = eip4844.CalcExcessBlobGas(miner.chainConfig, parent, header) + excessBlobGas = eip4844.CalcExcessBlobGas(miner.chainConfig, parent, timestamp) } header.BlobGasUsed = new(uint64) header.ExcessBlobGas = &excessBlobGas