mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-13 11:36:37 +00:00
core/vm: implement eip-7843
This commit is contained in:
parent
f7ce5467e3
commit
3b0d27b1e7
4 changed files with 62 additions and 8 deletions
|
|
@ -51,6 +51,12 @@ var (
|
||||||
// ExecutionPayloadV3 has the syntax of ExecutionPayloadV2 and appends the new
|
// ExecutionPayloadV3 has the syntax of ExecutionPayloadV2 and appends the new
|
||||||
// fields: blobGasUsed and excessBlobGas.
|
// fields: blobGasUsed and excessBlobGas.
|
||||||
PayloadV3 PayloadVersion = 0x3
|
PayloadV3 PayloadVersion = 0x3
|
||||||
|
|
||||||
|
// PayloadV4 is the identifier of ExecutionPayloadV3 introduced in amsterdam fork.
|
||||||
|
//
|
||||||
|
// https://github.com/ethereum/execution-apis/blob/main/src/engine/amsterdam.md#executionpayloadv4
|
||||||
|
// ExecutionPayloadV3 has the syntax of ExecutionPayloadV3 and appends the new
|
||||||
|
// field slotNumber.
|
||||||
PayloadV4 PayloadVersion = 0x4
|
PayloadV4 PayloadVersion = 0x4
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -64,11 +70,13 @@ type PayloadAttributes struct {
|
||||||
SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient" gencodec:"required"`
|
SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient" gencodec:"required"`
|
||||||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||||
BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"`
|
||||||
|
SlotNumber *uint64 `json:"slotNumber"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON type overrides for PayloadAttributes.
|
// JSON type overrides for PayloadAttributes.
|
||||||
type payloadAttributesMarshaling struct {
|
type payloadAttributesMarshaling struct {
|
||||||
Timestamp hexutil.Uint64
|
Timestamp hexutil.Uint64
|
||||||
|
SlotNumber *hexutil.Uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate go run github.com/fjl/gencodec -type ExecutableData -field-override executableDataMarshaling -out gen_ed.go
|
//go:generate go run github.com/fjl/gencodec -type ExecutableData -field-override executableDataMarshaling -out gen_ed.go
|
||||||
|
|
|
||||||
|
|
@ -213,6 +213,28 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV3(update engine.ForkchoiceStateV1, pa
|
||||||
return api.forkchoiceUpdated(update, params, engine.PayloadV3, false)
|
return api.forkchoiceUpdated(update, params, engine.PayloadV3, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ForkchoiceUpdatedV4 is equivalent to V3 with the addition of slot number
|
||||||
|
// in the payload attributes. It supports only PayloadAttributesV4.
|
||||||
|
func (api *ConsensusAPI) ForkchoiceUpdatedV4(update engine.ForkchoiceStateV1, params *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) {
|
||||||
|
if params != nil {
|
||||||
|
switch {
|
||||||
|
case params.Withdrawals == nil:
|
||||||
|
return engine.STATUS_INVALID, attributesErr("missing withdrawals")
|
||||||
|
case params.BeaconRoot == nil:
|
||||||
|
return engine.STATUS_INVALID, attributesErr("missing beacon root")
|
||||||
|
case params.SlotNumber == nil:
|
||||||
|
return engine.STATUS_INVALID, attributesErr("missing slot number")
|
||||||
|
case !api.checkFork(params.Timestamp, forks.Amsterdam):
|
||||||
|
return engine.STATUS_INVALID, unsupportedForkErr("fcuV4 must only be called for amsterdam payloads")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO(matt): the spec requires that fcu is applied when called on a valid
|
||||||
|
// hash, even if params are wrong. To do this we need to split up
|
||||||
|
// forkchoiceUpdate into a function that only updates the head and then a
|
||||||
|
// function that kicks off block construction.
|
||||||
|
return api.forkchoiceUpdated(update, params, engine.PayloadV4, false)
|
||||||
|
}
|
||||||
|
|
||||||
func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payloadAttributes *engine.PayloadAttributes, payloadVersion engine.PayloadVersion, payloadWitness bool) (engine.ForkChoiceResponse, error) {
|
func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payloadAttributes *engine.PayloadAttributes, payloadVersion engine.PayloadVersion, payloadWitness bool) (engine.ForkChoiceResponse, error) {
|
||||||
api.forkchoiceLock.Lock()
|
api.forkchoiceLock.Lock()
|
||||||
defer api.forkchoiceLock.Unlock()
|
defer api.forkchoiceLock.Unlock()
|
||||||
|
|
@ -346,6 +368,7 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl
|
||||||
Random: payloadAttributes.Random,
|
Random: payloadAttributes.Random,
|
||||||
Withdrawals: payloadAttributes.Withdrawals,
|
Withdrawals: payloadAttributes.Withdrawals,
|
||||||
BeaconRoot: payloadAttributes.BeaconRoot,
|
BeaconRoot: payloadAttributes.BeaconRoot,
|
||||||
|
SlotNum: payloadAttributes.SlotNumber,
|
||||||
Version: payloadVersion,
|
Version: payloadVersion,
|
||||||
}
|
}
|
||||||
id := args.Id()
|
id := args.Id()
|
||||||
|
|
@ -459,15 +482,16 @@ func (api *ConsensusAPI) GetPayloadV5(payloadID engine.PayloadID) (*engine.Execu
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPayloadV6 returns a cached payload by id.
|
// GetPayloadV6 returns a cached payload by id. This endpoint should only
|
||||||
|
// be used after the Amsterdam fork.
|
||||||
func (api *ConsensusAPI) GetPayloadV6(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) {
|
func (api *ConsensusAPI) GetPayloadV6(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) {
|
||||||
if !payloadID.Is(engine.PayloadV4) {
|
return api.getPayload(
|
||||||
return nil, engine.UnsupportedFork
|
payloadID,
|
||||||
}
|
|
||||||
return api.getPayload(payloadID,
|
|
||||||
false,
|
false,
|
||||||
[]engine.PayloadVersion{engine.PayloadV4},
|
[]engine.PayloadVersion{engine.PayloadV4},
|
||||||
nil)
|
[]forks.Fork{
|
||||||
|
forks.Amsterdam,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// getPayload will retrieve the specified payload and verify it conforms to the
|
// getPayload will retrieve the specified payload and verify it conforms to the
|
||||||
|
|
@ -728,9 +752,12 @@ func (api *ConsensusAPI) NewPayloadV5(params engine.ExecutableData, versionedHas
|
||||||
return invalidStatus, paramsErr("nil beaconRoot post-cancun")
|
return invalidStatus, paramsErr("nil beaconRoot post-cancun")
|
||||||
case executionRequests == nil:
|
case executionRequests == nil:
|
||||||
return invalidStatus, paramsErr("nil executionRequests post-prague")
|
return invalidStatus, paramsErr("nil executionRequests post-prague")
|
||||||
|
case !api.checkFork(params.Timestamp, forks.Prague, forks.Osaka, forks.Amsterdam):
|
||||||
case params.BlockAccessList == nil:
|
case params.BlockAccessList == nil:
|
||||||
return invalidStatus, paramsErr("nil block access list post-amsterdam")
|
return invalidStatus, paramsErr("nil block access list post-amsterdam")
|
||||||
case !api.checkFork(params.Timestamp, forks.Prague, forks.Osaka, forks.Amsterdam):
|
case params.SlotNumber == nil:
|
||||||
|
return invalidStatus, paramsErr("nil slotnumber post-amsterdam")
|
||||||
|
case !api.checkFork(params.Timestamp, forks.Amsterdam):
|
||||||
return invalidStatus, unsupportedForkErr("newPayloadV5 must only be called for amsterdam payloads")
|
return invalidStatus, unsupportedForkErr("newPayloadV5 must only be called for amsterdam payloads")
|
||||||
}
|
}
|
||||||
requests := convertRequests(executionRequests)
|
requests := convertRequests(executionRequests)
|
||||||
|
|
@ -768,6 +795,10 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe
|
||||||
if params.ExcessBlobGas != nil {
|
if params.ExcessBlobGas != nil {
|
||||||
ebg = strconv.Itoa(int(*params.ExcessBlobGas))
|
ebg = strconv.Itoa(int(*params.ExcessBlobGas))
|
||||||
}
|
}
|
||||||
|
slotnum := "nil"
|
||||||
|
if params.SlotNumber != nil {
|
||||||
|
ebg = strconv.Itoa(int(*params.SlotNumber))
|
||||||
|
}
|
||||||
log.Warn("Invalid NewPayload params",
|
log.Warn("Invalid NewPayload params",
|
||||||
"params.Number", params.Number,
|
"params.Number", params.Number,
|
||||||
"params.ParentHash", params.ParentHash,
|
"params.ParentHash", params.ParentHash,
|
||||||
|
|
@ -783,6 +814,7 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe
|
||||||
"params.BaseFeePerGas", params.BaseFeePerGas,
|
"params.BaseFeePerGas", params.BaseFeePerGas,
|
||||||
"params.BlobGasUsed", bgu,
|
"params.BlobGasUsed", bgu,
|
||||||
"params.ExcessBlobGas", ebg,
|
"params.ExcessBlobGas", ebg,
|
||||||
|
"params.SlotNumber", slotnum,
|
||||||
"len(params.Transactions)", len(params.Transactions),
|
"len(params.Transactions)", len(params.Transactions),
|
||||||
"len(params.Withdrawals)", len(params.Withdrawals),
|
"len(params.Withdrawals)", len(params.Withdrawals),
|
||||||
"beaconRoot", beaconRoot,
|
"beaconRoot", beaconRoot,
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ type BuildPayloadArgs struct {
|
||||||
Random common.Hash // The provided randomness value
|
Random common.Hash // The provided randomness value
|
||||||
Withdrawals types.Withdrawals // The provided withdrawals
|
Withdrawals types.Withdrawals // The provided withdrawals
|
||||||
BeaconRoot *common.Hash // The provided beaconRoot (Cancun)
|
BeaconRoot *common.Hash // The provided beaconRoot (Cancun)
|
||||||
|
SlotNum *uint64 // The provided slotNumber
|
||||||
Version engine.PayloadVersion // Versioning byte for payload id calculation.
|
Version engine.PayloadVersion // Versioning byte for payload id calculation.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,6 +58,9 @@ func (args *BuildPayloadArgs) Id() engine.PayloadID {
|
||||||
if args.BeaconRoot != nil {
|
if args.BeaconRoot != nil {
|
||||||
hasher.Write(args.BeaconRoot[:])
|
hasher.Write(args.BeaconRoot[:])
|
||||||
}
|
}
|
||||||
|
if args.SlotNum != nil {
|
||||||
|
binary.Write(hasher, binary.BigEndian, args.SlotNum)
|
||||||
|
}
|
||||||
var out engine.PayloadID
|
var out engine.PayloadID
|
||||||
copy(out[:], hasher.Sum(nil)[:8])
|
copy(out[:], hasher.Sum(nil)[:8])
|
||||||
out[0] = byte(args.Version)
|
out[0] = byte(args.Version)
|
||||||
|
|
@ -218,6 +222,7 @@ func (miner *Miner) buildPayload(args *BuildPayloadArgs, witness bool) (*Payload
|
||||||
random: args.Random,
|
random: args.Random,
|
||||||
withdrawals: args.Withdrawals,
|
withdrawals: args.Withdrawals,
|
||||||
beaconRoot: args.BeaconRoot,
|
beaconRoot: args.BeaconRoot,
|
||||||
|
slotNum: args.SlotNum,
|
||||||
noTxs: true,
|
noTxs: true,
|
||||||
}
|
}
|
||||||
empty := miner.generateWork(emptyParams, witness)
|
empty := miner.generateWork(emptyParams, witness)
|
||||||
|
|
@ -248,6 +253,7 @@ func (miner *Miner) buildPayload(args *BuildPayloadArgs, witness bool) (*Payload
|
||||||
random: args.Random,
|
random: args.Random,
|
||||||
withdrawals: args.Withdrawals,
|
withdrawals: args.Withdrawals,
|
||||||
beaconRoot: args.BeaconRoot,
|
beaconRoot: args.BeaconRoot,
|
||||||
|
slotNum: args.SlotNum,
|
||||||
noTxs: false,
|
noTxs: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,7 @@ type generateParams struct {
|
||||||
random common.Hash // The randomness generated by beacon chain, empty before the merge
|
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)
|
withdrawals types.Withdrawals // List of withdrawals to include in block (shanghai field)
|
||||||
beaconRoot *common.Hash // The beacon root (cancun 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
|
noTxs bool // Flag whether an empty block without any transaction is expected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -271,6 +272,13 @@ func (miner *Miner) prepareWork(genParams *generateParams, witness bool) (*envir
|
||||||
header.ExcessBlobGas = &excessBlobGas
|
header.ExcessBlobGas = &excessBlobGas
|
||||||
header.ParentBeaconRoot = genParams.beaconRoot
|
header.ParentBeaconRoot = genParams.beaconRoot
|
||||||
}
|
}
|
||||||
|
// Apply EIP-7843.
|
||||||
|
if miner.chainConfig.IsAmsterdam(header.Number, header.Time) {
|
||||||
|
if genParams.slotNum == nil {
|
||||||
|
return nil, errors.New("no slot number set post-amsterdam")
|
||||||
|
}
|
||||||
|
header.SlotNumber = genParams.slotNum
|
||||||
|
}
|
||||||
// Could potentially happen if starting to mine in an odd state.
|
// Could potentially happen if starting to mine in an odd state.
|
||||||
// Note genParams.coinbase can be different with header.Coinbase
|
// Note genParams.coinbase can be different with header.Coinbase
|
||||||
// since clique algorithm can modify the coinbase field in header.
|
// since clique algorithm can modify the coinbase field in header.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue