diff --git a/op-challenger/game/fault/agent.go b/op-challenger/game/fault/agent.go index e5b9cc73542d7932ad27b132a1e6ca3630b104b1..f2ae73f489ea69a45d6778a1708d34a83975643e 100644 --- a/op-challenger/game/fault/agent.go +++ b/op-challenger/game/fault/agent.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/solver" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum/go-ethereum/log" ) @@ -24,6 +25,7 @@ type ClaimLoader interface { } type Agent struct { + metrics metrics.Metricer solver *solver.Solver loader ClaimLoader responder Responder @@ -33,8 +35,9 @@ type Agent struct { log log.Logger } -func NewAgent(loader ClaimLoader, maxDepth int, trace types.TraceProvider, responder Responder, updater types.OracleUpdater, agreeWithProposedOutput bool, log log.Logger) *Agent { +func NewAgent(m metrics.Metricer, loader ClaimLoader, maxDepth int, trace types.TraceProvider, responder Responder, updater types.OracleUpdater, agreeWithProposedOutput bool, log log.Logger) *Agent { return &Agent{ + metrics: m, solver: solver.NewSolver(maxDepth, trace), loader: loader, responder: responder, @@ -134,6 +137,7 @@ func (a *Agent) move(ctx context.Context, claim types.Claim, game types.Game) er log.Debug("Skipping duplicate move") return nil } + a.metrics.RecordGameMove() log.Info("Performing move") return a.responder.Respond(ctx, move) } @@ -170,6 +174,7 @@ func (a *Agent) step(ctx context.Context, claim types.Claim, game types.Game) er a.log.Info("Performing step", "is_attack", step.IsAttack, "depth", step.LeafClaim.Depth(), "index_at_depth", step.LeafClaim.IndexAtDepth(), "value", step.LeafClaim.Value) + a.metrics.RecordGameStep() callData := types.StepCallData{ ClaimIndex: uint64(step.LeafClaim.ContractIndex), IsAttack: step.IsAttack, diff --git a/op-challenger/game/fault/agent_test.go b/op-challenger/game/fault/agent_test.go index dd18a9c7a2b7d840fdb2c6f75de5176c6810c368..117a3c7dc9b9fd0b72d274bc7413ba3d121957bd 100644 --- a/op-challenger/game/fault/agent_test.go +++ b/op-challenger/game/fault/agent_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" @@ -16,14 +17,14 @@ func TestShouldResolve(t *testing.T) { log := testlog.Logger(t, log.LvlCrit) t.Run("AgreeWithProposedOutput", func(t *testing.T) { - agent := NewAgent(nil, 0, nil, nil, nil, true, log) + agent := NewAgent(metrics.NoopMetrics, nil, 0, nil, nil, nil, true, log) require.False(t, agent.shouldResolve(context.Background(), types.GameStatusDefenderWon)) require.True(t, agent.shouldResolve(context.Background(), types.GameStatusChallengerWon)) require.False(t, agent.shouldResolve(context.Background(), types.GameStatusInProgress)) }) t.Run("DisagreeWithProposedOutput", func(t *testing.T) { - agent := NewAgent(nil, 0, nil, nil, nil, false, log) + agent := NewAgent(metrics.NoopMetrics, nil, 0, nil, nil, nil, false, log) require.True(t, agent.shouldResolve(context.Background(), types.GameStatusDefenderWon)) require.False(t, agent.shouldResolve(context.Background(), types.GameStatusChallengerWon)) require.False(t, agent.shouldResolve(context.Background(), types.GameStatusInProgress)) diff --git a/op-challenger/game/fault/player.go b/op-challenger/game/fault/player.go index b8904528bb108af60c9fe04bf4b28948ca545d73..d41100098296287a6b01c41b8a9feb8b54b38d60 100644 --- a/op-challenger/game/fault/player.go +++ b/op-challenger/game/fault/player.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -37,6 +38,7 @@ type GamePlayer struct { func NewGamePlayer( ctx context.Context, logger log.Logger, + m metrics.Metricer, cfg *config.Config, dir string, addr common.Address, @@ -105,7 +107,7 @@ func NewGamePlayer( } return &GamePlayer{ - act: NewAgent(loader, int(gameDepth), provider, responder, updater, cfg.AgreeWithProposedOutput, logger).Act, + act: NewAgent(m, loader, int(gameDepth), provider, responder, updater, cfg.AgreeWithProposedOutput, logger).Act, agreeWithProposedOutput: cfg.AgreeWithProposedOutput, loader: loader, logger: logger, diff --git a/op-challenger/game/monitor.go b/op-challenger/game/monitor.go index 6f205fab39d74e86ddc4dd4961b83f4169a62daa..303b546080dbfc8153392a9f37faa957e361b006 100644 --- a/op-challenger/game/monitor.go +++ b/op-challenger/game/monitor.go @@ -8,6 +8,7 @@ import ( "time" "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler" + "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-service/clock" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" @@ -26,6 +27,7 @@ type gameScheduler interface { type gameMonitor struct { logger log.Logger + metrics metrics.Metricer clock clock.Clock source gameSource scheduler gameScheduler @@ -36,6 +38,7 @@ type gameMonitor struct { func newGameMonitor( logger log.Logger, + m metrics.Metricer, cl clock.Clock, source gameSource, scheduler gameScheduler, @@ -45,6 +48,7 @@ func newGameMonitor( ) *gameMonitor { return &gameMonitor{ logger: logger, + metrics: m, clock: cl, scheduler: scheduler, source: source, diff --git a/op-challenger/game/monitor_test.go b/op-challenger/game/monitor_test.go index 732554c0b85f68660c6b6181408638e2128c21dc..105f8f73389e026c01002441cdaae4dfa80ccae3 100644 --- a/op-challenger/game/monitor_test.go +++ b/op-challenger/game/monitor_test.go @@ -6,6 +6,7 @@ import ( "testing" "time" + "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-node/testlog" "github.com/ethereum-optimism/optimism/op-service/clock" "github.com/ethereum/go-ethereum/common" @@ -100,7 +101,7 @@ func setupMonitorTest(t *testing.T, allowedGames []common.Address) (*gameMonitor return i, nil } sched := &stubScheduler{} - monitor := newGameMonitor(logger, clock.SystemClock, source, sched, time.Duration(0), fetchBlockNum, allowedGames) + monitor := newGameMonitor(logger, metrics.NoopMetrics, clock.SystemClock, source, sched, time.Duration(0), fetchBlockNum, allowedGames) return monitor, source, sched } diff --git a/op-challenger/game/service.go b/op-challenger/game/service.go index dc12e27dc33da8029b6f08d126527d8945dd8048..d176a559c7133ca42de1628dbf1b831e2813110a 100644 --- a/op-challenger/game/service.go +++ b/op-challenger/game/service.go @@ -72,10 +72,10 @@ func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*Se disk, cfg.MaxConcurrency, func(addr common.Address, dir string) (scheduler.GamePlayer, error) { - return fault.NewGamePlayer(ctx, logger, cfg, dir, addr, txMgr, client) + return fault.NewGamePlayer(ctx, logger, m, cfg, dir, addr, txMgr, client) }) - monitor := newGameMonitor(logger, cl, loader, sched, cfg.GameWindow, client.BlockNumber, cfg.GameAllowlist) + monitor := newGameMonitor(logger, m, cl, loader, sched, cfg.GameWindow, client.BlockNumber, cfg.GameAllowlist) m.RecordInfo(version.SimpleWithMeta) m.RecordUp() diff --git a/op-challenger/metrics/metrics.go b/op-challenger/metrics/metrics.go index cefc488eab35a91c28ff84cfd678f3975d5ac33b..e4f6c922bebc2aa18e6f7991918d9d6eecb2880e 100644 --- a/op-challenger/metrics/metrics.go +++ b/op-challenger/metrics/metrics.go @@ -20,6 +20,9 @@ type Metricer interface { // Record Tx metrics txmetrics.TxMetricer + + RecordGameStep() + RecordGameMove() } type Metrics struct { @@ -31,6 +34,9 @@ type Metrics struct { info prometheus.GaugeVec up prometheus.Gauge + + moves prometheus.Counter + steps prometheus.Counter } var _ Metricer = (*Metrics)(nil) @@ -58,6 +64,16 @@ func NewMetrics() *Metrics { Name: "up", Help: "1 if the op-challenger has finished starting up", }), + moves: factory.NewCounter(prometheus.CounterOpts{ + Namespace: Namespace, + Name: "moves", + Help: "Number of game moves made by the challenge agent", + }), + steps: factory.NewCounter(prometheus.CounterOpts{ + Namespace: Namespace, + Name: "steps", + Help: "Number of game steps made by the challenge agent", + }), } } @@ -84,3 +100,11 @@ func (m *Metrics) RecordUp() { func (m *Metrics) Document() []opmetrics.DocumentedMetric { return m.factory.Document() } + +func (m *Metrics) RecordGameMove() { + m.moves.Add(1) +} + +func (m *Metrics) RecordGameStep() { + m.steps.Add(1) +} diff --git a/op-challenger/metrics/noop.go b/op-challenger/metrics/noop.go index 052d288092e85d20e97fe0d3e8200ed39f5742d9..33ecdf3c8ed183b2b50a3d80b878248ad0bd4fc4 100644 --- a/op-challenger/metrics/noop.go +++ b/op-challenger/metrics/noop.go @@ -12,3 +12,5 @@ var NoopMetrics Metricer = new(noopMetrics) func (*noopMetrics) RecordInfo(version string) {} func (*noopMetrics) RecordUp() {} +func (*noopMetrics) RecordGameMove() {} +func (*noopMetrics) RecordGameStep() {}