eth/catalyst: implement getBlobsV2

This commit is contained in:
Marius van der Wijden 2025-03-11 12:54:40 +01:00 committed by MariusVanDerWijden
parent 9defed8e73
commit f4e5e73edf
4 changed files with 77 additions and 2 deletions

View file

@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/trie"
)
@ -116,6 +117,7 @@ type BlobsBundleV1 struct {
Commitments []hexutil.Bytes `json:"commitments"`
Proofs []hexutil.Bytes `json:"proofs"`
Blobs []hexutil.Bytes `json:"blobs"`
CellProofs []hexutil.Bytes `json:"cell_proofs"`
}
type BlobAndProofV1 struct {
@ -123,6 +125,11 @@ type BlobAndProofV1 struct {
Proof hexutil.Bytes `json:"proof"`
}
type BlobAndProofV2 struct {
Blob hexutil.Bytes `json:"blob"`
CellProofs []hexutil.Bytes `json:"cell_proofs"`
}
// JSON type overrides for ExecutionPayloadEnvelope.
type executionPayloadEnvelopeMarshaling struct {
BlockValue *hexutil.Big
@ -326,12 +333,20 @@ func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars []*types.
Commitments: make([]hexutil.Bytes, 0),
Blobs: make([]hexutil.Bytes, 0),
Proofs: make([]hexutil.Bytes, 0),
CellProofs: make([]hexutil.Bytes, 0),
}
for _, sidecar := range sidecars {
for j := range sidecar.Blobs {
bundle.Blobs = append(bundle.Blobs, hexutil.Bytes(sidecar.Blobs[j][:]))
bundle.Commitments = append(bundle.Commitments, hexutil.Bytes(sidecar.Commitments[j][:]))
bundle.Proofs = append(bundle.Proofs, hexutil.Bytes(sidecar.Proofs[j][:]))
cellProofs, err := kzg4844.ComputeCells(&sidecar.Blobs[j])
if err != nil {
panic(err)
}
for _, proof := range cellProofs {
bundle.CellProofs = append(bundle.CellProofs, hexutil.Bytes(proof[:]))
}
}
}

View file

@ -84,6 +84,10 @@ type Claim [32]byte
// useCKZG controls whether the cryptography should use the Go or C backend.
var useCKZG atomic.Bool
func init() {
UseCKZG(true)
}
// UseCKZG can be called to switch the default Go implementation of KZG to the C
// library if for some reason the user wishes to do so (e.g. consensus bug in one
// or the other).
@ -177,3 +181,7 @@ func CalcBlobHashV1(hasher hash.Hash, commit *Commitment) (vh [32]byte) {
func IsValidVersionedHash(h []byte) bool {
return len(h) == 32 && h[0] == 0x01
}
func ComputeCells(blob *Blob) ([]Proof, error) {
return ckzgComputeCells(blob)
}

View file

@ -32,6 +32,7 @@ import (
"github.com/ethereum/go-ethereum/core/stateless"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth/ethconfig"
"github.com/ethereum/go-ethereum/internal/version"
@ -511,7 +512,12 @@ func (api *ConsensusAPI) GetPayloadV3(payloadID engine.PayloadID) (*engine.Execu
if !payloadID.Is(engine.PayloadV3) {
return nil, engine.UnsupportedFork
}
return api.getPayload(payloadID, false)
envelope, err := api.getPayload(payloadID, false)
if err != nil {
return nil, err
}
envelope.BlobsBundle.CellProofs = nil
return envelope, nil
}
// GetPayloadV4 returns a cached payload by id.
@ -519,7 +525,25 @@ func (api *ConsensusAPI) GetPayloadV4(payloadID engine.PayloadID) (*engine.Execu
if !payloadID.Is(engine.PayloadV3) {
return nil, engine.UnsupportedFork
}
return api.getPayload(payloadID, false)
envelope, err := api.getPayload(payloadID, false)
if err != nil {
return nil, err
}
envelope.BlobsBundle.CellProofs = nil
return envelope, nil
}
// GetPayloadV4 returns a cached payload by id.
func (api *ConsensusAPI) GetPayloadV5(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) {
if !payloadID.Is(engine.PayloadV3) {
return nil, engine.UnsupportedFork
}
envelope, err := api.getPayload(payloadID, false)
if err != nil {
return nil, err
}
envelope.BlobsBundle.Proofs = nil
return envelope, nil
}
func (api *ConsensusAPI) getPayload(payloadID engine.PayloadID, full bool) (*engine.ExecutionPayloadEnvelope, error) {
@ -550,6 +574,33 @@ func (api *ConsensusAPI) GetBlobsV1(hashes []common.Hash) ([]*engine.BlobAndProo
return res, nil
}
// GetBlobsV2 returns a blob from the transaction pool.
func (api *ConsensusAPI) GetBlobsV2(hashes []common.Hash) ([]*engine.BlobAndProofV2, error) {
if len(hashes) > 128 {
return nil, engine.TooLargeRequest.With(fmt.Errorf("requested blob count too large: %v", len(hashes)))
}
res := make([]*engine.BlobAndProofV2, len(hashes))
blobs, _ := api.eth.TxPool().GetBlobs(hashes)
for i := 0; i < len(blobs); i++ {
if blobs[i] != nil {
cellProofs, err := kzg4844.ComputeCells(blobs[i])
if err != nil {
return nil, err
}
var proofs []hexutil.Bytes
for _, proof := range cellProofs {
proofs = append(proofs, hexutil.Bytes(proof[:]))
}
res[i] = &engine.BlobAndProofV2{
Blob: (*blobs[i])[:],
CellProofs: proofs,
}
}
}
return res, nil
}
// NewPayloadV1 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
func (api *ConsensusAPI) NewPayloadV1(params engine.ExecutableData) (engine.PayloadStatusV1, error) {
if params.Withdrawals != nil {

1
go.mod
View file

@ -103,6 +103,7 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/deepmap/oapi-codegen v1.6.0 // indirect
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/ethereum/c-kzg-4844/v2 v2.0.1 // indirect
github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect
github.com/getsentry/sentry-go v0.27.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect