From bbe4a40fd9582ebfed958c5d4abf3ca6f9279ec1 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Mon, 31 Mar 2025 17:29:17 +0200 Subject: [PATCH] core/types: compute cellproofs on transaction submission --- core/txpool/blobpool/blobpool.go | 10 ++++++---- core/txpool/blobpool/blobpool_test.go | 2 +- core/txpool/legacypool/legacypool.go | 4 ++-- core/txpool/subpool.go | 2 +- core/txpool/txpool.go | 8 ++++---- core/types/tx_blob.go | 16 ++++++++++++++++ eth/catalyst/api.go | 11 +++-------- 7 files changed, 33 insertions(+), 20 deletions(-) diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index e506da228d..e0792d5ba4 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -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. // This is a utility method for the engine API, enabling consensus clients to // 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 var ( - blobs = make([]*kzg4844.Blob, len(vhashes)) - proofs = make([]*kzg4844.Proof, len(vhashes)) + blobs = make([]*kzg4844.Blob, len(vhashes)) + proofs = make([]*kzg4844.Proof, len(vhashes)) + cell_proofs = make([][]kzg4844.Proof, len(vhashes)) ) index := make(map[common.Hash]int) 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 { blobs[idx] = &sidecar.Blobs[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 diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index 0a323179a6..ed4ef963ae 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -417,7 +417,7 @@ func verifyBlobRetrievals(t *testing.T, pool *BlobPool) { for i := range testBlobVHashes { copy(hashes[i][:], testBlobVHashes[i][:]) } - blobs, proofs := pool.GetBlobs(hashes) + blobs, proofs, _ := pool.GetBlobs(hashes) // Cross validate what we received vs what we wanted if len(blobs) != len(hashes) || len(proofs) != len(hashes) { diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 0223b456e6..e5f354d1e6 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -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 // implement the txpool.SubPool interface. -func (pool *LegacyPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Proof) { - return nil, nil +func (pool *LegacyPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Proof, [][]kzg4844.Proof) { + return nil, nil, nil } // Has returns an indicator whether txpool has a transaction cached with the diff --git a/core/txpool/subpool.go b/core/txpool/subpool.go index 8cfc14f164..95607b9bc8 100644 --- a/core/txpool/subpool.go +++ b/core/txpool/subpool.go @@ -136,7 +136,7 @@ type SubPool interface { // 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 // 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 // rules, but does not check state-dependent validation such as sufficient balance. diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index cc8f74c1b8..4e62b5a839 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -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. // This is a utility method for the engine API, enabling consensus clients to // 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 { // 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 // partial responses and that's too annoying to do until we get a second // blobpool (probably never). - if blobs, proofs := subpool.GetBlobs(vhashes); blobs != nil { - return blobs, proofs + if blobs, proofs, cellProofs := subpool.GetBlobs(vhashes); blobs != nil { + 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 diff --git a/core/types/tx_blob.go b/core/types/tx_blob.go index 9b1d53958f..393ad84978 100644 --- a/core/types/tx_blob.go +++ b/core/types/tx_blob.go @@ -58,6 +58,7 @@ type BlobTxSidecar struct { Blobs []kzg4844.Blob // Blobs needed by the blob pool Commitments []kzg4844.Commitment // Commitments 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. @@ -157,10 +158,15 @@ func (tx *BlobTx) copy() TxData { cpy.S.Set(tx.S) } 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{ Blobs: append([]kzg4844.Blob(nil), tx.Sidecar.Blobs...), Commitments: append([]kzg4844.Commitment(nil), tx.Sidecar.Commitments...), Proofs: append([]kzg4844.Proof(nil), tx.Sidecar.Proofs...), + CellProofs: cellProofs, } } return cpy @@ -252,10 +258,20 @@ func (tx *BlobTx) decode(input []byte) error { return err } *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{ Blobs: inner.Blobs, Commitments: inner.Commitments, Proofs: inner.Proofs, + CellProofs: cellProofs, } return nil } diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index d56be81cfa..40f4a456e8 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -32,7 +32,6 @@ 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" @@ -564,7 +563,7 @@ func (api *ConsensusAPI) GetBlobsV1(hashes []common.Hash) ([]*engine.BlobAndProo } 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++ { if blobs[i] != nil { res[i] = &engine.BlobAndProofV1{ @@ -583,15 +582,11 @@ func (api *ConsensusAPI) GetBlobsV2(hashes []common.Hash) ([]*engine.BlobAndProo } 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++ { if blobs[i] != nil { - cellProofs, err := kzg4844.ComputeCells(blobs[i]) - if err != nil { - return nil, err - } var proofs []hexutil.Bytes - for _, proof := range cellProofs { + for _, proof := range cellProofs[i] { proofs = append(proofs, hexutil.Bytes(proof[:])) } res[i] = &engine.BlobAndProofV2{