From 2f9ab7d28f1ca9d11ec107682f4f82513beeea0f Mon Sep 17 00:00:00 2001 From: Francis Li Date: Wed, 19 Mar 2025 14:58:02 -0700 Subject: [PATCH] new commit --- core/txpool/blobpool/blobpool_test.go | 32 +++++++++++++++++++++++++++ core/txpool/errors.go | 3 +++ core/txpool/validation.go | 12 +++++----- crypto/kzg4844/kzg4844.go | 8 +++++++ 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index d9137cb679..289d7c902c 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -236,6 +236,25 @@ func makeMultiBlobTx(nonce uint64, gasTipCap uint64, gasFeeCap uint64, blobFeeCa return types.MustSignNewTx(key, types.LatestSigner(params.MainnetChainConfig), blobtx) } +func makeMultiBlobTxWithCellProofs(nonce uint64, gasTipCap uint64, gasFeeCap uint64, blobFeeCap uint64, blobCount int, key *ecdsa.PrivateKey) *types.Transaction { + tx := makeMultiBlobTx(nonce, gasTipCap, gasFeeCap, blobFeeCap, blobCount, key) + + proofs := make([]kzg4844.Proof, 0) + for i, blob := range tx.BlobTxSidecar().Blobs { + cps, err := kzg4844.ComputeCells(&blob) + if err != nil { + panic(err) + } + tx.BlobTxSidecar().Proofs = append(proofs, cps...) + } + tx.Sidecar.Proofs = make([]kzg4844.Proof, blobCount) + for i := 0; i < blobCount; i++ { + tx.Sidecar.Proofs[i] = testBlobProofs[i] + } + + return tx +} + // makeUnsignedTx is a utility method to construct a random blob transaction // without signing it. func makeUnsignedTx(nonce uint64, gasTipCap uint64, gasFeeCap uint64, blobFeeCap uint64) *types.BlobTx { @@ -1482,6 +1501,19 @@ func TestAdd(t *testing.T) { }, }, }, + // Testing blob transaction verification around Osaka fork boundary + { + seeds: map[string]seed{ + "alice": {balance: 10000000}, + }, + adds: []addtx{ + { // New account, no previous txs, nonce 0, but blob fee cap too low + from: "alice", + tx: makeUnsignedTxWithTestBlob(0, 1, 1, 1, 0), + err: nil, + }, + }, + }, // Tests issue #30518 where a refactor broke internal state invariants, // causing included transactions not to be properly accounted and thus // account states going our of sync with the chain. diff --git a/core/txpool/errors.go b/core/txpool/errors.go index c38644857e..2b7cede4f5 100644 --- a/core/txpool/errors.go +++ b/core/txpool/errors.go @@ -56,4 +56,7 @@ var ( // input transaction of non-blob type when a blob transaction from this sender // remains pending (and vice-versa). ErrAlreadyReserved = errors.New("address already reserved") + + // ErrInvalidBlobSidecar is returned if the blob sidecar is invalid. + ErrInvalidBlobSidecar = errors.New("invalid blob sidecar, incorrect proofs") ) diff --git a/core/txpool/validation.go b/core/txpool/validation.go index 4af2192b1f..e0074e9435 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -169,7 +169,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types func validateBlobSidecar(cfg *params.ChainConfig, time uint64, hashes []common.Hash, sidecar *types.BlobTxSidecar) error { if len(sidecar.Blobs) != len(hashes) { - return fmt.Errorf("invalid number of %d blobs compared to %d blob hashes", len(sidecar.Blobs), len(hashes)) + return fmt.Errorf("invalid number of %d blobs compared to %d blob hashes", ErrInvalidBlobSidecar, len(sidecar.Blobs), len(hashes)) } if err := sidecar.ValidateBlobCommitmentHashes(hashes); err != nil { return err @@ -178,7 +178,7 @@ func validateBlobSidecar(cfg *params.ChainConfig, time uint64, hashes []common.H fork := cfg.LatestFork(time) if fork >= forks.Osaka { if len(sidecar.Blobs)*goethkzg.CellsPerExtBlob != len(sidecar.Proofs) { - return fmt.Errorf("invalid number of %d cell proofs compared to %d blobs", len(sidecar.Proofs), len(sidecar.Blobs)) + return fmt.Errorf("invalid number of %d cell proofs compared to %d blobs", ErrInvalidBlobSidecar, len(sidecar.Proofs), len(sidecar.Blobs)) } // Prepare cells and cell indices for each blob @@ -189,7 +189,7 @@ func validateBlobSidecar(cfg *params.ChainConfig, time uint64, hashes []common.H // Compute cells for the currentblob blobCells, err := kzg4844.ComputeCells(&sidecar.Blobs[i]) if err != nil { - return fmt.Errorf("failed to compute cells for blob %d: %v", i, err) + return fmt.Errorf("failed to compute cells for blob %d: %v", ErrInvalidBlobSidecar, i, err) } cells = append(cells, blobCells...) @@ -199,18 +199,18 @@ func validateBlobSidecar(cfg *params.ChainConfig, time uint64, hashes []common.H } if err := kzg4844.VerifyCellKZGProofBatch(sidecar.Commitments, cellIndices, cells, sidecar.Proofs); err != nil { - return fmt.Errorf("failed to verify cell proofs: %v", err) + return fmt.Errorf("failed to verify cell proofs: %v", ErrInvalidBlobSidecar, err) } } else { // older folks if len(sidecar.Proofs) != len(hashes) { - return fmt.Errorf("invalid number of %d blob proofs compared to %d blob hashes", len(sidecar.Proofs), len(hashes)) + return fmt.Errorf("invalid number of %d blob proofs compared to %d blob hashes", ErrInvalidBlobSidecar, len(sidecar.Proofs), len(hashes)) } // Blob commitments match with the hashes in the transaction, verify the // blobs themselves via KZG for i := range sidecar.Blobs { if err := kzg4844.VerifyBlobProof(&sidecar.Blobs[i], sidecar.Commitments[i], sidecar.Proofs[i]); err != nil { - return fmt.Errorf("invalid blob %d: %v", i, err) + return fmt.Errorf("invalid blob %d: %v", ErrInvalidBlobSidecar, i, err) } } } diff --git a/crypto/kzg4844/kzg4844.go b/crypto/kzg4844/kzg4844.go index bcbcc5d3b5..e895b161f3 100644 --- a/crypto/kzg4844/kzg4844.go +++ b/crypto/kzg4844/kzg4844.go @@ -168,6 +168,14 @@ func ComputeCells(blob *Blob) ([]Cell, error) { return gokzgComputeCells(blob) } +// ComputeCellsAndKZGProofs computes the cells and KZG proofs for a given blob. +func ComputeCellsAndKZGProofs(blob *Blob) ([]Cell, []Proof, error) { + if useCKZG.Load() { + return ckzgComputeCellsAndKZGProofs(blob) + } + return gokzgComputeCellsAndKZGProofs(blob) +} + // CalcBlobHashV1 calculates the 'versioned blob hash' of a commitment. // The given hasher must be a sha256 hash instance, otherwise the result will be invalid! func CalcBlobHashV1(hasher hash.Hash, commit *Commitment) (vh [32]byte) {