move ap4 block gas cost check to header

See https://github.com/ava-labs/coreth/pull/849
This commit is contained in:
Ceyhun Onur
2025-03-13 16:41:21 +01:00
committed by Quentin Mc Gaw
parent fbdc6f17d9
commit cdcc5cc2f7
4 changed files with 60 additions and 48 deletions
+32 -40
View File
@@ -154,20 +154,14 @@ func verifyHeaderGasFields(config *params.ChainConfig, header *types.Header, par
return fmt.Errorf("expected base fee (%d), found (%d)", expectedBaseFee, header.BaseFee)
}
if !config.IsSubnetEVM(header.Time) {
if header.BlockGasCost != nil {
return fmt.Errorf("invalid blockGasCost before fork: have %d, want <nil>", header.BlockGasCost)
}
return nil
}
// Enforce BlockGasCost constraints
expectedBlockGasCost := customheader.BlockGasCost(
config,
feeConfig,
parent,
header.Time,
)
if !utils.BigEqualUint64(header.BlockGasCost, expectedBlockGasCost) {
if !utils.BigEqual(header.BlockGasCost, expectedBlockGasCost) {
return fmt.Errorf("invalid block gas cost: have %d, want %d", header.BlockGasCost, expectedBlockGasCost)
}
return nil
@@ -334,25 +328,24 @@ func (eng *DummyEngine) verifyBlockFee(
func (eng *DummyEngine) Finalize(chain consensus.ChainHeaderReader, block *types.Block, parent *types.Header, state *state.StateDB, receipts []*types.Receipt) error {
config := chain.Config()
timestamp := block.Time()
// we use the parent to determine the fee config
// since the current block has not been finalized yet.
feeConfig, _, err := chain.GetFeeConfigAt(parent)
if err != nil {
return err
}
// Verify the BlockGasCost set in the header matches the expected value.
blockGasCost := block.BlockGasCost()
expectedBlockGasCost := customheader.BlockGasCost(
config,
feeConfig,
parent,
timestamp,
)
if !utils.BigEqual(blockGasCost, expectedBlockGasCost) {
return fmt.Errorf("invalid blockGasCost: have %d, want %d", blockGasCost, expectedBlockGasCost)
}
if config.IsSubnetEVM(timestamp) {
// we use the parent to determine the fee config
// since the current block has not been finalized yet.
feeConfig, _, err := chain.GetFeeConfigAt(parent)
if err != nil {
return err
}
// Verify the BlockGasCost set in the header matches the expected value.
blockGasCost := block.BlockGasCost()
expectedBlockGasCost := customheader.BlockGasCost(
feeConfig,
parent,
timestamp,
)
if !utils.BigEqualUint64(blockGasCost, expectedBlockGasCost) {
return fmt.Errorf("invalid blockGasCost: have %d, want %d", blockGasCost, expectedBlockGasCost)
}
// Verify the block fee was paid.
if err := eng.verifyBlockFee(
block.BaseFee(),
@@ -371,21 +364,20 @@ func (eng *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, h
uncles []*types.Header, receipts []*types.Receipt,
) (*types.Block, error) {
config := chain.Config()
// we use the parent to determine the fee config
// since the current block has not been finalized yet.
feeConfig, _, err := chain.GetFeeConfigAt(parent)
if err != nil {
return nil, err
}
// Calculate the required block gas cost for this block.
header.BlockGasCost = customheader.BlockGasCost(
config,
feeConfig,
parent,
header.Time,
)
if config.IsSubnetEVM(header.Time) {
// we use the parent to determine the fee config
// since the current block has not been finalized yet.
feeConfig, _, err := chain.GetFeeConfigAt(parent)
if err != nil {
return nil, err
}
// Calculate the required block gas cost for this block.
blockGasCost := customheader.BlockGasCost(
feeConfig,
parent,
header.Time,
)
header.BlockGasCost = new(big.Int).SetUint64(blockGasCost)
// Verify that this block covers the block fee.
if err := eng.verifyBlockFee(
header.BaseFee,
+8 -3
View File
@@ -22,11 +22,16 @@ var (
// BlockGasCost calculates the required block gas cost based on the parent
// header and the timestamp of the new block.
// Prior to Subnet-EVM, the returned block gas cost will be nil.
func BlockGasCost(
config *params.ChainConfig,
feeConfig commontype.FeeConfig,
parent *types.Header,
timestamp uint64,
) uint64 {
) *big.Int {
if !config.IsSubnetEVM(timestamp) {
return nil
}
step := feeConfig.BlockGasCostStep.Uint64()
// Treat an invalid parent/current time combination as 0 elapsed time.
//
@@ -36,12 +41,12 @@ func BlockGasCost(
if parent.Time <= timestamp {
timeElapsed = timestamp - parent.Time
}
return BlockGasCostWithStep(
return new(big.Int).SetUint64(BlockGasCostWithStep(
feeConfig,
parent.BlockGasCost,
step,
timeElapsed,
)
))
}
// BlockGasCostWithStep calculates the required block gas cost based on the
+18 -3
View File
@@ -57,35 +57,50 @@ func BlockGasCostTest(t *testing.T, feeConfig commontype.FeeConfig) {
tests := []struct {
name string
upgrades params.NetworkUpgrades
parentTime uint64
parentCost *big.Int
timestamp uint64
expected uint64
expected *big.Int
}{
{
name: "before_subnet_evm",
parentTime: 10,
upgrades: params.TestPreSubnetEVMChainConfig.NetworkUpgrades,
parentCost: maxBlockGasCostBig,
timestamp: 10 + targetBlockRate + 1,
expected: nil,
},
{
name: "normal",
upgrades: params.TestChainConfig.NetworkUpgrades,
parentTime: 10,
parentCost: maxBlockGasCostBig,
timestamp: 10 + targetBlockRate + 1,
expected: maxBlockGasCost - blockGasCostStep,
expected: new(big.Int).SetUint64(maxBlockGasCost - blockGasCostStep),
},
{
name: "negative_time_elapsed",
upgrades: params.TestChainConfig.NetworkUpgrades,
parentTime: 10,
parentCost: feeConfig.MinBlockGasCost,
timestamp: 9,
expected: minBlockGasCost + blockGasCostStep*targetBlockRate,
expected: new(big.Int).SetUint64(minBlockGasCost + blockGasCostStep*targetBlockRate),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
config := &params.ChainConfig{
NetworkUpgrades: test.upgrades,
}
parent := &types.Header{
Time: test.parentTime,
BlockGasCost: test.parentCost,
}
assert.Equal(t, test.expected, BlockGasCost(
config,
feeConfig,
parent,
test.timestamp,
+2 -2
View File
@@ -147,10 +147,10 @@ func VerifyGasLimitTest(t *testing.T, feeConfig commontype.FeeConfig) {
func TestGasCapacity(t *testing.T) {
t.Run("normal", func(t *testing.T) {
GasLimitTest(t, testFeeConfig)
GasCapacityTest(t, testFeeConfig)
})
t.Run("double", func(t *testing.T) {
GasLimitTest(t, testFeeConfigDouble)
GasCapacityTest(t, testFeeConfigDouble)
})
}