Skip to content
Merged
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
24 changes: 13 additions & 11 deletions op-program/host/prefetcher/prefetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ type L1Source interface {
}

type L1BlobSource interface {
GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.BlobSidecar, error)
GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error)
}

Expand Down Expand Up @@ -325,35 +324,38 @@ func (p *Prefetcher) prefetch(ctx context.Context, hint string) error {
blobHashIndex := binary.BigEndian.Uint64(hintBytes[32:40])
refTimestamp := binary.BigEndian.Uint64(hintBytes[40:48])

// Fetch the blob sidecar for the indexed blob hash passed in the hint.
// Fetch the blob for the indexed blob hash passed in the hint.
indexedBlobHash := eth.IndexedBlobHash{
Hash: blobVersionHash,
Index: blobHashIndex,
}
// We pass an `eth.L1BlockRef`, but `GetBlobSidecars` only uses the timestamp, which we received in the hint.
sidecars, err := p.l1BlobFetcher.GetBlobSidecars(ctx, eth.L1BlockRef{Time: refTimestamp}, []eth.IndexedBlobHash{indexedBlobHash})
if err != nil || len(sidecars) != 1 {
return fmt.Errorf("failed to fetch blob sidecars for %s %d: %w", blobVersionHash, blobHashIndex, err)
// We pass an `eth.L1BlockRef`, but `GetBlobs` only uses the timestamp, which we received in the hint.
blobs, err := p.l1BlobFetcher.GetBlobs(ctx, eth.L1BlockRef{Time: refTimestamp}, []eth.IndexedBlobHash{indexedBlobHash})
if err != nil || len(blobs) != 1 {
return fmt.Errorf("failed to fetch blobs for %s %d: %w", blobVersionHash, blobHashIndex, err)
}
blob := blobs[0]
kzgCommitment, err := blob.ComputeKZGCommitment()
if err != nil {
return fmt.Errorf("failed to compute KZG commitment for blob: %w", err)
}
sidecar := sidecars[0]

// Put the preimage for the versioned hash into the kv store
if err = p.kvStore.Put(preimage.Sha256Key(blobVersionHash).PreimageKey(), sidecar.KZGCommitment[:]); err != nil {
if err = p.kvStore.Put(preimage.Sha256Key(blobVersionHash).PreimageKey(), kzgCommitment[:]); err != nil {
return err
}

// Put all of the blob's field elements into the kv store. There should be 4096. The preimage oracle key for
// each field element is the keccak256 hash of `abi.encodePacked(sidecar.KZGCommitment, RootsOfUnity[i])`
blobKey := make([]byte, 80)
copy(blobKey[:48], sidecar.KZGCommitment[:])
copy(blobKey[:48], kzgCommitment[:])
for i := 0; i < params.BlobTxFieldElementsPerBlob; i++ {
rootOfUnity := l1.RootsOfUnity[i].Bytes()
copy(blobKey[48:], rootOfUnity[:])
blobKeyHash := crypto.Keccak256Hash(blobKey)
if err := p.kvStore.Put(preimage.Keccak256Key(blobKeyHash).PreimageKey(), blobKey); err != nil {
return err
}
if err = p.kvStore.Put(preimage.BlobKey(blobKeyHash).PreimageKey(), sidecar.Blob[i<<5:(i+1)<<5]); err != nil {
if err = p.kvStore.Put(preimage.BlobKey(blobKeyHash).PreimageKey(), blob[i<<5:(i+1)<<5]); err != nil {
return err
}
}
Expand Down
3 changes: 1 addition & 2 deletions op-program/host/prefetcher/prefetcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,10 @@ func TestFetchL1Blob(t *testing.T) {
prefetcher, _, blobFetcher, _, _ := createPrefetcher(t)

oracle := l1.NewPreimageOracle(asOracleFn(t, prefetcher), asHinter(t, prefetcher))
blobFetcher.ExpectOnGetBlobSidecars(
blobFetcher.ExpectOnGetBlobs(
context.Background(),
l1Ref,
[]eth.IndexedBlobHash{blobHash},
(eth.Bytes48)(commitment),
[]*eth.Blob{&blob},
nil,
)
Expand Down
10 changes: 0 additions & 10 deletions op-program/host/prefetcher/retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,6 @@ func NewRetryingL1BlobSource(logger log.Logger, source L1BlobSource) *RetryingL1
}
}

func (s *RetryingL1BlobSource) GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.BlobSidecar, error) {
return retry.Do(ctx, maxAttempts, s.strategy, func() ([]*eth.BlobSidecar, error) {
sidecars, err := s.source.GetBlobSidecars(ctx, ref, hashes)
if err != nil {
s.logger.Warn("Failed to retrieve blob sidecars", "ref", ref, "err", err)
}
return sidecars, err
})
}

func (s *RetryingL1BlobSource) GetBlobs(ctx context.Context, ref eth.L1BlockRef, hashes []eth.IndexedBlobHash) ([]*eth.Blob, error) {
return retry.Do(ctx, maxAttempts, s.strategy, func() ([]*eth.Blob, error) {
blobs, err := s.source.GetBlobs(ctx, ref, hashes)
Expand Down
49 changes: 0 additions & 49 deletions op-program/host/prefetcher/retry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,55 +163,6 @@ func TestRetryingL1BlobSource(t *testing.T) {
require.Equal(t, len(result), 1)
require.Equal(t, blob[:], result[0][:])
})

t.Run("GetBlobSidecars Success", func(t *testing.T) {
source, mock := createL1BlobSource(t)
defer mock.AssertExpectations(t)
mock.ExpectOnGetBlobSidecars(
ctx,
l1BlockRef,
[]eth.IndexedBlobHash{blobHash},
(eth.Bytes48)(commitment),
[]*eth.Blob{(*eth.Blob)(&blob)},
nil,
)

result, err := source.GetBlobSidecars(ctx, l1BlockRef, []eth.IndexedBlobHash{blobHash})
require.NoError(t, err)
require.Equal(t, len(result), 1)
require.Equal(t, blob[:], result[0].Blob[:])
require.Equal(t, blobHash.Index, uint64(result[0].Index))
require.Equal(t, (eth.Bytes48)(commitment), result[0].KZGCommitment)
})

t.Run("GetBlobSidecars Error", func(t *testing.T) {
source, mock := createL1BlobSource(t)
defer mock.AssertExpectations(t)
expectedErr := errors.New("boom")
mock.ExpectOnGetBlobSidecars(
ctx,
l1BlockRef,
[]eth.IndexedBlobHash{blobHash},
(eth.Bytes48)(commitment),
[]*eth.Blob{(*eth.Blob)(&blob)},
expectedErr,
)
mock.ExpectOnGetBlobSidecars(
ctx,
l1BlockRef,
[]eth.IndexedBlobHash{blobHash},
(eth.Bytes48)(commitment),
[]*eth.Blob{(*eth.Blob)(&blob)},
nil,
)

result, err := source.GetBlobSidecars(ctx, l1BlockRef, []eth.IndexedBlobHash{blobHash})
require.NoError(t, err)
require.Equal(t, len(result), 1)
require.Equal(t, blob[:], result[0].Blob[:])
require.Equal(t, blobHash.Index, uint64(result[0].Index))
require.Equal(t, (eth.Bytes48)(commitment), result[0].KZGCommitment)
})
}

func createL1BlobSource(t *testing.T) (*RetryingL1BlobSource, *testutils.MockBlobsFetcher) {
Expand Down