Commit 5a829ce7 authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

op-challenger: Apply game window to list-games (#10336)

Avoids it getting increasingly slower over time.
parent 98afa5b4
......@@ -3,6 +3,7 @@ package main
import (
"context"
"fmt"
"slices"
"sync"
"time"
......@@ -11,6 +12,7 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
opservice "github.com/ethereum-optimism/optimism/op-service"
"github.com/ethereum-optimism/optimism/op-service/clock"
"github.com/ethereum-optimism/optimism/op-service/dial"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum-optimism/optimism/op-service/sources/batching"
......@@ -33,6 +35,8 @@ func ListGames(ctx *cli.Context) error {
return err
}
gameWindow := ctx.Duration(flags.GameWindowFlag.Name)
l1Client, err := dial.DialEthClientWithTimeout(ctx.Context, dial.DefaultDialTimeout, logger, rpcUrl)
if err != nil {
return fmt.Errorf("failed to dial L1: %w", err)
......@@ -45,7 +49,7 @@ func ListGames(ctx *cli.Context) error {
if err != nil {
return fmt.Errorf("failed to retrieve current head block: %w", err)
}
return listGames(ctx.Context, caller, contract, head.Hash())
return listGames(ctx.Context, caller, contract, head.Hash(), gameWindow)
}
type gameInfo struct {
......@@ -57,11 +61,13 @@ type gameInfo struct {
err error
}
func listGames(ctx context.Context, caller *batching.MultiCaller, factory *contracts.DisputeGameFactoryContract, block common.Hash) error {
games, err := factory.GetAllGames(ctx, block)
func listGames(ctx context.Context, caller *batching.MultiCaller, factory *contracts.DisputeGameFactoryContract, block common.Hash, gameWindow time.Duration) error {
earliestTimestamp := clock.MinCheckedTimestamp(clock.SystemClock, gameWindow)
games, err := factory.GetGamesAtOrAfter(ctx, block, earliestTimestamp)
if err != nil {
return fmt.Errorf("failed to retrieve games: %w", err)
}
slices.Reverse(games)
infos := make([]*gameInfo, len(games))
var wg sync.WaitGroup
......@@ -95,13 +101,13 @@ func listGames(ctx context.Context, caller *batching.MultiCaller, factory *contr
wg.Wait()
lineFormat := "%3v %-42v %4v %-21v %14v %-66v %6v %-14v\n"
fmt.Printf(lineFormat, "Idx", "Game", "Type", "Created (Local)", "L2 Block", "Output Root", "Claims", "Status")
for idx, game := range infos {
for _, game := range infos {
if game.err != nil {
return game.err
}
created := time.Unix(int64(game.Timestamp), 0).Format(time.DateTime)
fmt.Printf(lineFormat,
idx, game.Proxy, game.GameType, created, game.l2BlockNum, game.rootClaim, game.claimCount, game.status)
game.Index, game.Proxy, game.GameType, created, game.l2BlockNum, game.rootClaim, game.claimCount, game.status)
}
return nil
}
......@@ -110,6 +116,7 @@ func listGamesFlags() []cli.Flag {
cliFlags := []cli.Flag{
flags.L1EthRpcFlag,
flags.FactoryAddressFlag,
flags.GameWindowFlag,
}
cliFlags = append(cliFlags, oplog.CLIFlags("OP_CHALLENGER")...)
return cliFlags
......
......@@ -73,7 +73,7 @@ func (f *DisputeGameFactoryContract) GetGame(ctx context.Context, idx uint64, bl
if err != nil {
return types.GameMetadata{}, fmt.Errorf("failed to load game %v: %w", idx, err)
}
return f.decodeGame(result), nil
return f.decodeGame(idx, result), nil
}
func (f *DisputeGameFactoryContract) GetGameImpl(ctx context.Context, gameType uint32) (common.Address, error) {
......@@ -118,8 +118,9 @@ func (f *DisputeGameFactoryContract) GetGamesAtOrAfter(ctx context.Context, bloc
return nil, fmt.Errorf("failed to fetch games: %w", err)
}
for _, result := range results {
game := f.decodeGame(result)
for i, result := range results {
idx := rangeEnd - uint64(i) - 1
game := f.decodeGame(idx, result)
if game.Timestamp < earliestTimestamp {
return games, nil
}
......@@ -147,8 +148,8 @@ func (f *DisputeGameFactoryContract) GetAllGames(ctx context.Context, blockHash
}
var games []types.GameMetadata
for _, result := range results {
games = append(games, f.decodeGame(result))
for i, result := range results {
games = append(games, f.decodeGame(uint64(i), result))
}
return games, nil
}
......@@ -189,11 +190,12 @@ func (f *DisputeGameFactoryContract) DecodeDisputeGameCreatedLog(rcpt *ethTypes.
return common.Address{}, 0, common.Hash{}, fmt.Errorf("%w: %v", ErrEventNotFound, eventDisputeGameCreated)
}
func (f *DisputeGameFactoryContract) decodeGame(result *batching.CallResult) types.GameMetadata {
func (f *DisputeGameFactoryContract) decodeGame(idx uint64, result *batching.CallResult) types.GameMetadata {
gameType := result.GetUint32(0)
timestamp := result.GetUint64(1)
proxy := result.GetAddress(2)
return types.GameMetadata{
Index: idx,
GameType: gameType,
Timestamp: timestamp,
Proxy: proxy,
......
......@@ -61,16 +61,19 @@ func TestLoadGame(t *testing.T) {
blockHash := common.Hash{0xbb, 0xce}
stubRpc, factory := setupDisputeGameFactoryTest(t)
game0 := types.GameMetadata{
Index: 0,
GameType: 0,
Timestamp: 1234,
Proxy: common.Address{0xaa},
}
game1 := types.GameMetadata{
Index: 1,
GameType: 1,
Timestamp: 5678,
Proxy: common.Address{0xbb},
}
game2 := types.GameMetadata{
Index: 2,
GameType: 99,
Timestamp: 9988,
Proxy: common.Address{0xcc},
......@@ -88,16 +91,19 @@ func TestGetAllGames(t *testing.T) {
blockHash := common.Hash{0xbb, 0xce}
stubRpc, factory := setupDisputeGameFactoryTest(t)
game0 := types.GameMetadata{
Index: 0,
GameType: 0,
Timestamp: 1234,
Proxy: common.Address{0xaa},
}
game1 := types.GameMetadata{
Index: 1,
GameType: 1,
Timestamp: 5678,
Proxy: common.Address{0xbb},
}
game2 := types.GameMetadata{
Index: 2,
GameType: 99,
Timestamp: 9988,
Proxy: common.Address{0xcc},
......@@ -135,6 +141,7 @@ func TestGetAllGamesAtOrAfter(t *testing.T) {
var allGames []types.GameMetadata
for i := 0; i < test.gameCount; i++ {
allGames = append(allGames, types.GameMetadata{
Index: uint64(i),
GameType: uint32(i),
Timestamp: uint64(i),
Proxy: common.Address{byte(i)},
......
......@@ -40,6 +40,7 @@ func GameStatusFromUint8(i uint8) (GameStatus, error) {
}
type GameMetadata struct {
Index uint64
GameType uint32
Timestamp uint64
Proxy common.Address
......
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