From 887849b3d0833d1e61e7f781849ca50d3d312378 Mon Sep 17 00:00:00 2001 From: geoknee Date: Mon, 6 Oct 2025 13:59:29 +0100 Subject: [PATCH 1/2] op-e2e: replicate stubbed kzg proof in GetBlobs --- op-e2e/e2eutils/blobstore/blobs.go | 27 +++++++++------------ op-service/sources/l1_beacon_client.go | 4 +-- op-service/sources/l1_beacon_client_test.go | 18 +++++++------- 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/op-e2e/e2eutils/blobstore/blobs.go b/op-e2e/e2eutils/blobstore/blobs.go index 45fcc5dfdddcd..7d0a07c6ab777 100644 --- a/op-e2e/e2eutils/blobstore/blobs.go +++ b/op-e2e/e2eutils/blobstore/blobs.go @@ -5,10 +5,12 @@ import ( "fmt" "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-service/eth" + "github.com/ethereum-optimism/optimism/op-service/sources" ) // Store is a simple in-memory store of blobs, for testing purposes @@ -31,19 +33,11 @@ func (store *Store) StoreBlob(blockTime uint64, indexedHash eth.IndexedBlobHash, } func (store *Store) GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) { - out := make([]*eth.Blob, 0, len(hashes)) - m, ok := store.blobs[ref.Time] - if !ok { - return nil, fmt.Errorf("no blobs known with given time: %w", ethereum.NotFound) - } - for _, h := range hashes { - b, ok := m[h] - if !ok { - return nil, fmt.Errorf("blob %d %s is not in store: %w", h.Index, h.Hash, ethereum.NotFound) - } - out = append(out, b) + out, err := store.GetBlobSidecars(ctx, ref, hashes) + if err != nil { + return nil, err } - return out, nil + return sources.BlobsFromSidecars(out, hashes, false) } func (store *Store) GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.BlobSidecar, error) { @@ -65,10 +59,11 @@ func (store *Store) GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef, has if err != nil { return nil, fmt.Errorf("failed to convert blob to commitment: %w", err) } - proof, err := kzg4844.ComputeBlobProof(b.KZGBlob(), commitment) - if err != nil { - return nil, fmt.Errorf("failed to compute blob proof: %w", err) - } + + // From Fulu onwards, a blob proof is not provided. + // Derivation should not rely on a valid proof here. + proof := kzg4844.Proof(hexutil.MustDecode("0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) + out = append(out, ð.BlobSidecar{ Index: eth.Uint64String(h.Index), Blob: *b, diff --git a/op-service/sources/l1_beacon_client.go b/op-service/sources/l1_beacon_client.go index f6586de8d40d4..d9871f7535500 100644 --- a/op-service/sources/l1_beacon_client.go +++ b/op-service/sources/l1_beacon_client.go @@ -272,14 +272,14 @@ func (cl *L1BeaconClient) GetBlobs(ctx context.Context, ref eth.L1BlockRef, hash if err != nil { return nil, fmt.Errorf("failed to get blob sidecars for L1BlockRef %s: %w", ref, err) } - blobs, err := blobsFromSidecars(blobSidecars, hashes, cl.cfg.SkipBlobVerification) + blobs, err := BlobsFromSidecars(blobSidecars, hashes, cl.cfg.SkipBlobVerification) if err != nil { return nil, fmt.Errorf("failed to get blobs from sidecars for L1BlockRef %s: %w", ref, err) } return blobs, nil } -func blobsFromSidecars(blobSidecars []*eth.BlobSidecar, hashes []eth.IndexedBlobHash, skipBlobVerification bool) ([]*eth.Blob, error) { +func BlobsFromSidecars(blobSidecars []*eth.BlobSidecar, hashes []eth.IndexedBlobHash, skipBlobVerification bool) ([]*eth.Blob, error) { if len(blobSidecars) != len(hashes) { return nil, fmt.Errorf("number of hashes and blobSidecars mismatch, %d != %d", len(hashes), len(blobSidecars)) } diff --git a/op-service/sources/l1_beacon_client_test.go b/op-service/sources/l1_beacon_client_test.go index 2a6cfafba0a03..1a975db242ef0 100644 --- a/op-service/sources/l1_beacon_client_test.go +++ b/op-service/sources/l1_beacon_client_test.go @@ -63,17 +63,17 @@ func TestBlobsFromSidecars(t *testing.T) { // put the sidecars in scrambled order to confirm error sidecars := []*eth.BlobSidecar{sidecar2, sidecar0, sidecar1} - _, err := blobsFromSidecars(sidecars, hashes, false) + _, err := BlobsFromSidecars(sidecars, hashes, false) require.Error(t, err) // too few sidecars should error sidecars = []*eth.BlobSidecar{sidecar0, sidecar1} - _, err = blobsFromSidecars(sidecars, hashes, false) + _, err = BlobsFromSidecars(sidecars, hashes, false) require.Error(t, err) // correct order should work sidecars = []*eth.BlobSidecar{sidecar0, sidecar1, sidecar2} - blobs, err := blobsFromSidecars(sidecars, hashes, false) + blobs, err := BlobsFromSidecars(sidecars, hashes, false) require.NoError(t, err) // confirm order by checking first blob byte against expected index for i := range blobs { @@ -84,20 +84,20 @@ func TestBlobsFromSidecars(t *testing.T) { badProof := *sidecar0 badProof.KZGProof[11]++ sidecars[1] = &badProof - _, err = blobsFromSidecars(sidecars, hashes, false) + _, err = BlobsFromSidecars(sidecars, hashes, false) require.Error(t, err) // mangle a commitment to make sure it's detected badCommitment := *sidecar0 badCommitment.KZGCommitment[13]++ sidecars[1] = &badCommitment - _, err = blobsFromSidecars(sidecars, hashes, false) + _, err = BlobsFromSidecars(sidecars, hashes, false) require.Error(t, err) // mangle a hash to make sure it's detected sidecars[1] = sidecar0 hashes[2].Hash[17]++ - _, err = blobsFromSidecars(sidecars, hashes, false) + _, err = BlobsFromSidecars(sidecars, hashes, false) require.Error(t, err) } @@ -130,11 +130,11 @@ func TestBlobsFromSidecars_SkipBlobVerification(t *testing.T) { sidecars[1].KZGProof = eth.Bytes48(badProof) // Check that verification succeeds when skipBlobVerification is true - _, err := blobsFromSidecars(sidecars, hashes, true) + _, err := BlobsFromSidecars(sidecars, hashes, true) require.NoError(t, err) // Check that verification fails when skipBlobVerification is false - _, err = blobsFromSidecars(sidecars, hashes, false) + _, err = BlobsFromSidecars(sidecars, hashes, false) require.Error(t, err) } @@ -142,7 +142,7 @@ func TestBlobsFromSidecars_SkipBlobVerification(t *testing.T) { func TestBlobsFromSidecars_EmptySidecarList(t *testing.T) { hashes := []eth.IndexedBlobHash{} sidecars := []*eth.BlobSidecar{} - blobs, err := blobsFromSidecars(sidecars, hashes, false) + blobs, err := BlobsFromSidecars(sidecars, hashes, false) require.NoError(t, err) require.Empty(t, blobs, "blobs should be empty when no sidecars are provided") } From e6e7054fbff3426142c116518fdb3a8fb952da7b Mon Sep 17 00:00:00 2001 From: geoknee Date: Tue, 7 Oct 2025 13:56:43 +0100 Subject: [PATCH 2/2] post merge fixes --- op-e2e/e2eutils/blobstore/blobs.go | 2 +- op-service/sources/l1_beacon_client.go | 6 +++--- op-service/sources/l1_beacon_client_test.go | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/op-e2e/e2eutils/blobstore/blobs.go b/op-e2e/e2eutils/blobstore/blobs.go index 7d0a07c6ab777..b6c595b65be08 100644 --- a/op-e2e/e2eutils/blobstore/blobs.go +++ b/op-e2e/e2eutils/blobstore/blobs.go @@ -37,7 +37,7 @@ func (store *Store) GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []e if err != nil { return nil, err } - return sources.BlobsFromSidecars(out, hashes, false) + return sources.BlobsFromSidecars(out, hashes) } func (store *Store) GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.BlobSidecar, error) { diff --git a/op-service/sources/l1_beacon_client.go b/op-service/sources/l1_beacon_client.go index c5aa3afbb8607..f09a59380fea2 100644 --- a/op-service/sources/l1_beacon_client.go +++ b/op-service/sources/l1_beacon_client.go @@ -312,7 +312,7 @@ func (cl *L1BeaconClient) GetBlobs(ctx context.Context, ref eth.L1BlockRef, hash if err != nil { return nil, fmt.Errorf("failed to get blob sidecars for L1BlockRef %s: %w", ref, err) } - blobs, err := blobsFromSidecars(blobSidecars, hashes) + blobs, err := BlobsFromSidecars(blobSidecars, hashes) if err != nil { return nil, fmt.Errorf("failed to get blobs from sidecars for L1BlockRef %s: %w", ref, err) } @@ -326,8 +326,8 @@ func (cl *L1BeaconClient) GetBlobs(ctx context.Context, ref eth.L1BlockRef, hash return blobs, nil } -// blobsFromSidecars pulls the blobs from the sidecars and verifies them against the supplied hashes. -func blobsFromSidecars(blobSidecars []*eth.BlobSidecar, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) { +// BlobsFromSidecars pulls the blobs from the sidecars and verifies them against the supplied hashes. +func BlobsFromSidecars(blobSidecars []*eth.BlobSidecar, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) { if len(blobSidecars) != len(hashes) { return nil, fmt.Errorf("number of hashes and blobSidecars mismatch, %d != %d", len(hashes), len(blobSidecars)) } diff --git a/op-service/sources/l1_beacon_client_test.go b/op-service/sources/l1_beacon_client_test.go index 38c02b1de5184..7947f34dc78f2 100644 --- a/op-service/sources/l1_beacon_client_test.go +++ b/op-service/sources/l1_beacon_client_test.go @@ -64,17 +64,17 @@ func TestBlobsFromSidecars(t *testing.T) { // put the sidecars in scrambled order to confirm error sidecars := []*eth.BlobSidecar{sidecar2, sidecar0, sidecar1} - _, err := blobsFromSidecars(sidecars, hashes) + _, err := BlobsFromSidecars(sidecars, hashes) require.Error(t, err) // too few sidecars should error sidecars = []*eth.BlobSidecar{sidecar0, sidecar1} - _, err = blobsFromSidecars(sidecars, hashes) + _, err = BlobsFromSidecars(sidecars, hashes) require.Error(t, err) // correct order should work sidecars = []*eth.BlobSidecar{sidecar0, sidecar1, sidecar2} - blobs, err := blobsFromSidecars(sidecars, hashes) + blobs, err := BlobsFromSidecars(sidecars, hashes) require.NoError(t, err) // confirm order by checking first blob byte against expected index for i := range blobs { @@ -85,20 +85,20 @@ func TestBlobsFromSidecars(t *testing.T) { badProof := *sidecar0 badProof.KZGProof[11]++ sidecars[1] = &badProof - _, err = blobsFromSidecars(sidecars, hashes) + _, err = BlobsFromSidecars(sidecars, hashes) require.Error(t, err) // mangle a commitment to make sure it's detected badCommitment := *sidecar0 badCommitment.KZGCommitment[13]++ sidecars[1] = &badCommitment - _, err = blobsFromSidecars(sidecars, hashes) + _, err = BlobsFromSidecars(sidecars, hashes) require.Error(t, err) // mangle a hash to make sure it's detected sidecars[1] = sidecar0 hashes[2].Hash[17]++ - _, err = blobsFromSidecars(sidecars, hashes) + _, err = BlobsFromSidecars(sidecars, hashes) require.Error(t, err) } @@ -131,7 +131,7 @@ func TestBlobsFromSidecars_BadProof(t *testing.T) { sidecars[1].KZGProof = eth.Bytes48(badProof) // Check that verification succeeds, the proof is not required - _, err := blobsFromSidecars(sidecars, hashes) + _, err := BlobsFromSidecars(sidecars, hashes) require.NoError(t, err) } @@ -139,7 +139,7 @@ func TestBlobsFromSidecars_BadProof(t *testing.T) { func TestBlobsFromSidecars_EmptySidecarList(t *testing.T) { hashes := []eth.IndexedBlobHash{} sidecars := []*eth.BlobSidecar{} - blobs, err := blobsFromSidecars(sidecars, hashes) + blobs, err := BlobsFromSidecars(sidecars, hashes) require.NoError(t, err) require.Empty(t, blobs, "blobs should be empty when no sidecars are provided") }