From 4983e4372cc6b6291dfd9a671ccdc35fcbb5630c Mon Sep 17 00:00:00 2001 From: healthykim Date: Thu, 23 Apr 2026 12:25:32 +0200 Subject: [PATCH] fix engine api error --- core/types/custody_bitmap.go | 38 +++++++++++++++++++++++++++++++++++- eth/catalyst/api.go | 14 ++++--------- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/core/types/custody_bitmap.go b/core/types/custody_bitmap.go index 8e52e093d1..d3624bb914 100644 --- a/core/types/custody_bitmap.go +++ b/core/types/custody_bitmap.go @@ -17,15 +17,51 @@ package types import ( + "fmt" + "math/big" "math/bits" "math/rand" "github.com/ethereum/go-ethereum/crypto/kzg4844" ) -// `CustodyBitmap` is a bitmap to represent which custody index to store (little endian) +// CustodyBitmap is a bitmap to represent which custody index to store (little endian). +// It is serialized as a hex-encoded uint128 quantity (e.g. "0x89") for JSON-RPC. type CustodyBitmap [16]byte +// MarshalText implements encoding.TextMarshaler. +// Encodes the bitmap as a hex-encoded uint128 quantity. +func (b CustodyBitmap) MarshalText() ([]byte, error) { + var be [16]byte + for i := range b { + be[15-i] = b[i] + } + v := new(big.Int).SetBytes(be[:]) + return []byte("0x" + v.Text(16)), nil +} + +// UnmarshalText implements encoding.TextUnmarshaler. +// Parses a hex-encoded uint128 quantity into the bitmap. +func (b *CustodyBitmap) UnmarshalText(input []byte) error { + s := string(input) + if len(s) < 2 || (s[:2] != "0x" && s[:2] != "0X") { + return fmt.Errorf("custody bitmap: missing 0x prefix") + } + v, ok := new(big.Int).SetString(s[2:], 16) + if !ok { + return fmt.Errorf("custody bitmap: invalid hex %q", s) + } + if v.BitLen() > 128 { + return fmt.Errorf("custody bitmap: value exceeds 128 bits") + } + *b = CustodyBitmap{} + beBytes := v.Bytes() // big-endian + for i, byt := range beBytes { + b[len(beBytes)-1-i] = byt + } + return nil +} + var ( CustodyBitmapAll = func() *CustodyBitmap { var result CustodyBitmap diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index 6aaa287eac..b980920493 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -662,7 +662,7 @@ func (api *ConsensusAPI) getBlobs(hashes []common.Hash, v2 bool) ([]*engine.Blob // GetBlobsV4 returns cell-level blob data from the transaction pool. // V4 returns only the requested cells as specified by the indices_bitarray. -func (api *ConsensusAPI) GetBlobsV4(hashes []common.Hash, indicesBitarray hexutil.Bytes) ([]*engine.BlobCellsAndProofsV1, error) { +func (api *ConsensusAPI) GetBlobsV4(hashes []common.Hash, indicesBitarray types.CustodyBitmap) ([]*engine.BlobCellsAndProofsV1, error) { head := api.eth.BlockChain().CurrentHeader() // Sparse blobpool is not necessarily coupled with the Amsterdam fork and // can technically be supported after the Osaka fork @@ -673,12 +673,7 @@ func (api *ConsensusAPI) GetBlobsV4(hashes []common.Hash, indicesBitarray hexuti if len(hashes) > 128 { return nil, engine.TooLargeRequest.With(fmt.Errorf("requested blob count too large: %v", len(hashes))) } - if len(indicesBitarray) != 16 { - return nil, engine.InvalidParams.With(fmt.Errorf("indices_bitarray must be 16 bytes, got %d", len(indicesBitarray))) - } - var mask types.CustodyBitmap - copy(mask[:], indicesBitarray) - cells, proofs, err := api.eth.BlobTxPool().GetBlobCells(hashes, mask) + cells, proofs, err := api.eth.BlobTxPool().GetBlobCells(hashes, indicesBitarray) if err != nil { return nil, engine.InvalidParams.With(err) } @@ -1223,9 +1218,8 @@ func (api *ConsensusAPI) getBodiesByRange(start, count hexutil.Uint64) ([]*engin return bodies, nil } -func (api *ConsensusAPI) BlobCustodyUpdatedV1(custodyColumns []uint64) { - bitmap := types.NewCustodyBitmap(custodyColumns) - api.eth.BlobFetcher().UpdateCustody(bitmap) +func (api *ConsensusAPI) BlobCustodyUpdatedV1(indicesBitarray types.CustodyBitmap) { + api.eth.BlobFetcher().UpdateCustody(indicesBitarray) } func getBody(block *types.Block) *engine.ExecutionPayloadBody {