Commit 0b20d8eb authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

op-program: Inject prefetcher instead of setting code in config (#11902)

* op-program: Support injecting a Prefetcher creator rather than setting code on the Config object.

* op-program: Use an interface for the Prefetcher instead of requiring a concrete type.
parent d5957fad
......@@ -3,6 +3,7 @@ package actions
import (
"math/big"
"github.com/ethereum-optimism/optimism/op-program/host/prefetcher"
"github.com/stretchr/testify/require"
"github.com/ethereum/go-ethereum/common"
......@@ -17,7 +18,6 @@ import (
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-program/host/sources"
"github.com/ethereum-optimism/optimism/op-service/eth"
)
......@@ -52,7 +52,7 @@ func NewL1Miner(t Testing, log log.Logger, genesis *core.Genesis) *L1Miner {
}
}
func (s *L1Miner) BlobStore() sources.L1BlobSource {
func (s *L1Miner) BlobStore() prefetcher.L1BlobSource {
return s.blobStore
}
......
......@@ -119,7 +119,7 @@ func runChannelTimeoutTest(gt *testing.T, checkResult func(gt *testing.T, err er
require.EqualValues(t, NumL2Blocks, l2SafeHead.Number.Uint64())
// Run the FPP on L2 block # NumL2Blocks/2.
err := env.RunFaultProofProgram(t, gt, NumL2Blocks/2, inputParams...)
err := env.RunFaultProofProgram(t, NumL2Blocks/2, inputParams...)
checkResult(gt, err)
}
......
package proofs
import (
"context"
"math/rand"
"testing"
altda "github.com/ethereum-optimism/optimism/op-alt-da"
batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags"
......@@ -10,6 +10,8 @@ import (
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-program/host"
"github.com/ethereum-optimism/optimism/op-program/host/config"
"github.com/ethereum-optimism/optimism/op-program/host/kvstore"
"github.com/ethereum-optimism/optimism/op-program/host/prefetcher"
hostTypes "github.com/ethereum-optimism/optimism/op-program/host/types"
"github.com/ethereum-optimism/optimism/op-service/sources"
"github.com/ethereum-optimism/optimism/op-service/testlog"
......@@ -90,7 +92,7 @@ func NewL2FaultProofEnv(t actions.Testing, tp *e2eutils.TestParams, dp *e2eutils
type FixtureInputParam func(f *FixtureInputs)
func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, gt *testing.T, l2ClaimBlockNum uint64, fixtureInputParams ...FixtureInputParam) error {
func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, l2ClaimBlockNum uint64, fixtureInputParams ...FixtureInputParam) error {
// Fetch the pre and post output roots for the fault proof.
preRoot, err := env.sequencer.RollupClient().OutputAtBlock(t.Ctx(), l2ClaimBlockNum-1)
require.NoError(t, err)
......@@ -116,8 +118,22 @@ func (env *L2FaultProofEnv) RunFaultProofProgram(t actions.Testing, gt *testing.
env,
fixtureInputs,
)
err = host.FaultProofProgram(t.Ctx(), env.log, programCfg)
tryDumpTestFixture(gt, err, t.Name(), env, programCfg)
withInProcessPrefetcher := host.WithPrefetcher(func(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *config.Config) (host.Prefetcher, error) {
// Set up in-process L1 sources
l1Cl := env.miner.L1Client(t, env.sd.RollupCfg)
l1BlobFetcher := env.miner.BlobStore()
// Set up in-process L2 source
l2ClCfg := sources.L2ClientDefaultConfig(env.sd.RollupCfg, true)
l2RPC := env.engine.RPCClient()
l2Client, err := host.NewL2Client(l2RPC, env.log, nil, &host.L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: cfg.L2Head})
require.NoError(t, err, "failed to create L2 client")
l2DebugCl := &host.L2Source{L2Client: l2Client, DebugClient: sources.NewDebugClient(l2RPC.CallContext)}
return prefetcher.NewPrefetcher(logger, l1Cl, l1BlobFetcher, l2DebugCl, kv), nil
})
err = host.FaultProofProgram(t.Ctx(), env.log, programCfg, withInProcessPrefetcher)
tryDumpTestFixture(t, err, t.Name(), env, programCfg)
return err
}
......@@ -165,18 +181,6 @@ func NewOpProgramCfg(
) *config.Config {
dfault := config.NewConfig(env.sd.RollupCfg, env.sd.L2Cfg.Config, fi.L1Head, fi.L2Head, fi.L2OutputRoot, fi.L2Claim, fi.L2BlockNumber)
// Set up in-process L1 sources
dfault.L1ProcessSource = env.miner.L1Client(t, env.sd.RollupCfg)
dfault.L1BeaconProcessSource = env.miner.BlobStore()
// Set up in-process L2 source
l2ClCfg := sources.L2ClientDefaultConfig(env.sd.RollupCfg, true)
l2RPC := env.engine.RPCClient()
l2Client, err := host.NewL2Client(l2RPC, env.log, nil, &host.L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: fi.L2Head})
require.NoError(t, err, "failed to create L2 client")
l2DebugCl := &host.L2Source{L2Client: l2Client, DebugClient: sources.NewDebugClient(l2RPC.CallContext)}
dfault.L2ProcessSource = l2DebugCl
if dumpFixtures {
dfault.DataDir = t.TempDir()
dfault.DataFormat = hostTypes.DataFormatPebble
......
......@@ -7,8 +7,8 @@ import (
"os"
"os/exec"
"path/filepath"
"testing"
"github.com/ethereum-optimism/optimism/op-e2e/actions"
"github.com/ethereum-optimism/optimism/op-program/client/claim"
"github.com/ethereum-optimism/optimism/op-program/host/config"
"github.com/ethereum/go-ethereum/common"
......@@ -46,7 +46,7 @@ type FixtureInputs struct {
// Dumps a `fp-tests` test fixture to disk if the `OP_E2E_DUMP_FIXTURES` environment variable is set.
//
// [fp-tests]: https://github.com/ethereum-optimism/fp-tests
func tryDumpTestFixture(t *testing.T, result error, name string, env *L2FaultProofEnv, programCfg *config.Config) {
func tryDumpTestFixture(t actions.Testing, result error, name string, env *L2FaultProofEnv, programCfg *config.Config) {
if !dumpFixtures {
return
}
......
......@@ -108,7 +108,7 @@ func runGarbageChannelTest(gt *testing.T, garbageKind actions.GarbageKind, check
require.Equal(t, uint64(NumL2Blocks), l2SafeHead.Number.Uint64())
// Run the FPP on L2 block # NumL2Blocks.
err := env.RunFaultProofProgram(t, gt, NumL2Blocks, inputParams...)
err := env.RunFaultProofProgram(t, NumL2Blocks, inputParams...)
checkResult(gt, err)
}
......
......@@ -59,7 +59,7 @@ func runSequenceWindowExpireTest(gt *testing.T, checkResult func(gt *testing.T,
require.Greater(t, l2SafeHead.Number.Uint64(), uint64(0))
// Run the FPP on one of the auto-derived blocks.
err := env.RunFaultProofProgram(t, gt, l2SafeHead.Number.Uint64()/2, inputParams...)
err := env.RunFaultProofProgram(t, l2SafeHead.Number.Uint64()/2, inputParams...)
checkResult(gt, err)
}
......
......@@ -54,7 +54,7 @@ func Test_ProgramAction_SimpleEmptyChain_HonestClaim_Granite(gt *testing.T) {
// Ensure the block is marked as safe before we attempt to fault prove it.
require.Equal(t, uint64(1), l2SafeHead.Number.Uint64())
err := env.RunFaultProofProgram(t, gt, l2SafeHead.Number.Uint64())
err := env.RunFaultProofProgram(t, l2SafeHead.Number.Uint64())
require.NoError(t, err, "fault proof program failed")
}
......@@ -102,7 +102,7 @@ func Test_ProgramAction_SimpleEmptyChain_JunkClaim_Granite(gt *testing.T) {
// Ensure the block is marked as safe before we attempt to fault prove it.
require.Equal(t, uint64(1), l2SafeHead.Number.Uint64())
err := env.RunFaultProofProgram(t, gt, l2SafeHead.Number.Uint64(), func(f *FixtureInputs) {
err := env.RunFaultProofProgram(t, l2SafeHead.Number.Uint64(), func(f *FixtureInputs) {
f.L2Claim = common.HexToHash("0xdeadbeef")
})
require.Error(t, err, "fault proof program should have failed")
......
......@@ -9,7 +9,6 @@ import (
"github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-program/host/sources"
"github.com/ethereum-optimism/optimism/op-service/eth"
)
......@@ -78,5 +77,4 @@ func (store *BlobsStore) GetBlobSidecars(ctx context.Context, ref eth.L1BlockRef
var (
_ derive.L1BlobsFetcher = (*BlobsStore)(nil)
_ sources.L1BlobSource = (*BlobsStore)(nil)
)
......@@ -13,7 +13,6 @@ import (
opnode "github.com/ethereum-optimism/optimism/op-node"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-program/host/flags"
hostSources "github.com/ethereum-optimism/optimism/op-program/host/sources"
"github.com/ethereum-optimism/optimism/op-service/sources"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
......@@ -74,11 +73,6 @@ type Config struct {
// IsCustomChainConfig indicates that the program uses a custom chain configuration
IsCustomChainConfig bool
// Optional process sources. Will be favored over the RPC sources if set.
L1ProcessSource hostSources.L1Source
L1BeaconProcessSource hostSources.L1BlobSource
L2ProcessSource hostSources.L2Source
}
func (c *Config) Check() error {
......@@ -119,11 +113,7 @@ func (c *Config) Check() error {
}
func (c *Config) FetchingEnabled() bool {
return (c.L1URL != "" && c.L2URL != "" && c.L1BeaconURL != "") || c.InProcessSourcesEnabled()
}
func (c *Config) InProcessSourcesEnabled() bool {
return c.L1ProcessSource != nil && c.L1BeaconProcessSource != nil && c.L2ProcessSource != nil
return c.L1URL != "" && c.L2URL != "" && c.L1BeaconURL != ""
}
// NewConfig creates a Config with all optional values set to the CLI default value
......
......@@ -16,7 +16,6 @@ import (
"github.com/ethereum-optimism/optimism/op-program/host/flags"
"github.com/ethereum-optimism/optimism/op-program/host/kvstore"
"github.com/ethereum-optimism/optimism/op-program/host/prefetcher"
hostSources "github.com/ethereum-optimism/optimism/op-program/host/sources"
"github.com/ethereum-optimism/optimism/op-program/host/types"
opservice "github.com/ethereum-optimism/optimism/op-service"
"github.com/ethereum-optimism/optimism/op-service/client"
......@@ -31,6 +30,24 @@ type L2Source struct {
*sources.DebugClient
}
type Prefetcher interface {
Hint(hint string) error
GetPreimage(ctx context.Context, key common.Hash) ([]byte, error)
}
type PrefetcherCreator func(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *config.Config) (Prefetcher, error)
type creatorsCfg struct {
prefetcher PrefetcherCreator
}
type ProgramOpt func(c *creatorsCfg)
func WithPrefetcher(creator PrefetcherCreator) ProgramOpt {
return func(c *creatorsCfg) {
c.prefetcher = creator
}
}
func Main(logger log.Logger, cfg *config.Config) error {
if err := cfg.Check(); err != nil {
return fmt.Errorf("invalid config: %w", err)
......@@ -44,7 +61,7 @@ func Main(logger log.Logger, cfg *config.Config) error {
if cfg.ServerMode {
preimageChan := preimage.ClientPreimageChannel()
hinterChan := preimage.ClientHinterChannel()
return PreimageServer(ctx, logger, cfg, preimageChan, hinterChan)
return PreimageServer(ctx, logger, cfg, preimageChan, hinterChan, makeDefaultPrefetcher)
}
if err := FaultProofProgram(ctx, logger, cfg); err != nil {
......@@ -55,7 +72,13 @@ func Main(logger log.Logger, cfg *config.Config) error {
}
// FaultProofProgram is the programmatic entry-point for the fault proof program
func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Config) error {
func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Config, opts ...ProgramOpt) error {
creators := &creatorsCfg{
prefetcher: makeDefaultPrefetcher,
}
for _, opt := range opts {
opt(creators)
}
var (
serverErr chan error
pClientRW preimage.FileChannel
......@@ -92,7 +115,7 @@ func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Confi
serverErr = make(chan error)
go func() {
defer close(serverErr)
serverErr <- PreimageServer(ctx, logger, cfg, pHostRW, hHostRW)
serverErr <- PreimageServer(ctx, logger, cfg, pHostRW, hHostRW, creators.prefetcher)
}()
var cmd *exec.Cmd
......@@ -124,7 +147,7 @@ func FaultProofProgram(ctx context.Context, logger log.Logger, cfg *config.Confi
// This method will block until both the hinter and preimage handlers complete.
// If either returns an error both handlers are stopped.
// The supplied preimageChannel and hintChannel will be closed before this function returns.
func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, preimageChannel preimage.FileChannel, hintChannel preimage.FileChannel) error {
func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config, preimageChannel preimage.FileChannel, hintChannel preimage.FileChannel, prefetcherCreator PrefetcherCreator) error {
var serverDone chan error
var hinterDone chan error
logger.Info("Starting preimage server")
......@@ -172,11 +195,11 @@ func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config,
getPreimage kvstore.PreimageSource
hinter preimage.HintHandler
)
if cfg.FetchingEnabled() {
prefetch, err := makePrefetcher(ctx, logger, kv, cfg)
prefetch, err := prefetcherCreator(ctx, logger, kv, cfg)
if err != nil {
return fmt.Errorf("failed to create prefetcher: %w", err)
}
if prefetch != nil {
getPreimage = func(key common.Hash) ([]byte, error) { return prefetch.GetPreimage(ctx, key) }
hinter = prefetch.Hint
} else {
......@@ -205,17 +228,10 @@ func PreimageServer(ctx context.Context, logger log.Logger, cfg *config.Config,
}
}
func makePrefetcher(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *config.Config) (*prefetcher.Prefetcher, error) {
var l1Cl hostSources.L1Source
var l1BlobFetcher hostSources.L1BlobSource
var l2DebugCl hostSources.L2Source
if cfg.InProcessSourcesEnabled() {
logger.Debug("Using in-process sources for preimage fetching.")
l1Cl = cfg.L1ProcessSource
l1BlobFetcher = cfg.L1BeaconProcessSource
l2DebugCl = cfg.L2ProcessSource
} else {
func makeDefaultPrefetcher(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *config.Config) (Prefetcher, error) {
if !cfg.FetchingEnabled() {
return nil, nil
}
logger.Info("Connecting to L1 node", "l1", cfg.L1URL)
l1RPC, err := client.NewRPC(ctx, logger, cfg.L1URL, client.WithDialBackoff(10))
if err != nil {
......@@ -230,18 +246,17 @@ func makePrefetcher(ctx context.Context, logger log.Logger, kv kvstore.KV, cfg *
l1ClCfg := sources.L1ClientDefaultConfig(cfg.Rollup, cfg.L1TrustRPC, cfg.L1RPCKind)
l2ClCfg := sources.L2ClientDefaultConfig(cfg.Rollup, true)
l1Cl, err = sources.NewL1Client(l1RPC, logger, nil, l1ClCfg)
l1Cl, err := sources.NewL1Client(l1RPC, logger, nil, l1ClCfg)
if err != nil {
return nil, fmt.Errorf("failed to create L1 client: %w", err)
}
l1Beacon := sources.NewBeaconHTTPClient(client.NewBasicHTTPClient(cfg.L1BeaconURL, logger))
l1BlobFetcher = sources.NewL1BeaconClient(l1Beacon, sources.L1BeaconClientConfig{FetchAllSidecars: false})
l1BlobFetcher := sources.NewL1BeaconClient(l1Beacon, sources.L1BeaconClientConfig{FetchAllSidecars: false})
l2Cl, err := NewL2Client(l2RPC, logger, nil, &L2ClientConfig{L2ClientConfig: l2ClCfg, L2Head: cfg.L2Head})
if err != nil {
return nil, fmt.Errorf("failed to create L2 client: %w", err)
}
l2DebugCl = &L2Source{L2Client: l2Cl, DebugClient: sources.NewDebugClient(l2RPC.CallContext)}
}
l2DebugCl := &L2Source{L2Client: l2Cl, DebugClient: sources.NewDebugClient(l2RPC.CallContext)}
return prefetcher.NewPrefetcher(logger, l1Cl, l1BlobFetcher, l2DebugCl, kv), nil
}
......
......@@ -37,7 +37,7 @@ func TestServerMode(t *testing.T) {
logger := testlog.Logger(t, log.LevelTrace)
result := make(chan error)
go func() {
result <- PreimageServer(context.Background(), logger, cfg, preimageServer, hintServer)
result <- PreimageServer(context.Background(), logger, cfg, preimageServer, hintServer, makeDefaultPrefetcher)
}()
pClient := preimage.NewOracleClient(preimageClient)
......
......@@ -13,7 +13,6 @@ import (
"github.com/ethereum-optimism/optimism/op-program/client/l2"
"github.com/ethereum-optimism/optimism/op-program/client/mpt"
"github.com/ethereum-optimism/optimism/op-program/host/kvstore"
"github.com/ethereum-optimism/optimism/op-program/host/sources"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
......@@ -35,16 +34,34 @@ var acceleratedPrecompiles = []common.Address{
common.BytesToAddress([]byte{0x0a}), // KZG Point Evaluation
}
type L1Source interface {
InfoByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, error)
InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error)
FetchReceipts(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Receipts, error)
}
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)
}
type L2Source interface {
InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error)
NodeByHash(ctx context.Context, hash common.Hash) ([]byte, error)
CodeByHash(ctx context.Context, hash common.Hash) ([]byte, error)
OutputByRoot(ctx context.Context, root common.Hash) (eth.Output, error)
}
type Prefetcher struct {
logger log.Logger
l1Fetcher sources.L1Source
l1BlobFetcher sources.L1BlobSource
l2Fetcher sources.L2Source
l1Fetcher L1Source
l1BlobFetcher L1BlobSource
l2Fetcher L2Source
lastHint string
kvStore kvstore.KV
}
func NewPrefetcher(logger log.Logger, l1Fetcher sources.L1Source, l1BlobFetcher sources.L1BlobSource, l2Fetcher sources.L2Source, kvStore kvstore.KV) *Prefetcher {
func NewPrefetcher(logger log.Logger, l1Fetcher L1Source, l1BlobFetcher L1BlobSource, l2Fetcher L2Source, kvStore kvstore.KV) *Prefetcher {
return &Prefetcher{
logger: logger,
l1Fetcher: NewRetryingL1Source(logger, l1Fetcher),
......
......@@ -4,7 +4,6 @@ import (
"context"
"math"
"github.com/ethereum-optimism/optimism/op-program/host/sources"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/retry"
"github.com/ethereum/go-ethereum/common"
......@@ -16,11 +15,11 @@ const maxAttempts = math.MaxInt // Succeed or die trying
type RetryingL1Source struct {
logger log.Logger
source sources.L1Source
source L1Source
strategy retry.Strategy
}
func NewRetryingL1Source(logger log.Logger, source sources.L1Source) *RetryingL1Source {
func NewRetryingL1Source(logger log.Logger, source L1Source) *RetryingL1Source {
return &RetryingL1Source{
logger: logger,
source: source,
......@@ -58,15 +57,15 @@ func (s *RetryingL1Source) FetchReceipts(ctx context.Context, blockHash common.H
})
}
var _ sources.L1Source = (*RetryingL1Source)(nil)
var _ L1Source = (*RetryingL1Source)(nil)
type RetryingL1BlobSource struct {
logger log.Logger
source sources.L1BlobSource
source L1BlobSource
strategy retry.Strategy
}
func NewRetryingL1BlobSource(logger log.Logger, source sources.L1BlobSource) *RetryingL1BlobSource {
func NewRetryingL1BlobSource(logger log.Logger, source L1BlobSource) *RetryingL1BlobSource {
return &RetryingL1BlobSource{
logger: logger,
source: source,
......@@ -94,11 +93,11 @@ func (s *RetryingL1BlobSource) GetBlobs(ctx context.Context, ref eth.L1BlockRef,
})
}
var _ sources.L1BlobSource = (*RetryingL1BlobSource)(nil)
var _ L1BlobSource = (*RetryingL1BlobSource)(nil)
type RetryingL2Source struct {
logger log.Logger
source sources.L2Source
source L2Source
strategy retry.Strategy
}
......@@ -143,7 +142,7 @@ func (s *RetryingL2Source) OutputByRoot(ctx context.Context, root common.Hash) (
})
}
func NewRetryingL2Source(logger log.Logger, source sources.L2Source) *RetryingL2Source {
func NewRetryingL2Source(logger log.Logger, source L2Source) *RetryingL2Source {
return &RetryingL2Source{
logger: logger,
source: source,
......@@ -151,4 +150,4 @@ func NewRetryingL2Source(logger log.Logger, source sources.L2Source) *RetryingL2
}
}
var _ sources.L2Source = (*RetryingL2Source)(nil)
var _ L2Source = (*RetryingL2Source)(nil)
......@@ -12,7 +12,6 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-program/host/sources"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/retry"
"github.com/ethereum-optimism/optimism/op-service/testlog"
......@@ -375,4 +374,4 @@ func (m *MockL2Source) ExpectOutputByRoot(root common.Hash, output eth.Output, e
m.Mock.On("OutputByRoot", root).Once().Return(output, &err)
}
var _ sources.L2Source = (*MockL2Source)(nil)
var _ L2Source = (*MockL2Source)(nil)
package sources
import (
"context"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
)
type L1Source interface {
InfoByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, error)
InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error)
FetchReceipts(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Receipts, error)
}
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)
}
type L2Source interface {
InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error)
NodeByHash(ctx context.Context, hash common.Hash) ([]byte, error)
CodeByHash(ctx context.Context, hash common.Hash) ([]byte, error)
OutputByRoot(ctx context.Context, root common.Hash) (eth.Output, error)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment