Commit 1a34669c authored by Evan Richard's avatar Evan Richard Committed by GitHub

Merge pull request #8580 from ethereum-optimism/evan/l2_endpoint_provider

op-service, op-proposer, op-batcher: Add L2EndpointProvider and its first struct, StaticL2EndpointProvider.
parents 20360744 915e76f0
...@@ -17,6 +17,7 @@ import ( ...@@ -17,6 +17,7 @@ import (
"github.com/ethereum-optimism/optimism/op-batcher/metrics" "github.com/ethereum-optimism/optimism/op-batcher/metrics"
"github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-service/dial"
"github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum-optimism/optimism/op-service/txmgr"
) )
...@@ -43,8 +44,7 @@ type DriverSetup struct { ...@@ -43,8 +44,7 @@ type DriverSetup struct {
Config BatcherConfig Config BatcherConfig
Txmgr txmgr.TxManager Txmgr txmgr.TxManager
L1Client L1Client L1Client L1Client
L2Client L2Client EndpointProvider dial.L2EndpointProvider
RollupClient RollupClient
ChannelConfig ChannelConfig ChannelConfig ChannelConfig
} }
...@@ -185,7 +185,11 @@ func (l *BatchSubmitter) loadBlocksIntoState(ctx context.Context) error { ...@@ -185,7 +185,11 @@ func (l *BatchSubmitter) loadBlocksIntoState(ctx context.Context) error {
func (l *BatchSubmitter) loadBlockIntoState(ctx context.Context, blockNumber uint64) (*types.Block, error) { func (l *BatchSubmitter) loadBlockIntoState(ctx context.Context, blockNumber uint64) (*types.Block, error) {
ctx, cancel := context.WithTimeout(ctx, l.Config.NetworkTimeout) ctx, cancel := context.WithTimeout(ctx, l.Config.NetworkTimeout)
defer cancel() defer cancel()
block, err := l.L2Client.BlockByNumber(ctx, new(big.Int).SetUint64(blockNumber)) l2Client, err := l.EndpointProvider.EthClient(ctx)
if err != nil {
return nil, fmt.Errorf("getting L2 client: %w", err)
}
block, err := l2Client.BlockByNumber(ctx, new(big.Int).SetUint64(blockNumber))
if err != nil { if err != nil {
return nil, fmt.Errorf("getting L2 block: %w", err) return nil, fmt.Errorf("getting L2 block: %w", err)
} }
...@@ -203,7 +207,11 @@ func (l *BatchSubmitter) loadBlockIntoState(ctx context.Context, blockNumber uin ...@@ -203,7 +207,11 @@ func (l *BatchSubmitter) loadBlockIntoState(ctx context.Context, blockNumber uin
func (l *BatchSubmitter) calculateL2BlockRangeToStore(ctx context.Context) (eth.BlockID, eth.BlockID, error) { func (l *BatchSubmitter) calculateL2BlockRangeToStore(ctx context.Context) (eth.BlockID, eth.BlockID, error) {
ctx, cancel := context.WithTimeout(ctx, l.Config.NetworkTimeout) ctx, cancel := context.WithTimeout(ctx, l.Config.NetworkTimeout)
defer cancel() defer cancel()
syncStatus, err := l.RollupClient.SyncStatus(ctx) rollupClient, err := l.EndpointProvider.RollupClient(ctx)
if err != nil {
return eth.BlockID{}, eth.BlockID{}, fmt.Errorf("getting rollup client: %w", err)
}
syncStatus, err := rollupClient.SyncStatus(ctx)
// Ensure that we have the sync status // Ensure that we have the sync status
if err != nil { if err != nil {
return eth.BlockID{}, eth.BlockID{}, fmt.Errorf("failed to get sync status: %w", err) return eth.BlockID{}, eth.BlockID{}, fmt.Errorf("failed to get sync status: %w", err)
......
...@@ -23,7 +23,6 @@ import ( ...@@ -23,7 +23,6 @@ import (
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" oprpc "github.com/ethereum-optimism/optimism/op-service/rpc"
"github.com/ethereum-optimism/optimism/op-service/sources"
"github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum-optimism/optimism/op-service/txmgr"
) )
...@@ -43,8 +42,7 @@ type BatcherService struct { ...@@ -43,8 +42,7 @@ type BatcherService struct {
Log log.Logger Log log.Logger
Metrics metrics.Metricer Metrics metrics.Metricer
L1Client *ethclient.Client L1Client *ethclient.Client
L2Client *ethclient.Client EndpointProvider dial.L2EndpointProvider
RollupNode *sources.RollupClient
TxManager txmgr.TxManager TxManager txmgr.TxManager
BatcherConfig BatcherConfig
...@@ -127,17 +125,12 @@ func (bs *BatcherService) initRPCClients(ctx context.Context, cfg *CLIConfig) er ...@@ -127,17 +125,12 @@ func (bs *BatcherService) initRPCClients(ctx context.Context, cfg *CLIConfig) er
} }
bs.L1Client = l1Client bs.L1Client = l1Client
l2Client, err := dial.DialEthClientWithTimeout(ctx, dial.DefaultDialTimeout, bs.Log, cfg.L2EthRpc) endpointProvider, err := dial.NewStaticL2EndpointProvider(ctx, bs.Log, cfg.L2EthRpc, cfg.RollupRpc)
if err != nil { if err != nil {
return fmt.Errorf("failed to dial L2 engine RPC: %w", err) return fmt.Errorf("failed to create L2 endpoint provider: %w", err)
} }
bs.L2Client = l2Client bs.EndpointProvider = endpointProvider
rollupClient, err := dial.DialRollupClientWithTimeout(ctx, dial.DefaultDialTimeout, bs.Log, cfg.RollupRpc)
if err != nil {
return fmt.Errorf("failed to dial L2 rollup-client RPC: %w", err)
}
bs.RollupNode = rollupClient
return nil return nil
} }
...@@ -158,7 +151,11 @@ func (bs *BatcherService) initBalanceMonitor(cfg *CLIConfig) { ...@@ -158,7 +151,11 @@ func (bs *BatcherService) initBalanceMonitor(cfg *CLIConfig) {
} }
func (bs *BatcherService) initRollupConfig(ctx context.Context) error { func (bs *BatcherService) initRollupConfig(ctx context.Context) error {
rollupConfig, err := bs.RollupNode.RollupConfig(ctx) rollupNode, err := bs.EndpointProvider.RollupClient(ctx)
if err != nil {
return fmt.Errorf("failed to retrieve rollup client: %w", err)
}
rollupConfig, err := rollupNode.RollupConfig(ctx)
if err != nil { if err != nil {
return fmt.Errorf("failed to retrieve rollup config: %w", err) return fmt.Errorf("failed to retrieve rollup config: %w", err)
} }
...@@ -235,8 +232,7 @@ func (bs *BatcherService) initDriver() { ...@@ -235,8 +232,7 @@ func (bs *BatcherService) initDriver() {
Config: bs.BatcherConfig, Config: bs.BatcherConfig,
Txmgr: bs.TxManager, Txmgr: bs.TxManager,
L1Client: bs.L1Client, L1Client: bs.L1Client,
L2Client: bs.L2Client, EndpointProvider: bs.EndpointProvider,
RollupClient: bs.RollupNode,
ChannelConfig: bs.ChannelConfig, ChannelConfig: bs.ChannelConfig,
}) })
} }
...@@ -329,11 +325,8 @@ func (bs *BatcherService) Stop(ctx context.Context) error { ...@@ -329,11 +325,8 @@ func (bs *BatcherService) Stop(ctx context.Context) error {
if bs.L1Client != nil { if bs.L1Client != nil {
bs.L1Client.Close() bs.L1Client.Close()
} }
if bs.L2Client != nil { if bs.EndpointProvider != nil {
bs.L2Client.Close() bs.EndpointProvider.Close()
}
if bs.RollupNode != nil {
bs.RollupNode.Close()
} }
if result == nil { if result == nil {
......
...@@ -20,6 +20,7 @@ import ( ...@@ -20,6 +20,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-proposer/metrics" "github.com/ethereum-optimism/optimism/op-proposer/metrics"
"github.com/ethereum-optimism/optimism/op-proposer/proposer" "github.com/ethereum-optimism/optimism/op-proposer/proposer"
"github.com/ethereum-optimism/optimism/op-service/dial"
"github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/sources"
"github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum-optimism/optimism/op-service/txmgr"
) )
...@@ -64,13 +65,15 @@ func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Cl ...@@ -64,13 +65,15 @@ func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Cl
L2OutputOracleAddr: cfg.OutputOracleAddr, L2OutputOracleAddr: cfg.OutputOracleAddr,
AllowNonFinalized: cfg.AllowNonFinalized, AllowNonFinalized: cfg.AllowNonFinalized,
} }
rollupProvider, err := dial.NewStaticL2RollupProviderFromExistingRollup(rollupCl)
require.NoError(t, err)
driverSetup := proposer.DriverSetup{ driverSetup := proposer.DriverSetup{
Log: log, Log: log,
Metr: metrics.NoopMetrics, Metr: metrics.NoopMetrics,
Cfg: proposerConfig, Cfg: proposerConfig,
Txmgr: fakeTxMgr{from: crypto.PubkeyToAddress(cfg.ProposerKey.PublicKey)}, Txmgr: fakeTxMgr{from: crypto.PubkeyToAddress(cfg.ProposerKey.PublicKey)},
L1Client: l1, L1Client: l1,
RollupClient: rollupCl, RollupProvider: rollupProvider,
} }
dr, err := proposer.NewL2OutputSubmitter(driverSetup) dr, err := proposer.NewL2OutputSubmitter(driverSetup)
......
...@@ -18,6 +18,7 @@ import ( ...@@ -18,6 +18,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-proposer/metrics" "github.com/ethereum-optimism/optimism/op-proposer/metrics"
"github.com/ethereum-optimism/optimism/op-service/dial"
"github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum-optimism/optimism/op-service/txmgr"
) )
...@@ -48,8 +49,8 @@ type DriverSetup struct { ...@@ -48,8 +49,8 @@ type DriverSetup struct {
Txmgr txmgr.TxManager Txmgr txmgr.TxManager
L1Client L1Client L1Client L1Client
// RollupClient is used to retrieve output roots from // RollupProvider's RollupClient() is used to retrieve output roots from
RollupClient RollupClient RollupProvider dial.RollupProvider
} }
// L2OutputSubmitter is responsible for proposing outputs // L2OutputSubmitter is responsible for proposing outputs
...@@ -167,7 +168,12 @@ func (l *L2OutputSubmitter) FetchNextOutputInfo(ctx context.Context) (*eth.Outpu ...@@ -167,7 +168,12 @@ func (l *L2OutputSubmitter) FetchNextOutputInfo(ctx context.Context) (*eth.Outpu
// Fetch the current L2 heads // Fetch the current L2 heads
cCtx, cancel = context.WithTimeout(ctx, l.Cfg.NetworkTimeout) cCtx, cancel = context.WithTimeout(ctx, l.Cfg.NetworkTimeout)
defer cancel() defer cancel()
status, err := l.RollupClient.SyncStatus(cCtx) rollupClient, err := l.RollupProvider.RollupClient(cCtx)
if err != nil {
l.Log.Error("proposer unable to get rollup client", "err", err)
return nil, false, err
}
status, err := rollupClient.SyncStatus(cCtx)
if err != nil { if err != nil {
l.Log.Error("proposer unable to get sync status", "err", err) l.Log.Error("proposer unable to get sync status", "err", err)
return nil, false, err return nil, false, err
...@@ -192,7 +198,13 @@ func (l *L2OutputSubmitter) FetchNextOutputInfo(ctx context.Context) (*eth.Outpu ...@@ -192,7 +198,13 @@ func (l *L2OutputSubmitter) FetchNextOutputInfo(ctx context.Context) (*eth.Outpu
func (l *L2OutputSubmitter) fetchOutput(ctx context.Context, block *big.Int) (*eth.OutputResponse, bool, error) { func (l *L2OutputSubmitter) fetchOutput(ctx context.Context, block *big.Int) (*eth.OutputResponse, bool, error) {
ctx, cancel := context.WithTimeout(ctx, l.Cfg.NetworkTimeout) ctx, cancel := context.WithTimeout(ctx, l.Cfg.NetworkTimeout)
defer cancel() defer cancel()
output, err := l.RollupClient.OutputAtBlock(ctx, block.Uint64())
rollupClient, err := l.RollupProvider.RollupClient(ctx)
if err != nil {
l.Log.Error("proposer unable to get rollup client", "err", err)
return nil, false, err
}
output, err := rollupClient.OutputAtBlock(ctx, block.Uint64())
if err != nil { if err != nil {
l.Log.Error("failed to fetch output at block %d: %w", block, err) l.Log.Error("failed to fetch output at block %d: %w", block, err)
return nil, false, err return nil, false, err
......
...@@ -19,7 +19,6 @@ import ( ...@@ -19,7 +19,6 @@ import (
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
oprpc "github.com/ethereum-optimism/optimism/op-service/rpc" oprpc "github.com/ethereum-optimism/optimism/op-service/rpc"
"github.com/ethereum-optimism/optimism/op-service/sources"
"github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
...@@ -51,7 +50,7 @@ type ProposerService struct { ...@@ -51,7 +50,7 @@ type ProposerService struct {
TxManager txmgr.TxManager TxManager txmgr.TxManager
L1Client *ethclient.Client L1Client *ethclient.Client
RollupClient *sources.RollupClient RollupProvider dial.RollupProvider
driver *L2OutputSubmitter driver *L2OutputSubmitter
...@@ -122,11 +121,11 @@ func (ps *ProposerService) initRPCClients(ctx context.Context, cfg *CLIConfig) e ...@@ -122,11 +121,11 @@ func (ps *ProposerService) initRPCClients(ctx context.Context, cfg *CLIConfig) e
} }
ps.L1Client = l1Client ps.L1Client = l1Client
rollupClient, err := dial.DialRollupClientWithTimeout(ctx, dial.DefaultDialTimeout, ps.Log, cfg.RollupRpc) rollupProvider, err := dial.NewStaticL2RollupProvider(ctx, ps.Log, cfg.RollupRpc)
if err != nil { if err != nil {
return fmt.Errorf("failed to dial L2 rollup-client RPC: %w", err) return fmt.Errorf("failed to build L2 endpoint provider: %w", err)
} }
ps.RollupClient = rollupClient ps.RollupProvider = rollupProvider
return nil return nil
} }
...@@ -204,7 +203,7 @@ func (ps *ProposerService) initDriver() error { ...@@ -204,7 +203,7 @@ func (ps *ProposerService) initDriver() error {
Cfg: ps.ProposerConfig, Cfg: ps.ProposerConfig,
Txmgr: ps.TxManager, Txmgr: ps.TxManager,
L1Client: ps.L1Client, L1Client: ps.L1Client,
RollupClient: ps.RollupClient, RollupProvider: ps.RollupProvider,
}) })
if err != nil { if err != nil {
return err return err
...@@ -298,8 +297,8 @@ func (ps *ProposerService) Stop(ctx context.Context) error { ...@@ -298,8 +297,8 @@ func (ps *ProposerService) Stop(ctx context.Context) error {
ps.L1Client.Close() ps.L1Client.Close()
} }
if ps.RollupClient != nil { if ps.RollupProvider != nil {
ps.RollupClient.Close() ps.RollupProvider.Close()
} }
if result == nil { if result == nil {
......
package dial
import (
"context"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
)
// L2EndpointProvider is an interface for providing a RollupClient and l2 eth client
// It manages the lifecycle of the RollupClient and eth client for callers
// It does this by extending the RollupProvider interface to add the ability to get an EthClient
type L2EndpointProvider interface {
RollupProvider
// EthClient(ctx) returns the underlying ethclient pointing to the L2 execution node
EthClient(ctx context.Context) (*ethclient.Client, error)
}
// StaticL2EndpointProvider is a L2EndpointProvider that always returns the same static RollupClient and eth client
// It is meant for scenarios where a single, unchanging (L2 rollup node, L2 execution node) pair is used
type StaticL2EndpointProvider struct {
StaticL2RollupProvider
ethClient *ethclient.Client
}
func NewStaticL2EndpointProvider(ctx context.Context, log log.Logger, ethClientUrl string, rollupClientUrl string) (*StaticL2EndpointProvider, error) {
ethClient, err := DialEthClientWithTimeout(ctx, DefaultDialTimeout, log, ethClientUrl)
if err != nil {
return nil, err
}
rollupProvider, err := NewStaticL2RollupProvider(ctx, log, rollupClientUrl)
if err != nil {
return nil, err
}
return &StaticL2EndpointProvider{
StaticL2RollupProvider: *rollupProvider,
ethClient: ethClient,
}, nil
}
func (p *StaticL2EndpointProvider) EthClient(context.Context) (*ethclient.Client, error) {
return p.ethClient, nil
}
func (p *StaticL2EndpointProvider) Close() {
if p.ethClient != nil {
p.ethClient.Close()
}
p.StaticL2RollupProvider.Close()
}
package dial
import (
"context"
"github.com/ethereum-optimism/optimism/op-service/sources"
"github.com/ethereum/go-ethereum/log"
)
// RollupProvider is an interface for providing a RollupClient
// It manages the lifecycle of the RollupClient for callers
type RollupProvider interface {
// RollupClient(ctx) returns the underlying sources.RollupClient pointing to the L2 rollup consensus node
RollupClient(ctx context.Context) (*sources.RollupClient, error)
// Close() closes the underlying client or clients
Close()
}
// StaticL2RollupProvider is a RollupProvider that always returns the same static RollupClient
// It is meant for scenarios where a single, unchanging L2 rollup node is used
type StaticL2RollupProvider struct {
rollupClient *sources.RollupClient
}
func NewStaticL2RollupProvider(ctx context.Context, log log.Logger, rollupClientUrl string) (*StaticL2RollupProvider, error) {
rollupClient, err := DialRollupClientWithTimeout(ctx, DefaultDialTimeout, log, rollupClientUrl)
if err != nil {
return nil, err
}
return &StaticL2RollupProvider{
rollupClient: rollupClient,
}, nil
}
// The NewStaticL2EndpointProviderFromExistingRollup constructor is used in e2e testing
func NewStaticL2RollupProviderFromExistingRollup(rollupCl *sources.RollupClient) (*StaticL2RollupProvider, error) {
return &StaticL2RollupProvider{
rollupClient: rollupCl,
}, nil
}
func (p *StaticL2RollupProvider) RollupClient(context.Context) (*sources.RollupClient, error) {
return p.rollupClient, nil
}
func (p *StaticL2RollupProvider) Close() {
if p.rollupClient != nil {
p.rollupClient.Close()
}
}
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