Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 11 additions & 16 deletions op-e2e/e2eutils/blobstore/blobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}

func (store *Store) GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.BlobSidecar, error) {
Expand All @@ -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, &eth.BlobSidecar{
Index: eth.Uint64String(h.Index),
Blob: *b,
Expand Down
6 changes: 3 additions & 3 deletions op-service/sources/l1_beacon_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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))
}
Expand Down
16 changes: 8 additions & 8 deletions op-service/sources/l1_beacon_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)

}
Expand Down Expand Up @@ -131,15 +131,15 @@ 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)

}

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")
}
Expand Down