core/types: compute cellproofs on transaction submission

This commit is contained in:
Marius van der Wijden 2025-03-31 17:29:17 +02:00 committed by MariusVanDerWijden
parent d05a127f34
commit 8b7e1f058c
7 changed files with 33 additions and 20 deletions

View file

@ -1298,11 +1298,12 @@ func (p *BlobPool) GetMetadata(hash common.Hash) *txpool.TxMetadata {
// GetBlobs returns a number of blobs are proofs for the given versioned hashes. // GetBlobs returns a number of blobs are proofs for the given versioned hashes.
// This is a utility method for the engine API, enabling consensus clients to // This is a utility method for the engine API, enabling consensus clients to
// retrieve blobs from the pools directly instead of the network. // retrieve blobs from the pools directly instead of the network.
func (p *BlobPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Proof) { func (p *BlobPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Proof, [][]kzg4844.Proof) {
// Create a map of the blob hash to indices for faster fills // Create a map of the blob hash to indices for faster fills
var ( var (
blobs = make([]*kzg4844.Blob, len(vhashes)) blobs = make([]*kzg4844.Blob, len(vhashes))
proofs = make([]*kzg4844.Proof, len(vhashes)) proofs = make([]*kzg4844.Proof, len(vhashes))
cell_proofs = make([][]kzg4844.Proof, len(vhashes))
) )
index := make(map[common.Hash]int) index := make(map[common.Hash]int)
for i, vhash := range vhashes { for i, vhash := range vhashes {
@ -1341,10 +1342,11 @@ func (p *BlobPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.
if idx, ok := index[blobhash]; ok { if idx, ok := index[blobhash]; ok {
blobs[idx] = &sidecar.Blobs[j] blobs[idx] = &sidecar.Blobs[j]
proofs[idx] = &sidecar.Proofs[j] proofs[idx] = &sidecar.Proofs[j]
cell_proofs[idx] = sidecar.CellProofs[j]
} }
} }
} }
return blobs, proofs return blobs, proofs, cell_proofs
} }
// Add inserts a set of blob transactions into the pool if they pass validation (both // Add inserts a set of blob transactions into the pool if they pass validation (both

View file

@ -417,7 +417,7 @@ func verifyBlobRetrievals(t *testing.T, pool *BlobPool) {
for i := range testBlobVHashes { for i := range testBlobVHashes {
copy(hashes[i][:], testBlobVHashes[i][:]) copy(hashes[i][:], testBlobVHashes[i][:])
} }
blobs, proofs := pool.GetBlobs(hashes) blobs, proofs, _ := pool.GetBlobs(hashes)
// Cross validate what we received vs what we wanted // Cross validate what we received vs what we wanted
if len(blobs) != len(hashes) || len(proofs) != len(hashes) { if len(blobs) != len(hashes) || len(proofs) != len(hashes) {

View file

@ -1065,8 +1065,8 @@ func (pool *LegacyPool) GetMetadata(hash common.Hash) *txpool.TxMetadata {
// GetBlobs is not supported by the legacy transaction pool, it is just here to // GetBlobs is not supported by the legacy transaction pool, it is just here to
// implement the txpool.SubPool interface. // implement the txpool.SubPool interface.
func (pool *LegacyPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Proof) { func (pool *LegacyPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Proof, [][]kzg4844.Proof) {
return nil, nil return nil, nil, nil
} }
// Has returns an indicator whether txpool has a transaction cached with the // Has returns an indicator whether txpool has a transaction cached with the

View file

@ -136,7 +136,7 @@ type SubPool interface {
// GetBlobs returns a number of blobs are proofs for the given versioned hashes. // GetBlobs returns a number of blobs are proofs for the given versioned hashes.
// This is a utility method for the engine API, enabling consensus clients to // This is a utility method for the engine API, enabling consensus clients to
// retrieve blobs from the pools directly instead of the network. // retrieve blobs from the pools directly instead of the network.
GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Proof) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Proof, [][]kzg4844.Proof)
// ValidateTxBasics checks whether a transaction is valid according to the consensus // ValidateTxBasics checks whether a transaction is valid according to the consensus
// rules, but does not check state-dependent validation such as sufficient balance. // rules, but does not check state-dependent validation such as sufficient balance.

View file

@ -311,17 +311,17 @@ func (p *TxPool) GetMetadata(hash common.Hash) *TxMetadata {
// GetBlobs returns a number of blobs are proofs for the given versioned hashes. // GetBlobs returns a number of blobs are proofs for the given versioned hashes.
// This is a utility method for the engine API, enabling consensus clients to // This is a utility method for the engine API, enabling consensus clients to
// retrieve blobs from the pools directly instead of the network. // retrieve blobs from the pools directly instead of the network.
func (p *TxPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Proof) { func (p *TxPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Proof, [][]kzg4844.Proof) {
for _, subpool := range p.subpools { for _, subpool := range p.subpools {
// It's an ugly to assume that only one pool will be capable of returning // It's an ugly to assume that only one pool will be capable of returning
// anything meaningful for this call, but anythingh else requires merging // anything meaningful for this call, but anythingh else requires merging
// partial responses and that's too annoying to do until we get a second // partial responses and that's too annoying to do until we get a second
// blobpool (probably never). // blobpool (probably never).
if blobs, proofs := subpool.GetBlobs(vhashes); blobs != nil { if blobs, proofs, cellProofs := subpool.GetBlobs(vhashes); blobs != nil {
return blobs, proofs return blobs, proofs, cellProofs
} }
} }
return nil, nil return nil, nil, nil
} }
// Add enqueues a batch of transactions into the pool if they are valid. Due // Add enqueues a batch of transactions into the pool if they are valid. Due

View file

@ -58,6 +58,7 @@ type BlobTxSidecar struct {
Blobs []kzg4844.Blob // Blobs needed by the blob pool Blobs []kzg4844.Blob // Blobs needed by the blob pool
Commitments []kzg4844.Commitment // Commitments needed by the blob pool Commitments []kzg4844.Commitment // Commitments needed by the blob pool
Proofs []kzg4844.Proof // Proofs needed by the blob pool Proofs []kzg4844.Proof // Proofs needed by the blob pool
CellProofs [][]kzg4844.Proof // Cell proofs
} }
// BlobHashes computes the blob hashes of the given blobs. // BlobHashes computes the blob hashes of the given blobs.
@ -157,10 +158,15 @@ func (tx *BlobTx) copy() TxData {
cpy.S.Set(tx.S) cpy.S.Set(tx.S)
} }
if tx.Sidecar != nil { if tx.Sidecar != nil {
cellProofs := make([][]kzg4844.Proof, len(tx.Sidecar.CellProofs))
for i := range tx.Sidecar.CellProofs {
cellProofs[i] = append([]kzg4844.Proof(nil), tx.Sidecar.CellProofs[i]...)
}
cpy.Sidecar = &BlobTxSidecar{ cpy.Sidecar = &BlobTxSidecar{
Blobs: append([]kzg4844.Blob(nil), tx.Sidecar.Blobs...), Blobs: append([]kzg4844.Blob(nil), tx.Sidecar.Blobs...),
Commitments: append([]kzg4844.Commitment(nil), tx.Sidecar.Commitments...), Commitments: append([]kzg4844.Commitment(nil), tx.Sidecar.Commitments...),
Proofs: append([]kzg4844.Proof(nil), tx.Sidecar.Proofs...), Proofs: append([]kzg4844.Proof(nil), tx.Sidecar.Proofs...),
CellProofs: cellProofs,
} }
} }
return cpy return cpy
@ -252,10 +258,20 @@ func (tx *BlobTx) decode(input []byte) error {
return err return err
} }
*tx = *inner.BlobTx *tx = *inner.BlobTx
// compute the cell proof
cellProofs := make([][]kzg4844.Proof, 0)
for i := range len(inner.Blobs) {
cellProof, err := kzg4844.ComputeCells(&inner.Blobs[i])
if err != nil {
return err
}
cellProofs = append(cellProofs, cellProof)
}
tx.Sidecar = &BlobTxSidecar{ tx.Sidecar = &BlobTxSidecar{
Blobs: inner.Blobs, Blobs: inner.Blobs,
Commitments: inner.Commitments, Commitments: inner.Commitments,
Proofs: inner.Proofs, Proofs: inner.Proofs,
CellProofs: cellProofs,
} }
return nil return nil
} }

View file

@ -32,7 +32,6 @@ import (
"github.com/ethereum/go-ethereum/core/stateless" "github.com/ethereum/go-ethereum/core/stateless"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "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"
"github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/eth/ethconfig"
"github.com/ethereum/go-ethereum/internal/version" "github.com/ethereum/go-ethereum/internal/version"
@ -564,7 +563,7 @@ func (api *ConsensusAPI) GetBlobsV1(hashes []common.Hash) ([]*engine.BlobAndProo
} }
res := make([]*engine.BlobAndProofV1, len(hashes)) res := make([]*engine.BlobAndProofV1, len(hashes))
blobs, proofs := api.eth.TxPool().GetBlobs(hashes) blobs, proofs, _ := api.eth.TxPool().GetBlobs(hashes)
for i := 0; i < len(blobs); i++ { for i := 0; i < len(blobs); i++ {
if blobs[i] != nil { if blobs[i] != nil {
res[i] = &engine.BlobAndProofV1{ res[i] = &engine.BlobAndProofV1{
@ -583,15 +582,11 @@ func (api *ConsensusAPI) GetBlobsV2(hashes []common.Hash) ([]*engine.BlobAndProo
} }
res := make([]*engine.BlobAndProofV2, len(hashes)) res := make([]*engine.BlobAndProofV2, len(hashes))
blobs, _ := api.eth.TxPool().GetBlobs(hashes) blobs, _, cellProofs := api.eth.TxPool().GetBlobs(hashes)
for i := 0; i < len(blobs); i++ { for i := 0; i < len(blobs); i++ {
if blobs[i] != nil { if blobs[i] != nil {
cellProofs, err := kzg4844.ComputeCells(blobs[i])
if err != nil {
return nil, err
}
var proofs []hexutil.Bytes var proofs []hexutil.Bytes
for _, proof := range cellProofs { for _, proof := range cellProofs[i] {
proofs = append(proofs, hexutil.Bytes(proof[:])) proofs = append(proofs, hexutil.Bytes(proof[:]))
} }
res[i] = &engine.BlobAndProofV2{ res[i] = &engine.BlobAndProofV2{