Commit 1ec22b75 authored by Andreas Bigger's avatar Andreas Bigger

Challenger subcommands

parent 3d297905
......@@ -54,6 +54,24 @@ type Challenger struct {
networkTimeout time.Duration
}
// From returns the address of the account used to send transactions.
func (c *Challenger) From() common.Address {
return c.txMgr.From()
}
// Client returns the client for the settlement layer.
func (c *Challenger) Client() *ethclient.Client {
return c.l1Client
}
func (c *Challenger) NewOracleSubscription() (*Subscription, error) {
query, err := c.BuildOutputLogFilter()
if err != nil {
return nil, err
}
return NewSubscription(query, c.Client(), c.log), nil
}
// NewChallenger creates a new Challenger
func NewChallenger(cfg config.Config, l log.Logger, m metrics.Metricer) (*Challenger, error) {
ctx, cancel := context.WithCancel(context.Background())
......
......@@ -34,3 +34,8 @@ func BuildOutputLogFilter(l2ooABI *abi.ABI) (ethereum.FilterQuery, error) {
return query, nil
}
// BuildOutputLogFilter creates a filter query for the L2OutputOracle contract.
func (c *Challenger) BuildOutputLogFilter() (ethereum.FilterQuery, error) {
return BuildOutputLogFilter(c.l2ooABI)
}
......@@ -61,6 +61,11 @@ func (s *Subscription) Started() bool {
return s.started
}
// Logs returns the log channel.
func (s *Subscription) Logs() <-chan types.Log {
return s.logs
}
// Subscribe constructs the subscription.
func (s *Subscription) Subscribe() error {
s.log.Info("Subscribing to", "query", s.query.Topics, "id", s.id)
......
package challenger
package main
import (
"context"
......@@ -10,8 +10,11 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-service/opio"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
oprpc "github.com/ethereum-optimism/optimism/op-service/rpc"
"github.com/ethereum-optimism/optimism/op-challenger/challenger"
"github.com/ethereum-optimism/optimism/op-service/pprof"
"github.com/ethereum-optimism/optimism/op-service/rpc"
)
// Main is the entrypoint into the Challenger. This method executes the
......@@ -24,7 +27,7 @@ func Main(logger log.Logger, version string, cfg *config.Config) error {
m := metrics.NewMetrics("default")
logger.Info("Initializing Challenger")
challenger, err := NewChallenger(*cfg, logger, m)
service, err := challenger.NewChallenger(*cfg, logger, m)
if err != nil {
logger.Error("Unable to create the Challenger", "error", err)
return err
......@@ -32,19 +35,19 @@ func Main(logger log.Logger, version string, cfg *config.Config) error {
logger.Info("Starting Challenger")
ctx, cancel := context.WithCancel(context.Background())
if err := challenger.Start(); err != nil {
if err := service.Start(); err != nil {
cancel()
logger.Error("Unable to start Challenger", "error", err)
return err
}
defer challenger.Stop()
defer service.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 {
if err := pprof.ListenAndServe(ctx, pprofConfig.ListenAddr, pprofConfig.ListenPort); err != nil {
logger.Error("error starting pprof", "err", err)
}
}()
......@@ -58,11 +61,11 @@ func Main(logger log.Logger, version string, cfg *config.Config) error {
logger.Error("error starting metrics server", err)
}
}()
m.StartBalanceMetrics(ctx, logger, challenger.l1Client, challenger.txMgr.From())
m.StartBalanceMetrics(ctx, logger, service.Client(), service.From())
}
rpcCfg := cfg.RPCConfig
server := oprpc.NewServer(rpcCfg.ListenAddr, rpcCfg.ListenPort, version, oprpc.WithLogger(logger))
server := rpc.NewServer(rpcCfg.ListenAddr, rpcCfg.ListenPort, version, rpc.WithLogger(logger))
if err := server.Start(); err != nil {
cancel()
return fmt.Errorf("error starting RPC server: %w", err)
......
package main
import (
"fmt"
"os"
challenger "github.com/ethereum-optimism/optimism/op-challenger/challenger"
log "github.com/ethereum/go-ethereum/log"
cli "github.com/urfave/cli"
watch "github.com/ethereum-optimism/optimism/op-challenger/cmd/watch"
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"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
)
......@@ -37,7 +36,7 @@ var VersionWithMeta = func() string {
func main() {
args := os.Args
if err := run(args, challenger.Main); err != nil {
if err := run(args, Main); err != nil {
log.Crit("Application failed", "err", err)
}
}
......@@ -59,7 +58,7 @@ func run(args []string, action ConfigAction) error {
app.Usage = "Challenge Invalid L2OutputOracle Outputs"
app.Description = "A modular op-stack challenge agent for dispute games written in golang."
app.Action = func(ctx *cli.Context) error {
logger, err := setupLogging(ctx)
logger, err := config.LoggerFromCLI(ctx)
if err != nil {
return err
}
......@@ -71,15 +70,12 @@ func run(args []string, action ConfigAction) error {
}
return action(logger, VersionWithMeta, cfg)
}
app.Commands = []cli.Command{
{
Name: "watch",
Subcommands: watch.Subcommands,
},
}
return app.Run(args)
}
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 watch
import (
"github.com/urfave/cli"
"github.com/ethereum-optimism/optimism/op-challenger/config"
)
var Subcommands = cli.Commands{
{
Name: "oracle",
Usage: "Watches the L2OutputOracle for new output proposals",
Action: func(ctx *cli.Context) error {
logger, err := config.LoggerFromCLI(ctx)
if err != nil {
return err
}
logger.Info("Listening for new output proposals")
cfg, err := config.NewConfigFromCLI(ctx)
if err != nil {
return err
}
return Oracle(logger, cfg)
},
},
{
Name: "factory",
Usage: "Watches the DisputeGameFactory for new dispute games",
Action: func(ctx *cli.Context) error {
panic("factory not implemented")
},
},
}
package watch
import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
log "github.com/ethereum/go-ethereum/log"
challenger "github.com/ethereum-optimism/optimism/op-challenger/challenger"
config "github.com/ethereum-optimism/optimism/op-challenger/config"
metrics "github.com/ethereum-optimism/optimism/op-challenger/metrics"
)
// Oracle listens to the L2OutputOracle for newly proposed outputs.
func Oracle(logger log.Logger, cfg *config.Config) error {
if err := cfg.Check(); err != nil {
return fmt.Errorf("invalid config: %w", err)
}
m := metrics.NewMetrics("default")
service, err := challenger.NewChallenger(*cfg, logger, m)
if err != nil {
logger.Error("Unable to create the Challenger", "error", err)
return err
}
logger.Info("Listening for OutputProposed events from the L2OutputOracle contract", "l2oo", cfg.L2OOAddress.String())
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
subscription, err := service.NewOracleSubscription()
if err != nil {
logger.Error("Unable to create the subscription", "error", err)
return err
}
err = subscription.Subscribe()
if err != nil {
logger.Error("Unable to subscribe to the L2OutputOracle contract", "error", err)
return 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, service.Client(), service.From())
}
m.RecordUp()
interruptChannel := make(chan os.Signal, 1)
signal.Notify(interruptChannel, []os.Signal{
os.Interrupt,
os.Kill,
syscall.SIGTERM,
syscall.SIGQUIT,
}...)
for {
select {
case log := <-subscription.Logs():
logger.Info("Received log", "log", log)
case <-interruptChannel:
logger.Info("Received interrupt signal, exiting...")
}
}
}
package config
import (
"fmt"
log "github.com/ethereum/go-ethereum/log"
cli "github.com/urfave/cli"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
)
// LoggerFromCLI creates a [log.Logger] from the
// supplied [cli.Context].
func LoggerFromCLI(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
}
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