mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 12:16:44 +00:00
eth/catalyst: pass TargetGasLimit via engine api (#35372)
Pass targetGasLimit via engine api --------- Co-authored-by: Gary Rong <garyrong0905@gmail.com>
This commit is contained in:
parent
4911ab04fc
commit
4363b81e6f
7 changed files with 92 additions and 59 deletions
|
|
@ -34,8 +34,8 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) {
|
|||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
|
||||
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
|
||||
SlotNumber *hexutil.Uint64 `json:"slotNumber,omitempty"`
|
||||
BlockAccessList hexutil.Bytes `json:"blockAccessList,omitempty"`
|
||||
SlotNumber *hexutil.Uint64 `json:"slotNumber,omitempty"`
|
||||
}
|
||||
var enc ExecutableData
|
||||
enc.ParentHash = e.ParentHash
|
||||
|
|
@ -60,8 +60,8 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) {
|
|||
enc.Withdrawals = e.Withdrawals
|
||||
enc.BlobGasUsed = (*hexutil.Uint64)(e.BlobGasUsed)
|
||||
enc.ExcessBlobGas = (*hexutil.Uint64)(e.ExcessBlobGas)
|
||||
enc.SlotNumber = (*hexutil.Uint64)(e.SlotNumber)
|
||||
enc.BlockAccessList = e.BlockAccessList
|
||||
enc.SlotNumber = (*hexutil.Uint64)(e.SlotNumber)
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
||||
|
|
@ -85,8 +85,8 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error {
|
|||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
|
||||
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
|
||||
SlotNumber *hexutil.Uint64 `json:"slotNumber,omitempty"`
|
||||
BlockAccessList *hexutil.Bytes `json:"blockAccessList,omitempty"`
|
||||
SlotNumber *hexutil.Uint64 `json:"slotNumber,omitempty"`
|
||||
}
|
||||
var dec ExecutableData
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
|
|
@ -160,11 +160,11 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error {
|
|||
if dec.ExcessBlobGas != nil {
|
||||
e.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas)
|
||||
}
|
||||
if dec.SlotNumber != nil {
|
||||
e.SlotNumber = (*uint64)(dec.SlotNumber)
|
||||
}
|
||||
if dec.BlockAccessList != nil {
|
||||
e.BlockAccessList = *dec.BlockAccessList
|
||||
}
|
||||
if dec.SlotNumber != nil {
|
||||
e.SlotNumber = (*uint64)(dec.SlotNumber)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ func (p PayloadAttributes) MarshalJSON() ([]byte, error) {
|
|||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
||||
SlotNumber *hexutil.Uint64 `json:"slotNumber"`
|
||||
TargetGasLimit *hexutil.Uint64 `json:"targetGasLimit"`
|
||||
}
|
||||
var enc PayloadAttributes
|
||||
enc.Timestamp = hexutil.Uint64(p.Timestamp)
|
||||
|
|
@ -30,6 +31,7 @@ func (p PayloadAttributes) MarshalJSON() ([]byte, error) {
|
|||
enc.Withdrawals = p.Withdrawals
|
||||
enc.BeaconRoot = p.BeaconRoot
|
||||
enc.SlotNumber = (*hexutil.Uint64)(p.SlotNumber)
|
||||
enc.TargetGasLimit = (*hexutil.Uint64)(p.TargetGasLimit)
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
||||
|
|
@ -42,6 +44,7 @@ func (p *PayloadAttributes) UnmarshalJSON(input []byte) error {
|
|||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
||||
SlotNumber *hexutil.Uint64 `json:"slotNumber"`
|
||||
TargetGasLimit *hexutil.Uint64 `json:"targetGasLimit"`
|
||||
}
|
||||
var dec PayloadAttributes
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
|
|
@ -68,5 +71,8 @@ func (p *PayloadAttributes) UnmarshalJSON(input []byte) error {
|
|||
if dec.SlotNumber != nil {
|
||||
p.SlotNumber = (*uint64)(dec.SlotNumber)
|
||||
}
|
||||
if dec.TargetGasLimit != nil {
|
||||
p.TargetGasLimit = (*uint64)(dec.TargetGasLimit)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ var (
|
|||
//
|
||||
// https://github.com/ethereum/execution-apis/blob/main/src/engine/amsterdam.md#executionpayloadv4
|
||||
// ExecutionPayloadV4 has the syntax of ExecutionPayloadV3 and appends the new
|
||||
// field slotNumber.
|
||||
// fields slotNumber and blockAccessList.
|
||||
PayloadV4 PayloadVersion = 0x4
|
||||
)
|
||||
|
||||
|
|
@ -74,12 +74,14 @@ type PayloadAttributes struct {
|
|||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
||||
SlotNumber *uint64 `json:"slotNumber"`
|
||||
TargetGasLimit *uint64 `json:"targetGasLimit"`
|
||||
}
|
||||
|
||||
// JSON type overrides for PayloadAttributes.
|
||||
type payloadAttributesMarshaling struct {
|
||||
Timestamp hexutil.Uint64
|
||||
SlotNumber *hexutil.Uint64
|
||||
Timestamp hexutil.Uint64
|
||||
SlotNumber *hexutil.Uint64
|
||||
TargetGasLimit *hexutil.Uint64
|
||||
}
|
||||
|
||||
//go:generate go run github.com/fjl/gencodec -type ExecutableData -field-override executableDataMarshaling -out ed_codec.go
|
||||
|
|
@ -103,8 +105,8 @@ type ExecutableData struct {
|
|||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
BlobGasUsed *uint64 `json:"blobGasUsed"`
|
||||
ExcessBlobGas *uint64 `json:"excessBlobGas"`
|
||||
SlotNumber *uint64 `json:"slotNumber,omitempty"`
|
||||
BlockAccessList []byte `json:"blockAccessList,omitempty"`
|
||||
SlotNumber *uint64 `json:"slotNumber,omitempty"`
|
||||
}
|
||||
|
||||
// JSON type overrides for executableData.
|
||||
|
|
@ -440,7 +442,7 @@ type ExecutionPayloadBody struct {
|
|||
// ExecutionPayloadBodyV2 extends ExecutionPayloadBody with the block access list.
|
||||
type ExecutionPayloadBodyV2 struct {
|
||||
ExecutionPayloadBody
|
||||
BlockAccessList *bal.BlockAccessList `json:"blockAccessList"`
|
||||
BlockAccessList *hexutil.Bytes `json:"blockAccessList"`
|
||||
}
|
||||
|
||||
// Client identifiers to support ClientVersionV1.
|
||||
|
|
|
|||
|
|
@ -229,6 +229,8 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV4(ctx context.Context, update engine.
|
|||
return engine.STATUS_INVALID, attributesErr("missing beacon root")
|
||||
case params.SlotNumber == nil:
|
||||
return engine.STATUS_INVALID, attributesErr("missing slot number")
|
||||
case params.TargetGasLimit == nil:
|
||||
return engine.STATUS_INVALID, attributesErr("missing target gas limit")
|
||||
case !api.checkFork(params.Timestamp, forks.Amsterdam):
|
||||
return engine.STATUS_INVALID, unsupportedForkErr("fcuV4 must only be called for amsterdam payloads")
|
||||
}
|
||||
|
|
@ -385,14 +387,15 @@ func (api *ConsensusAPI) forkchoiceUpdated(ctx context.Context, update engine.Fo
|
|||
// will replace it arbitrarily many times in between.
|
||||
if payloadAttributes != nil {
|
||||
args := &miner.BuildPayloadArgs{
|
||||
Parent: update.HeadBlockHash,
|
||||
Timestamp: payloadAttributes.Timestamp,
|
||||
FeeRecipient: payloadAttributes.SuggestedFeeRecipient,
|
||||
Random: payloadAttributes.Random,
|
||||
Withdrawals: payloadAttributes.Withdrawals,
|
||||
BeaconRoot: payloadAttributes.BeaconRoot,
|
||||
SlotNum: payloadAttributes.SlotNumber,
|
||||
Version: payloadVersion,
|
||||
Parent: update.HeadBlockHash,
|
||||
Timestamp: payloadAttributes.Timestamp,
|
||||
FeeRecipient: payloadAttributes.SuggestedFeeRecipient,
|
||||
Random: payloadAttributes.Random,
|
||||
Withdrawals: payloadAttributes.Withdrawals,
|
||||
BeaconRoot: payloadAttributes.BeaconRoot,
|
||||
SlotNum: payloadAttributes.SlotNumber,
|
||||
TargetGasLimit: payloadAttributes.TargetGasLimit,
|
||||
Version: payloadVersion,
|
||||
}
|
||||
id := args.Id()
|
||||
// If we already are busy generating this work, then we do not need
|
||||
|
|
@ -1320,9 +1323,17 @@ func getBodyV2(block *types.Block) *engine.ExecutionPayloadBodyV2 {
|
|||
if body == nil {
|
||||
return nil
|
||||
}
|
||||
var balData *hexutil.Bytes
|
||||
if bal := block.AccessList(); bal != nil {
|
||||
// Ignore the RLP encoding error just in case, interpreting
|
||||
// the BAL as unavailable.
|
||||
if enc, err := rlp.EncodeToBytes(bal); err == nil {
|
||||
balData = (*hexutil.Bytes)(&enc)
|
||||
}
|
||||
}
|
||||
return &engine.ExecutionPayloadBodyV2{
|
||||
ExecutionPayloadBody: *body,
|
||||
BlockAccessList: block.AccessList(),
|
||||
BlockAccessList: balData,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1594,7 +1594,7 @@ func TestGetPayloadBodyV2BlockAccessList(t *testing.T) {
|
|||
name: "retained empty BAL",
|
||||
header: &types.Header{BlockAccessListHash: &emptyHash},
|
||||
accessList: &empty,
|
||||
want: "[]",
|
||||
want: `"0xc0"`, // JSON-encoded hex string, quotes included
|
||||
},
|
||||
{
|
||||
name: "pruned BAL",
|
||||
|
|
|
|||
|
|
@ -40,14 +40,15 @@ import (
|
|||
// Check engine-api specification for more details.
|
||||
// https://github.com/ethereum/execution-apis/blob/main/src/engine/cancun.md#payloadattributesv3
|
||||
type BuildPayloadArgs struct {
|
||||
Parent common.Hash // The parent block to build payload on top
|
||||
Timestamp uint64 // The provided timestamp of generated payload
|
||||
FeeRecipient common.Address // The provided recipient address for collecting transaction fee
|
||||
Random common.Hash // The provided randomness value
|
||||
Withdrawals types.Withdrawals // The provided withdrawals
|
||||
BeaconRoot *common.Hash // The provided beaconRoot (Cancun)
|
||||
SlotNum *uint64 // The provided slotNumber
|
||||
Version engine.PayloadVersion // Versioning byte for payload id calculation.
|
||||
Parent common.Hash // The parent block to build payload on top
|
||||
Timestamp uint64 // The provided timestamp of generated payload
|
||||
FeeRecipient common.Address // The provided recipient address for collecting transaction fee
|
||||
Random common.Hash // The provided randomness value
|
||||
Withdrawals types.Withdrawals // The provided withdrawals
|
||||
BeaconRoot *common.Hash // The provided beaconRoot (Cancun)
|
||||
SlotNum *uint64 // The provided slotNumber (Amsterdam)
|
||||
TargetGasLimit *uint64 // The provided target gas limit (Amsterdam)
|
||||
Version engine.PayloadVersion // Versioning byte for payload id calculation.
|
||||
}
|
||||
|
||||
// Id computes an 8-byte identifier by hashing the components of the payload arguments.
|
||||
|
|
@ -62,7 +63,10 @@ func (args *BuildPayloadArgs) Id() engine.PayloadID {
|
|||
hasher.Write(args.BeaconRoot[:])
|
||||
}
|
||||
if args.SlotNum != nil {
|
||||
binary.Write(hasher, binary.BigEndian, args.SlotNum)
|
||||
binary.Write(hasher, binary.BigEndian, *args.SlotNum)
|
||||
}
|
||||
if args.TargetGasLimit != nil {
|
||||
binary.Write(hasher, binary.BigEndian, *args.TargetGasLimit)
|
||||
}
|
||||
var out engine.PayloadID
|
||||
copy(out[:], hasher.Sum(nil)[:8])
|
||||
|
|
@ -246,15 +250,16 @@ func (miner *Miner) buildPayload(ctx context.Context, args *BuildPayloadArgs, wi
|
|||
// enough to run. The empty payload can at least make sure there is something
|
||||
// to deliver for not missing slot.
|
||||
emptyParams := &generateParams{
|
||||
timestamp: args.Timestamp,
|
||||
forceTime: true,
|
||||
parentHash: args.Parent,
|
||||
coinbase: args.FeeRecipient,
|
||||
random: args.Random,
|
||||
withdrawals: args.Withdrawals,
|
||||
beaconRoot: args.BeaconRoot,
|
||||
slotNum: args.SlotNum,
|
||||
noTxs: true,
|
||||
timestamp: args.Timestamp,
|
||||
forceTime: true,
|
||||
parentHash: args.Parent,
|
||||
coinbase: args.FeeRecipient,
|
||||
random: args.Random,
|
||||
withdrawals: args.Withdrawals,
|
||||
beaconRoot: args.BeaconRoot,
|
||||
slotNum: args.SlotNum,
|
||||
targetGasLimit: args.TargetGasLimit,
|
||||
noTxs: true,
|
||||
}
|
||||
empty := miner.generateWork(ctx, emptyParams, witness)
|
||||
if empty.err != nil {
|
||||
|
|
@ -286,15 +291,16 @@ func (miner *Miner) buildPayload(ctx context.Context, args *BuildPayloadArgs, wi
|
|||
endTimer := time.NewTimer(time.Second * 12)
|
||||
|
||||
fullParams := &generateParams{
|
||||
timestamp: args.Timestamp,
|
||||
forceTime: true,
|
||||
parentHash: args.Parent,
|
||||
coinbase: args.FeeRecipient,
|
||||
random: args.Random,
|
||||
withdrawals: args.Withdrawals,
|
||||
beaconRoot: args.BeaconRoot,
|
||||
slotNum: args.SlotNum,
|
||||
noTxs: false,
|
||||
timestamp: args.Timestamp,
|
||||
forceTime: true,
|
||||
parentHash: args.Parent,
|
||||
coinbase: args.FeeRecipient,
|
||||
random: args.Random,
|
||||
withdrawals: args.Withdrawals,
|
||||
beaconRoot: args.BeaconRoot,
|
||||
slotNum: args.SlotNum,
|
||||
targetGasLimit: args.TargetGasLimit,
|
||||
noTxs: false,
|
||||
}
|
||||
for {
|
||||
select {
|
||||
|
|
@ -351,6 +357,7 @@ func (miner *Miner) BuildTestingPayload(args *BuildPayloadArgs, transactions []*
|
|||
withdrawals: args.Withdrawals,
|
||||
beaconRoot: args.BeaconRoot,
|
||||
slotNum: args.SlotNum,
|
||||
targetGasLimit: args.TargetGasLimit,
|
||||
noTxs: empty,
|
||||
forceOverrides: true,
|
||||
overrideExtraData: extraData,
|
||||
|
|
|
|||
|
|
@ -117,15 +117,16 @@ type newPayloadResult struct {
|
|||
|
||||
// generateParams wraps various settings for generating sealing task.
|
||||
type generateParams struct {
|
||||
timestamp uint64 // The timestamp for sealing task
|
||||
forceTime bool // Flag whether the given timestamp is immutable or not
|
||||
parentHash common.Hash // Parent block hash, empty means the latest chain head
|
||||
coinbase common.Address // The fee recipient address for including transaction
|
||||
random common.Hash // The randomness generated by beacon chain, empty before the merge
|
||||
withdrawals types.Withdrawals // List of withdrawals to include in block (shanghai field)
|
||||
beaconRoot *common.Hash // The beacon root (cancun field).
|
||||
slotNum *uint64 // The slot number (amsterdam field).
|
||||
noTxs bool // Flag whether an empty block without any transaction is expected
|
||||
timestamp uint64 // The timestamp for sealing task
|
||||
forceTime bool // Flag whether the given timestamp is immutable or not
|
||||
parentHash common.Hash // Parent block hash, empty means the latest chain head
|
||||
coinbase common.Address // The fee recipient address for including transaction
|
||||
random common.Hash // The randomness generated by beacon chain, empty before the merge
|
||||
withdrawals types.Withdrawals // List of withdrawals to include in block (shanghai field)
|
||||
beaconRoot *common.Hash // The beacon root (cancun field).
|
||||
slotNum *uint64 // The slot number (amsterdam field).
|
||||
targetGasLimit *uint64 // The target gas limit requested by the CL (amsterdam field).
|
||||
noTxs bool // Flag whether an empty block without any transaction is expected
|
||||
|
||||
forceOverrides bool // Flag whether we should overwrite extraData and transactions
|
||||
overrideExtraData []byte
|
||||
|
|
@ -267,11 +268,17 @@ func (miner *Miner) prepareWork(ctx context.Context, genParams *generateParams,
|
|||
}
|
||||
timestamp = parent.Time + 1
|
||||
}
|
||||
// Post-Amsterdam use TargetGasLimit provided by CL
|
||||
number := new(big.Int).Add(parent.Number, common.Big1)
|
||||
gasCeil := miner.config.GasCeil
|
||||
if miner.chainConfig.IsAmsterdam(number, timestamp) && genParams.targetGasLimit != nil {
|
||||
gasCeil = *genParams.targetGasLimit
|
||||
}
|
||||
// Construct the sealing block header.
|
||||
header := &types.Header{
|
||||
ParentHash: parent.Hash(),
|
||||
Number: new(big.Int).Add(parent.Number, common.Big1),
|
||||
GasLimit: core.CalcGasLimit(parent.GasLimit, miner.config.GasCeil),
|
||||
Number: number,
|
||||
GasLimit: core.CalcGasLimit(parent.GasLimit, gasCeil),
|
||||
Time: timestamp,
|
||||
Coinbase: genParams.coinbase,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue