Commit f717c43c authored by OptimismBot's avatar OptimismBot Committed by GitHub

Merge pull request #5624 from ethereum-optimism/pops/test/challenger

feat(pops): Refactor Challenger for Testability
parents 352e0f52 666f490d
......@@ -2,111 +2,26 @@ package challenger
import (
"context"
"fmt"
_ "net/http/pprof"
"os"
"os/signal"
"sync"
"syscall"
"time"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/urfave/cli"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-node/sources"
opservice "github.com/ethereum-optimism/optimism/op-service"
opclient "github.com/ethereum-optimism/optimism/op-service/client"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
oprpc "github.com/ethereum-optimism/optimism/op-service/rpc"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
)
// Main is the entrypoint into the Challenger. This method executes the
// service and blocks until the service exits.
func Main(version string, cliCtx *cli.Context) error {
cfg := NewConfig(cliCtx)
if err := cfg.Check(); err != nil {
return fmt.Errorf("invalid CLI flags: %w", err)
}
abi "github.com/ethereum/go-ethereum/accounts/abi"
bind "github.com/ethereum/go-ethereum/accounts/abi/bind"
common "github.com/ethereum/go-ethereum/common"
ethclient "github.com/ethereum/go-ethereum/ethclient"
log "github.com/ethereum/go-ethereum/log"
l := oplog.NewLogger(cfg.LogConfig)
m := metrics.NewMetrics("default")
l.Info("Initializing Challenger")
challengerConfig, err := NewChallengerConfigFromCLIConfig(cfg, l, m)
if err != nil {
l.Error("Unable to create the Challenger", "error", err)
return err
}
config "github.com/ethereum-optimism/optimism/op-challenger/config"
metrics "github.com/ethereum-optimism/optimism/op-challenger/metrics"
challenger, err := NewChallenger(*challengerConfig, l, m)
if err != nil {
l.Error("Unable to create the Challenger", "error", err)
return err
}
l.Info("Starting Challenger")
ctx, cancel := context.WithCancel(context.Background())
if err := challenger.Start(); err != nil {
cancel()
l.Error("Unable to start Challenger", "error", err)
return err
}
defer challenger.Stop()
l.Info("Challenger started")
pprofConfig := cfg.PprofConfig
if pprofConfig.Enabled {
l.Info("starting pprof", "addr", pprofConfig.ListenAddr, "port", pprofConfig.ListenPort)
go func() {
if err := oppprof.ListenAndServe(ctx, pprofConfig.ListenAddr, pprofConfig.ListenPort); err != nil {
l.Error("error starting pprof", "err", err)
}
}()
}
metricsCfg := cfg.MetricsConfig
if metricsCfg.Enabled {
l.Info("starting metrics server", "addr", metricsCfg.ListenAddr, "port", metricsCfg.ListenPort)
go func() {
if err := m.Serve(ctx, metricsCfg.ListenAddr, metricsCfg.ListenPort); err != nil {
l.Error("error starting metrics server", err)
}
}()
m.StartBalanceMetrics(ctx, l, challengerConfig.L1Client, challengerConfig.TxManager.From())
}
rpcCfg := cfg.RPCConfig
server := oprpc.NewServer(rpcCfg.ListenAddr, rpcCfg.ListenPort, version, oprpc.WithLogger(l))
if err := server.Start(); err != nil {
cancel()
return fmt.Errorf("error starting RPC server: %w", err)
}
m.RecordInfo(version)
m.RecordUp()
interruptChannel := make(chan os.Signal, 1)
signal.Notify(interruptChannel, []os.Signal{
os.Interrupt,
os.Kill,
syscall.SIGTERM,
syscall.SIGQUIT,
}...)
<-interruptChannel
cancel()
return nil
}
bindings "github.com/ethereum-optimism/optimism/op-bindings/bindings"
sources "github.com/ethereum-optimism/optimism/op-node/sources"
opclient "github.com/ethereum-optimism/optimism/op-service/client"
txmgr "github.com/ethereum-optimism/optimism/op-service/txmgr"
)
// challenger contests invalid L2OutputOracle outputs
// Challenger contests invalid L2OutputOracle outputs
type Challenger struct {
txMgr txmgr.TxManager
wg sync.WaitGroup
......@@ -128,7 +43,6 @@ type Challenger struct {
l2ooABI *abi.ABI
// dispute game factory contract
// TODO(@refcell): add a binding for this contract
// dgfContract *bindings.DisputeGameFactoryCaller
dgfContractAddr common.Address
// dgfABI *abi.ABI
......@@ -136,59 +50,30 @@ type Challenger struct {
networkTimeout time.Duration
}
// NewChallengerFromCLIConfig creates a new challenger given the CLI Config
func NewChallengerFromCLIConfig(cfg CLIConfig, l log.Logger, m metrics.Metricer) (*Challenger, error) {
challengerConfig, err := NewChallengerConfigFromCLIConfig(cfg, l, m)
if err != nil {
return nil, err
}
return NewChallenger(*challengerConfig, l, m)
}
// NewChallengerConfigFromCLIConfig creates the challenger config from the CLI config.
func NewChallengerConfigFromCLIConfig(cfg CLIConfig, l log.Logger, m metrics.Metricer) (*Config, error) {
l2ooAddress, err := opservice.ParseAddress(cfg.L2OOAddress)
if err != nil {
return nil, err
}
dgfAddress, err := opservice.ParseAddress(cfg.DGFAddress)
if err != nil {
return nil, err
}
// NewChallenger creates a new Challenger
func NewChallenger(cfg config.Config, l log.Logger, m metrics.Metricer) (*Challenger, error) {
ctx, cancel := context.WithCancel(context.Background())
txManager, err := txmgr.NewSimpleTxManager("challenger", l, m, cfg.TxMgrConfig)
txManager, err := txmgr.NewSimpleTxManager("challenger", l, m, *cfg.TxMgrConfig)
if err != nil {
cancel()
return nil, err
}
// Connect to L1 and L2 providers. Perform these last since they are the most expensive.
ctx := context.Background()
l1Client, err := opclient.DialEthClientWithTimeout(ctx, cfg.L1EthRpc, opclient.DefaultDialTimeout)
if err != nil {
cancel()
return nil, err
}
rollupClient, err := opclient.DialRollupClientWithTimeout(ctx, cfg.RollupRpc, opclient.DefaultDialTimeout)
if err != nil {
cancel()
return nil, err
}
return &Config{
L2OutputOracleAddr: l2ooAddress,
DisputeGameFactory: dgfAddress,
NetworkTimeout: cfg.TxMgrConfig.NetworkTimeout,
L1Client: l1Client,
RollupClient: rollupClient,
TxManager: txManager,
}, nil
}
// NewChallenger creates a new Challenger
func NewChallenger(cfg Config, l log.Logger, m metrics.Metricer) (*Challenger, error) {
ctx, cancel := context.WithCancel(context.Background())
l2ooContract, err := bindings.NewL2OutputOracleCaller(cfg.L2OutputOracleAddr, cfg.L1Client)
l2ooContract, err := bindings.NewL2OutputOracleCaller(cfg.L2OOAddress, l1Client)
if err != nil {
cancel()
return nil, err
......@@ -201,7 +86,7 @@ func NewChallenger(cfg Config, l log.Logger, m metrics.Metricer) (*Challenger, e
cancel()
return nil, err
}
log.Info("Connected to L2OutputOracle", "address", cfg.L2OutputOracleAddr, "version", version)
l.Info("Connected to L2OutputOracle", "address", cfg.L2OOAddress, "version", version)
parsed, err := bindings.L2OutputOracleMetaData.GetAbi()
if err != nil {
......@@ -210,7 +95,7 @@ func NewChallenger(cfg Config, l log.Logger, m metrics.Metricer) (*Challenger, e
}
return &Challenger{
txMgr: cfg.TxManager,
txMgr: txManager,
done: make(chan struct{}),
log: l,
......@@ -219,15 +104,15 @@ func NewChallenger(cfg Config, l log.Logger, m metrics.Metricer) (*Challenger, e
ctx: ctx,
cancel: cancel,
rollupClient: cfg.RollupClient,
rollupClient: rollupClient,
l1Client: cfg.L1Client,
l1Client: l1Client,
l2ooContract: l2ooContract,
l2ooContractAddr: cfg.L2OutputOracleAddr,
l2ooContractAddr: cfg.L2OOAddress,
l2ooABI: parsed,
dgfContractAddr: cfg.DisputeGameFactory,
dgfContractAddr: cfg.DGFAddress,
networkTimeout: cfg.NetworkTimeout,
}, nil
......
package challenger
import (
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/urfave/cli"
flags "github.com/ethereum-optimism/optimism/op-challenger/flags"
sources "github.com/ethereum-optimism/optimism/op-node/sources"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
oprpc "github.com/ethereum-optimism/optimism/op-service/rpc"
txmgr "github.com/ethereum-optimism/optimism/op-service/txmgr"
)
// Config contains the well typed fields that are used to initialize the challenger.
// It is intended for programmatic use.
type Config struct {
L2OutputOracleAddr common.Address
DisputeGameFactory common.Address
NetworkTimeout time.Duration
TxManager txmgr.TxManager
L1Client *ethclient.Client
RollupClient *sources.RollupClient
}
// CLIConfig is a well typed config that is parsed from the CLI params.
// This also contains config options for auxiliary services.
// It is transformed into a `Config` before the Challenger is started.
type CLIConfig struct {
// L1EthRpc is the HTTP provider URL for L1.
L1EthRpc string
// RollupRpc is the HTTP provider URL for the rollup node.
RollupRpc string
// L2OOAddress is the L2OutputOracle contract address.
L2OOAddress string
// DGFAddress is the DisputeGameFactory contract address.
DGFAddress string
TxMgrConfig txmgr.CLIConfig
RPCConfig oprpc.CLIConfig
LogConfig oplog.CLIConfig
MetricsConfig opmetrics.CLIConfig
PprofConfig oppprof.CLIConfig
}
func (c CLIConfig) Check() error {
if err := c.RPCConfig.Check(); err != nil {
return err
}
if err := c.LogConfig.Check(); err != nil {
return err
}
if err := c.MetricsConfig.Check(); err != nil {
return err
}
if err := c.PprofConfig.Check(); err != nil {
return err
}
if err := c.TxMgrConfig.Check(); err != nil {
return err
}
return nil
}
// NewConfig parses the Config from the provided flags or environment variables.
func NewConfig(ctx *cli.Context) CLIConfig {
return CLIConfig{
// Required Flags
L1EthRpc: ctx.GlobalString(flags.L1EthRpcFlag.Name),
RollupRpc: ctx.GlobalString(flags.RollupRpcFlag.Name),
L2OOAddress: ctx.GlobalString(flags.L2OOAddressFlag.Name),
DGFAddress: ctx.GlobalString(flags.DGFAddressFlag.Name),
TxMgrConfig: txmgr.ReadCLIConfig(ctx),
// Optional Flags
RPCConfig: oprpc.ReadCLIConfig(ctx),
LogConfig: oplog.ReadCLIConfig(ctx),
MetricsConfig: opmetrics.ReadCLIConfig(ctx),
PprofConfig: oppprof.ReadCLIConfig(ctx),
}
}
package challenger
import (
"context"
"fmt"
_ "net/http/pprof"
"os"
"os/signal"
"syscall"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
oprpc "github.com/ethereum-optimism/optimism/op-service/rpc"
)
// Main is the entrypoint into the Challenger. This method executes the
// service and blocks until the service exits.
func Main(logger log.Logger, version string, cfg *config.Config) error {
if err := cfg.Check(); err != nil {
return fmt.Errorf("invalid config: %w", err)
}
m := metrics.NewMetrics("default")
logger.Info("Initializing Challenger")
challenger, err := NewChallenger(*cfg, logger, m)
if err != nil {
logger.Error("Unable to create the Challenger", "error", err)
return err
}
logger.Info("Starting Challenger")
ctx, cancel := context.WithCancel(context.Background())
if err := challenger.Start(); err != nil {
cancel()
logger.Error("Unable to start Challenger", "error", err)
return err
}
defer challenger.Stop()
logger.Info("Challenger started")
pprofConfig := cfg.PprofConfig
if pprofConfig.Enabled {
logger.Info("starting pprof", "addr", pprofConfig.ListenAddr, "port", pprofConfig.ListenPort)
go func() {
if err := oppprof.ListenAndServe(ctx, pprofConfig.ListenAddr, pprofConfig.ListenPort); err != nil {
logger.Error("error starting pprof", "err", err)
}
}()
}
metricsCfg := cfg.MetricsConfig
if metricsCfg.Enabled {
log.Info("starting metrics server", "addr", metricsCfg.ListenAddr, "port", metricsCfg.ListenPort)
go func() {
if err := m.Serve(ctx, metricsCfg.ListenAddr, metricsCfg.ListenPort); err != nil {
logger.Error("error starting metrics server", err)
}
}()
m.StartBalanceMetrics(ctx, logger, challenger.l1Client, challenger.txMgr.From())
}
rpcCfg := cfg.RPCConfig
server := oprpc.NewServer(rpcCfg.ListenAddr, rpcCfg.ListenPort, version, oprpc.WithLogger(logger))
if err := server.Start(); err != nil {
cancel()
return fmt.Errorf("error starting RPC server: %w", err)
}
m.RecordInfo(version)
m.RecordUp()
interruptChannel := make(chan os.Signal, 1)
signal.Notify(interruptChannel, []os.Signal{
os.Interrupt,
os.Kill,
syscall.SIGTERM,
syscall.SIGQUIT,
}...)
<-interruptChannel
cancel()
return nil
}
package main
import (
"fmt"
"os"
challenger "github.com/ethereum-optimism/optimism/op-challenger/challenger"
config "github.com/ethereum-optimism/optimism/op-challenger/config"
flags "github.com/ethereum-optimism/optimism/op-challenger/flags"
version "github.com/ethereum-optimism/optimism/op-challenger/version"
log "github.com/ethereum/go-ethereum/log"
cli "github.com/urfave/cli"
......@@ -12,30 +15,71 @@ import (
oplog "github.com/ethereum-optimism/optimism/op-service/log"
)
const Version = "0.1.0"
var (
GitCommit = ""
GitDate = ""
)
// VersionWithMeta holds the textual version string including the metadata.
var VersionWithMeta = func() string {
v := version.Version
if GitCommit != "" {
v += "-" + GitCommit[:8]
}
if GitDate != "" {
v += "-" + GitDate
}
if version.Meta != "" {
v += "-" + version.Meta
}
return v
}()
func main() {
args := os.Args
if err := run(args, challenger.Main); err != nil {
log.Crit("Application failed", "err", err)
}
}
type ConfigAction func(log log.Logger, version string, config *config.Config) error
// run parses the supplied args to create a config.Config instance, sets up logging
// then calls the supplied ConfigAction.
// This allows testing the translation from CLI arguments to Config
func run(args []string, action ConfigAction) error {
// Set up logger with a default INFO level in case we fail to parse flags,
// otherwise the final critical log won't show what the parsing error was.
oplog.SetupDefaults()
app := cli.NewApp()
app.Version = VersionWithMeta
app.Flags = flags.Flags
app.Version = Version
app.Name = "op-challenger"
app.Usage = "Challenge invalid L2OutputOracle outputs"
app.Usage = "Challenge Invalid L2OutputOracle Outputs"
app.Description = "A modular op-stack challenge agent for dispute games written in golang."
app.Action = curryMain(Version)
app.Commands = []cli.Command{}
app.Action = func(ctx *cli.Context) error {
logger, err := setupLogging(ctx)
if err != nil {
return err
}
logger.Info("Starting challenger", "version", VersionWithMeta)
err := app.Run(os.Args)
if err != nil {
log.Crit("Application failed", "message", err)
cfg, err := config.NewConfigFromCLI(ctx)
if err != nil {
return err
}
return action(logger, VersionWithMeta, cfg)
}
return app.Run(args)
}
// curryMain transforms the challenger.Main function into an app.Action
// This is done to capture the Version of the challenger.
func curryMain(version string) func(ctx *cli.Context) error {
return func(ctx *cli.Context) error {
return challenger.Main(version, ctx)
func setupLogging(ctx *cli.Context) (log.Logger, error) {
logCfg := oplog.ReadCLIConfig(ctx)
if err := logCfg.Check(); err != nil {
return nil, fmt.Errorf("log config error: %w", err)
}
logger := oplog.NewLogger(logCfg)
return logger, nil
}
package config
import (
"errors"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/urfave/cli"
flags "github.com/ethereum-optimism/optimism/op-challenger/flags"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
oprpc "github.com/ethereum-optimism/optimism/op-service/rpc"
txmgr "github.com/ethereum-optimism/optimism/op-service/txmgr"
)
var (
ErrMissingL1EthRPC = errors.New("missing l1 eth rpc url")
ErrMissingRollupRpc = errors.New("missing rollup rpc url")
ErrMissingL2OOAddress = errors.New("missing l2 output oracle contract address")
ErrMissingDGFAddress = errors.New("missing dispute game factory contract address")
ErrInvalidNetworkTimeout = errors.New("invalid network timeout")
ErrMissingTxMgrConfig = errors.New("missing tx manager config")
ErrMissingRPCConfig = errors.New("missing rpc config")
ErrMissingLogConfig = errors.New("missing log config")
ErrMissingMetricsConfig = errors.New("missing metrics config")
ErrMissingPprofConfig = errors.New("missing pprof config")
)
// Config is a well typed config that is parsed from the CLI params.
// This also contains config options for auxiliary services.
// It is used to initialize the challenger.
type Config struct {
// L1EthRpc is the HTTP provider URL for L1.
L1EthRpc string
// RollupRpc is the HTTP provider URL for the rollup node.
RollupRpc string
// L2OOAddress is the L2OutputOracle contract address.
L2OOAddress common.Address
// DGFAddress is the DisputeGameFactory contract address.
DGFAddress common.Address
// NetworkTimeout is the timeout for network requests.
NetworkTimeout time.Duration
TxMgrConfig *txmgr.CLIConfig
RPCConfig *oprpc.CLIConfig
LogConfig *oplog.CLIConfig
MetricsConfig *opmetrics.CLIConfig
PprofConfig *oppprof.CLIConfig
}
func (c Config) Check() error {
if c.L1EthRpc == "" {
return ErrMissingL1EthRPC
}
if c.RollupRpc == "" {
return ErrMissingRollupRpc
}
if c.L2OOAddress == (common.Address{}) {
return ErrMissingL2OOAddress
}
if c.DGFAddress == (common.Address{}) {
return ErrMissingDGFAddress
}
if c.NetworkTimeout == 0 {
return ErrInvalidNetworkTimeout
}
if c.TxMgrConfig == nil {
return ErrMissingTxMgrConfig
}
if c.RPCConfig == nil {
return ErrMissingRPCConfig
}
if c.LogConfig == nil {
return ErrMissingLogConfig
}
if c.MetricsConfig == nil {
return ErrMissingMetricsConfig
}
if c.PprofConfig == nil {
return ErrMissingPprofConfig
}
if err := c.RPCConfig.Check(); err != nil {
return err
}
if err := c.LogConfig.Check(); err != nil {
return err
}
if err := c.MetricsConfig.Check(); err != nil {
return err
}
if err := c.PprofConfig.Check(); err != nil {
return err
}
if err := c.TxMgrConfig.Check(); err != nil {
return err
}
return nil
}
// NewConfig creates a Config with all optional values set to the CLI default value
func NewConfig(
L1EthRpc string,
RollupRpc string,
L2OOAddress common.Address,
DGFAddress common.Address,
NetworkTimeout time.Duration,
TxMgrConfig *txmgr.CLIConfig,
RPCConfig *oprpc.CLIConfig,
LogConfig *oplog.CLIConfig,
MetricsConfig *opmetrics.CLIConfig,
PprofConfig *oppprof.CLIConfig,
) *Config {
return &Config{
L1EthRpc: L1EthRpc,
RollupRpc: RollupRpc,
L2OOAddress: L2OOAddress,
DGFAddress: DGFAddress,
NetworkTimeout: NetworkTimeout,
TxMgrConfig: TxMgrConfig,
RPCConfig: RPCConfig,
LogConfig: LogConfig,
MetricsConfig: MetricsConfig,
PprofConfig: PprofConfig,
}
}
// NewConfigFromCLI parses the Config from the provided flags or environment variables.
func NewConfigFromCLI(ctx *cli.Context) (*Config, error) {
l1EthRpc := ctx.GlobalString(flags.L1EthRpcFlag.Name)
if l1EthRpc == "" {
return nil, ErrMissingL1EthRPC
}
rollupRpc := ctx.GlobalString(flags.RollupRpcFlag.Name)
if rollupRpc == "" {
return nil, ErrMissingRollupRpc
}
l2ooAddress := common.HexToAddress(ctx.GlobalString(flags.L2OOAddressFlag.Name))
if l2ooAddress == (common.Address{}) {
return nil, ErrMissingL2OOAddress
}
dgfAddress := common.HexToAddress(ctx.GlobalString(flags.DGFAddressFlag.Name))
if dgfAddress == (common.Address{}) {
return nil, ErrMissingDGFAddress
}
txMgrConfig := txmgr.ReadCLIConfig(ctx)
rpcConfig := oprpc.ReadCLIConfig(ctx)
logConfig := oplog.ReadCLIConfig(ctx)
metricsConfig := opmetrics.ReadCLIConfig(ctx)
pprofConfig := oppprof.ReadCLIConfig(ctx)
return &Config{
// Required Flags
L1EthRpc: l1EthRpc,
RollupRpc: rollupRpc,
L2OOAddress: l2ooAddress,
DGFAddress: dgfAddress,
TxMgrConfig: &txMgrConfig,
// Optional Flags
RPCConfig: &rpcConfig,
LogConfig: &logConfig,
MetricsConfig: &metricsConfig,
PprofConfig: &pprofConfig,
}, nil
}
package config
import (
"testing"
"time"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
oprpc "github.com/ethereum-optimism/optimism/op-service/rpc"
txmgr "github.com/ethereum-optimism/optimism/op-service/txmgr"
client "github.com/ethereum-optimism/optimism/op-signer/client"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
var (
validL1EthRpc = "http://localhost:8545"
validRollupRpc = "http://localhost:8546"
validL2OOAddress = common.HexToAddress("0x7bdd3b028C4796eF0EAf07d11394d0d9d8c24139")
validDGFAddress = common.HexToAddress("0x7bdd3b028C4796eF0EAf07d11394d0d9d8c24139")
validNetworkTimeout = time.Duration(5) * time.Second
)
var validTxMgrConfig = txmgr.CLIConfig{
L1RPCURL: validL1EthRpc,
NumConfirmations: 10,
NetworkTimeout: validNetworkTimeout,
ResubmissionTimeout: time.Duration(5) * time.Second,
ReceiptQueryInterval: time.Duration(5) * time.Second,
TxNotInMempoolTimeout: time.Duration(5) * time.Second,
SafeAbortNonceTooLowCount: 10,
SignerCLIConfig: client.CLIConfig{
Endpoint: "http://localhost:8547",
// First address for the default hardhat mnemonic
Address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
},
}
var validRPCConfig = oprpc.CLIConfig{
ListenAddr: "localhost:8547",
ListenPort: 8547,
}
var validLogConfig = oplog.DefaultCLIConfig()
var validMetricsConfig = opmetrics.CLIConfig{
Enabled: false,
}
var validPprofConfig = oppprof.CLIConfig{
Enabled: false,
}
func validConfig() *Config {
cfg := NewConfig(
validL1EthRpc,
validRollupRpc,
validL2OOAddress,
validDGFAddress,
validNetworkTimeout,
&validTxMgrConfig,
&validRPCConfig,
&validLogConfig,
&validMetricsConfig,
&validPprofConfig,
)
return cfg
}
// TestValidConfigIsValid checks that the config provided by validConfig is actually valid
func TestValidConfigIsValid(t *testing.T) {
err := validConfig().Check()
require.NoError(t, err)
}
func TestTxMgrConfig(t *testing.T) {
t.Run("Required", func(t *testing.T) {
config := validConfig()
config.TxMgrConfig = nil
err := config.Check()
require.ErrorIs(t, err, ErrMissingTxMgrConfig)
})
t.Run("Invalid", func(t *testing.T) {
config := validConfig()
config.TxMgrConfig = &txmgr.CLIConfig{}
err := config.Check()
require.Equal(t, err.Error(), "must provide a L1 RPC url")
})
}
func TestL1EthRpcRequired(t *testing.T) {
config := validConfig()
config.L1EthRpc = ""
err := config.Check()
require.ErrorIs(t, err, ErrMissingL1EthRPC)
}
func TestRollupRpcRequired(t *testing.T) {
config := validConfig()
config.RollupRpc = ""
err := config.Check()
require.ErrorIs(t, err, ErrMissingRollupRpc)
}
func TestL2OOAddressRequired(t *testing.T) {
config := validConfig()
config.L2OOAddress = common.Address{}
err := config.Check()
require.ErrorIs(t, err, ErrMissingL2OOAddress)
}
func TestDGFAddressRequired(t *testing.T) {
config := validConfig()
config.DGFAddress = common.Address{}
err := config.Check()
require.ErrorIs(t, err, ErrMissingDGFAddress)
}
func TestNetworkTimeoutRequired(t *testing.T) {
config := validConfig()
config.NetworkTimeout = 0
err := config.Check()
require.ErrorIs(t, err, ErrInvalidNetworkTimeout)
}
package version
var (
Version = "v0.1.0"
Meta = "dev"
)
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