eth/catalyst: check fork timestamps during engine_getPayload (#32754)

This adds checks into getPayload to ensure the correct version is called
for the fork which applies to the payload.

---------

Co-authored-by: jsvisa <delweng@gmail.com>
This commit is contained in:
lightclient 2025-11-28 10:02:24 -03:00 committed by GitHub
parent a122dbe459
commit 28376aea78
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -402,10 +402,12 @@ func (api *ConsensusAPI) ExchangeTransitionConfigurationV1(config engine.Transit
// GetPayloadV1 returns a cached payload by id.
func (api *ConsensusAPI) GetPayloadV1(payloadID engine.PayloadID) (*engine.ExecutableData, error) {
if !payloadID.Is(engine.PayloadV1) {
return nil, engine.UnsupportedFork
}
data, err := api.getPayload(payloadID, false)
data, err := api.getPayload(
payloadID,
false,
[]engine.PayloadVersion{engine.PayloadV1},
nil,
)
if err != nil {
return nil, err
}
@ -414,35 +416,34 @@ func (api *ConsensusAPI) GetPayloadV1(payloadID engine.PayloadID) (*engine.Execu
// GetPayloadV2 returns a cached payload by id.
func (api *ConsensusAPI) GetPayloadV2(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) {
// executionPayload: ExecutionPayloadV1 | ExecutionPayloadV2 where:
//
// - ExecutionPayloadV1 MUST be returned if the payload timestamp is lower
// than the Shanghai timestamp
//
// - ExecutionPayloadV2 MUST be returned if the payload timestamp is greater
// or equal to the Shanghai timestamp
if !payloadID.Is(engine.PayloadV1, engine.PayloadV2) {
return nil, engine.UnsupportedFork
}
return api.getPayload(payloadID, false)
return api.getPayload(
payloadID,
false,
[]engine.PayloadVersion{engine.PayloadV1, engine.PayloadV2},
[]forks.Fork{forks.Shanghai},
)
}
// GetPayloadV3 returns a cached payload by id. This endpoint should only
// be used for the Cancun fork.
func (api *ConsensusAPI) GetPayloadV3(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) {
if !payloadID.Is(engine.PayloadV3) {
return nil, engine.UnsupportedFork
}
return api.getPayload(payloadID, false)
return api.getPayload(
payloadID,
false,
[]engine.PayloadVersion{engine.PayloadV3},
[]forks.Fork{forks.Cancun},
)
}
// GetPayloadV4 returns a cached payload by id. This endpoint should only
// be used for the Prague fork.
func (api *ConsensusAPI) GetPayloadV4(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) {
if !payloadID.Is(engine.PayloadV3) {
return nil, engine.UnsupportedFork
}
return api.getPayload(payloadID, false)
return api.getPayload(
payloadID,
false,
[]engine.PayloadVersion{engine.PayloadV3},
[]forks.Fork{forks.Prague},
)
}
// GetPayloadV5 returns a cached payload by id. This endpoint should only
@ -451,18 +452,35 @@ func (api *ConsensusAPI) GetPayloadV4(payloadID engine.PayloadID) (*engine.Execu
// This method follows the same specification as engine_getPayloadV4 with
// changes of returning BlobsBundleV2 with BlobSidecar version 1.
func (api *ConsensusAPI) GetPayloadV5(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) {
if !payloadID.Is(engine.PayloadV3) {
return nil, engine.UnsupportedFork
}
return api.getPayload(payloadID, false)
return api.getPayload(
payloadID,
false,
[]engine.PayloadVersion{engine.PayloadV3},
[]forks.Fork{
forks.Osaka,
forks.BPO1,
forks.BPO2,
forks.BPO3,
forks.BPO4,
forks.BPO5,
})
}
func (api *ConsensusAPI) getPayload(payloadID engine.PayloadID, full bool) (*engine.ExecutionPayloadEnvelope, error) {
// getPayload will retreive the specified payload and verify it conforms to the
// endpoint's allowed payload versions and forks.
func (api *ConsensusAPI) getPayload(payloadID engine.PayloadID, full bool, versions []engine.PayloadVersion, forks []forks.Fork) (*engine.ExecutionPayloadEnvelope, error) {
log.Trace("Engine API request received", "method", "GetPayload", "id", payloadID)
if !payloadID.Is(versions...) {
return nil, engine.UnsupportedFork
}
data := api.localBlocks.get(payloadID, full)
if data == nil {
return nil, engine.UnknownPayload
}
if forks != nil && !api.checkFork(data.ExecutionPayload.Timestamp, forks...) {
return nil, engine.UnsupportedFork
}
return data, nil
}