eth/catalyst: pass targetGasLimit through in testing_buildBlockV1 (#35501)
Some checks are pending
/ Linux Build (push) Waiting to run
/ Linux Build (arm) (push) Waiting to run
/ Keeper Build (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run

`testing_buildBlockV1` decodes `targetGasLimit` from the payload
attributes but does not pass it to `miner.BuildPayloadArgs`. The miner
then falls back to its configured gas ceiling, so the field is silently
ignored. The engine API path (`forkchoiceUpdated`) already passes it
through.

This matters for fixture generation in ethereum/execution-apis, where
`testing_buildBlockV1` builds Amsterdam test blocks and the gas limit
must honor the CL-provided target (see ethereum/execution-apis#857 and
ethereum/execution-apis#862).

The new test builds an Amsterdam block with a target inside the
per-block adjustment bound and checks the payload hits it exactly.
This commit is contained in:
Chase Wright 2026-08-11 07:28:01 -05:00 committed by GitHub
parent c3185d9030
commit 87ab9435f5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 50 additions and 7 deletions

View file

@ -94,13 +94,14 @@ func (api *testingAPI) buildTestingBlock(payloadAttributes engine.PayloadAttribu
extra = *extraData
}
args := &miner.BuildPayloadArgs{
Parent: parentHash,
Timestamp: payloadAttributes.Timestamp,
FeeRecipient: payloadAttributes.SuggestedFeeRecipient,
Random: payloadAttributes.Random,
Withdrawals: payloadAttributes.Withdrawals,
BeaconRoot: payloadAttributes.BeaconRoot,
SlotNum: payloadAttributes.SlotNumber,
Parent: parentHash,
Timestamp: payloadAttributes.Timestamp,
FeeRecipient: payloadAttributes.SuggestedFeeRecipient,
Random: payloadAttributes.Random,
Withdrawals: payloadAttributes.Withdrawals,
BeaconRoot: payloadAttributes.BeaconRoot,
SlotNum: payloadAttributes.SlotNumber,
TargetGasLimit: payloadAttributes.TargetGasLimit,
}
return api.eth.Miner().BuildTestingPayload(args, txs, buildEmpty, extra)
}

View file

@ -120,6 +120,48 @@ func TestBuildBlockV1(t *testing.T) {
})
}
func TestBuildBlockV1TargetGasLimit(t *testing.T) {
genesis, blocks := generateMergeChain(5, true)
time := blocks[len(blocks)-1].Time() + 5
genesis.Config.ShanghaiTime = &time
genesis.Config.CancunTime = &time
genesis.Config.PragueTime = &time
genesis.Config.OsakaTime = &time
genesis.Config.AmsterdamTime = &time
genesis.Config.BlobScheduleConfig = params.DefaultBlobSchedule
n, ethservice := startEthService(t, genesis, blocks)
defer n.Close()
var (
api = &testingAPI{eth: ethservice}
parent = ethservice.BlockChain().CurrentBlock()
beaconRoot = common.Hash{42}
slot = uint64(1)
// Within the per-block adjustment bound, so the built block
// must hit the target exactly.
target = parent.GasLimit - 1000
)
attrs := engine.PayloadAttributes{
Timestamp: parent.Time + 5,
Random: crypto.Keccak256Hash([]byte("test")),
SuggestedFeeRecipient: parent.Coinbase,
Withdrawals: make([]*types.Withdrawal, 0),
BeaconRoot: &beaconRoot,
SlotNumber: &slot,
TargetGasLimit: &target,
}
emptyTxs := []hexutil.Bytes{}
envelope, err := api.BuildBlockV1(parent.Hash(), attrs, &emptyTxs, nil)
if err != nil {
t.Fatalf("BuildBlockV1 failed: %v", err)
}
if got := envelope.ExecutionPayload.GasLimit; got != target {
t.Errorf("gas limit mismatch: got %d want %d", got, target)
}
}
func TestCommitBlockV1(t *testing.T) {
genesis, blocks := generateMergeChain(5, true)
n, ethservice := startEthService(t, genesis, blocks)