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