eth/catalyst: check osaka in engine_getBlobsV1 (#32731)

ref
https://github.com/ethereum/execution-apis/blob/main/src/engine/osaka.md#cancun-api

> Client software MUST return -38005: Unsupported fork error if the
Osaka fork has been activated.

---------

Signed-off-by: Delweng <delweng@gmail.com>
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
This commit is contained in:
Delweng 2025-09-29 17:56:39 +08:00 committed by GitHub
parent 943a30d1ee
commit 265db06242
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 35 additions and 3 deletions

View file

@ -492,6 +492,12 @@ func (api *ConsensusAPI) getPayload(payloadID engine.PayloadID, full bool) (*eng
// Client software MAY return an array of all null entries if syncing or otherwise
// unable to serve blob pool data.
func (api *ConsensusAPI) GetBlobsV1(hashes []common.Hash) ([]*engine.BlobAndProofV1, error) {
// Reject the request if Osaka has been activated.
// follow https://github.com/ethereum/execution-apis/blob/main/src/engine/osaka.md#cancun-api
head := api.eth.BlockChain().CurrentHeader()
if !api.checkFork(head.Time, forks.Cancun, forks.Prague) {
return nil, unsupportedForkErr("engine_getBlobsV1 is only available at Cancun/Prague fork")
}
if len(hashes) > 128 {
return nil, engine.TooLargeRequest.With(fmt.Errorf("requested blob count too large: %v", len(hashes)))
}
@ -532,9 +538,6 @@ func (api *ConsensusAPI) GetBlobsV1(hashes []common.Hash) ([]*engine.BlobAndProo
// - if the request is [A_versioned_hash_for_blob_with_blob_proof], the response
// MUST be null as well.
//
// Note, geth internally make the conversion from old version to new one, so the
// data will be returned normally.
//
// Client software MUST support request sizes of at least 128 blob versioned
// hashes. The client MUST return -38004: Too large request error if the number
// of requested blobs is too large.
@ -542,6 +545,10 @@ func (api *ConsensusAPI) GetBlobsV1(hashes []common.Hash) ([]*engine.BlobAndProo
// Client software MUST return null if syncing or otherwise unable to serve
// blob pool data.
func (api *ConsensusAPI) GetBlobsV2(hashes []common.Hash) ([]*engine.BlobAndProofV2, error) {
head := api.eth.BlockChain().CurrentHeader()
if api.config().LatestFork(head.Time) < forks.Osaka {
return nil, unsupportedForkErr("engine_getBlobsV2 is not available before Osaka fork")
}
if len(hashes) > 128 {
return nil, engine.TooLargeRequest.With(fmt.Errorf("requested blob count too large: %v", len(hashes)))
}

View file

@ -1991,6 +1991,31 @@ func TestGetBlobsV1(t *testing.T) {
}
}
func TestGetBlobsV1AfterOsakaFork(t *testing.T) {
genesis := &core.Genesis{
Config: params.MergedTestChainConfig,
Alloc: types.GenesisAlloc{testAddr: {Balance: testBalance}},
Difficulty: common.Big0,
Timestamp: 1, // Timestamp > 0 to ensure Osaka fork is active
}
n, ethServ := startEthService(t, genesis, nil)
defer n.Close()
var engineErr *engine.EngineAPIError
api := newConsensusAPIWithoutHeartbeat(ethServ)
_, err := api.GetBlobsV1([]common.Hash{testrand.Hash()})
if !errors.As(err, &engineErr) {
t.Fatalf("Unexpected error: %T", err)
} else {
if engineErr.ErrorCode() != -38005 {
t.Fatalf("Expected error code -38005, got %d", engineErr.ErrorCode())
}
if engineErr.Error() != "Unsupported fork" {
t.Fatalf("Expected error message 'Unsupported fork', got '%s'", engineErr.Error())
}
}
}
func TestGetBlobsV2(t *testing.T) {
n, api := newGetBlobEnv(t, 1)
defer n.Close()