From 33bb5f748d1153273c9e2227e28d5219788f8ded Mon Sep 17 00:00:00 2001 From: MariusVanDerWijden Date: Wed, 15 Oct 2025 12:04:41 +0200 Subject: [PATCH] signer/core/apitypes: add cell proofs --- signer/core/apitypes/types.go | 5 +- signer/core/apitypes/types_test.go | 172 +++++++++++++++++++++++++++++ 2 files changed, 174 insertions(+), 3 deletions(-) diff --git a/signer/core/apitypes/types.go b/signer/core/apitypes/types.go index a942931407..19323246a7 100644 --- a/signer/core/apitypes/types.go +++ b/signer/core/apitypes/types.go @@ -259,7 +259,7 @@ func (args *SendTxArgs) validateTxSidecar() error { if args.Commitments == nil { // Generate commitment and proof. commitments := make([]kzg4844.Commitment, n) - proofs := make([]kzg4844.Proof, n) + proofs := make([]kzg4844.Proof, 0, n) for i, b := range args.Blobs { c, err := kzg4844.BlobToCommitment(&b) if err != nil { @@ -275,14 +275,13 @@ func (args *SendTxArgs) validateTxSidecar() error { } proofs = append(proofs, p...) } - } else { for i, b := range args.Blobs { p, err := kzg4844.ComputeBlobProof(&b, commitments[i]) if err != nil { return fmt.Errorf("blobs[%d]: error computing proof: %v", i, err) } - proofs[i] = p + proofs = append(proofs, p) } } args.Commitments = commitments diff --git a/signer/core/apitypes/types_test.go b/signer/core/apitypes/types_test.go index ab9d1b22d8..3e8f3bd43b 100644 --- a/signer/core/apitypes/types_test.go +++ b/signer/core/apitypes/types_test.go @@ -17,8 +17,10 @@ package apitypes import ( + "crypto/rand" "crypto/sha256" "encoding/json" + "fmt" "testing" "github.com/ethereum/go-ethereum/common" @@ -229,3 +231,173 @@ func TestType_TypeName(t *testing.T) { } } } + +func TestValidateTxSidecar(t *testing.T) { + t.Parallel() + + // Helper function to create a test blob and its commitment/proof + createTestBlob := func() (kzg4844.Blob, kzg4844.Commitment, kzg4844.Proof, common.Hash) { + b := make([]byte, 31) + rand.Read(b) + var blob kzg4844.Blob + for i := range b { + blob[i+1] = b[i] + } + commitment, err := kzg4844.BlobToCommitment(&blob) + if err != nil { + t.Fatal(err) + } + proof, err := kzg4844.ComputeBlobProof(&blob, commitment) + if err != nil { + t.Fatal(err) + } + hash := kzg4844.CalcBlobHashV1(sha256.New(), &commitment) + return blob, commitment, proof, hash + } + + // Helper function to create test cell proofs for v1 transactions + createTestCellProofs := func(blob kzg4844.Blob) []kzg4844.Proof { + cellProofs, err := kzg4844.ComputeCellProofs(&blob) + if err != nil { + t.Fatal(err) + } + return cellProofs + } + + blob1, commitment1, proof1, hash1 := createTestBlob() + blob2, commitment2, proof2, hash2 := createTestBlob() + + tests := []struct { + name string + args SendTxArgs + wantErr bool + }{ + { + name: "no blobs - should pass", + args: SendTxArgs{}, + wantErr: false, + }, + { + name: "valid blobs with commitments and proofs", + args: SendTxArgs{ + Blobs: []kzg4844.Blob{blob1, blob2}, + Commitments: []kzg4844.Commitment{commitment1, commitment2}, + Proofs: []kzg4844.Proof{proof1, proof2}, + BlobHashes: []common.Hash{hash1, hash2}, + }, + wantErr: false, + }, + { + name: "valid blobs without commitments/proofs - should generate them", + args: SendTxArgs{ + Blobs: []kzg4844.Blob{blob1}, + }, + wantErr: false, + }, + { + name: "valid blobs with v1 cell proofs", + args: SendTxArgs{ + Blobs: []kzg4844.Blob{blob1}, + Commitments: []kzg4844.Commitment{commitment1}, + Proofs: createTestCellProofs(blob1), + BlobHashes: []common.Hash{hash1}, + }, + wantErr: false, + }, + { + name: "blobs with v1 version flag - should generate cell proofs", + args: SendTxArgs{ + Blobs: []kzg4844.Blob{blob1}, + BlobVersion: 1, + }, + wantErr: false, + }, + { + name: "proofs provided but commitments not", + args: SendTxArgs{ + Blobs: []kzg4844.Blob{blob1}, + Proofs: []kzg4844.Proof{proof1}, + }, + wantErr: true, + }, + { + name: "commitments provided but proofs not", + args: SendTxArgs{ + Blobs: []kzg4844.Blob{blob1}, + Commitments: []kzg4844.Commitment{commitment1}, + }, + wantErr: true, + }, + { + name: "mismatch between blobs and commitments", + args: SendTxArgs{ + Blobs: []kzg4844.Blob{blob1, blob2}, + Commitments: []kzg4844.Commitment{commitment1}, // Only one commitment for two blobs + Proofs: []kzg4844.Proof{proof1}, + }, + wantErr: true, + }, + { + name: "mismatch between blobs and hashes", + args: SendTxArgs{ + Blobs: []kzg4844.Blob{blob1, blob2}, + Commitments: []kzg4844.Commitment{commitment1, commitment2}, + Proofs: []kzg4844.Proof{proof1, proof2}, + BlobHashes: []common.Hash{hash1}, // Only one hash for two blobs + }, + wantErr: true, + }, + { + name: "wrong number of proofs", + args: SendTxArgs{ + Blobs: []kzg4844.Blob{blob1, blob2}, + Commitments: []kzg4844.Commitment{commitment1, commitment2}, + Proofs: []kzg4844.Proof{proof1, proof2, proof1}, // 3 proofs for 2 blobs + }, + wantErr: true, + }, + { + name: "invalid blob hash", + args: SendTxArgs{ + Blobs: []kzg4844.Blob{blob1}, + Commitments: []kzg4844.Commitment{commitment1}, + Proofs: []kzg4844.Proof{proof1}, + BlobHashes: []common.Hash{hash2}, // Wrong hash + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Make a copy to avoid modifying the original test case + args := tt.args + err := args.validateTxSidecar() + + if tt.wantErr { + if err == nil { + t.Errorf("validateTxSidecar() expected error but got none") + return + } + } else { + if err != nil { + t.Errorf("validateTxSidecar() unexpected error = %v", err) + } + + // For successful cases, verify that commitments and proofs were generated if they weren't provided + if len(args.Blobs) > 0 { + if args.Commitments == nil || len(args.Commitments) != len(args.Blobs) { + t.Errorf("validateTxSidecar() should have generated commitments") + } + if args.Proofs == nil || (len(args.Proofs) != len(args.Blobs) && len(args.Proofs) != len(args.Blobs)*kzg4844.CellProofsPerBlob) { + fmt.Println("proofs", args.Proofs) + t.Errorf("validateTxSidecar() should have generated proofs") + } + if args.BlobHashes == nil || len(args.BlobHashes) != len(args.Blobs) { + t.Errorf("validateTxSidecar() should have generated blob hashes") + } + } + } + }) + } +}