Commit 33328e78 authored by Adrian Sutton's avatar Adrian Sutton

op-challenger: Pass through full game data when creating player instead of just address.

First step towards selecting the game to create based on game type and supporting multiple game types in one instance.
parent c6613a43
package game
package loader
import (
"context"
......@@ -6,6 +6,7 @@ import (
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
)
......@@ -25,25 +26,19 @@ type MinimalDisputeGameFactoryCaller interface {
}, error)
}
type FaultDisputeGame struct {
GameType uint8
Timestamp uint64
Proxy common.Address
}
type gameLoader struct {
type GameLoader struct {
caller MinimalDisputeGameFactoryCaller
}
// NewGameLoader creates a new services that can be used to fetch on chain dispute games.
func NewGameLoader(caller MinimalDisputeGameFactoryCaller) *gameLoader {
return &gameLoader{
func NewGameLoader(caller MinimalDisputeGameFactoryCaller) *GameLoader {
return &GameLoader{
caller: caller,
}
}
// FetchAllGamesAtBlock fetches all dispute games from the factory at a given block number.
func (l *gameLoader) FetchAllGamesAtBlock(ctx context.Context, earliestTimestamp uint64, blockNumber *big.Int) ([]FaultDisputeGame, error) {
func (l *GameLoader) FetchAllGamesAtBlock(ctx context.Context, earliestTimestamp uint64, blockNumber *big.Int) ([]types.GameData, error) {
if blockNumber == nil {
return nil, ErrMissingBlockNumber
}
......@@ -56,7 +51,7 @@ func (l *gameLoader) FetchAllGamesAtBlock(ctx context.Context, earliestTimestamp
return nil, fmt.Errorf("failed to fetch game count: %w", err)
}
games := make([]FaultDisputeGame, 0)
games := make([]types.GameData, 0)
if gameCount.Uint64() == 0 {
return games, nil
}
......
package game
package loader
import (
"context"
......@@ -6,6 +6,7 @@ import (
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
......@@ -78,18 +79,18 @@ func TestGameLoader_FetchAllGames(t *testing.T) {
expectedGames := test.caller.games
expectedGames = expectedGames[len(expectedGames)-test.expectedLen:]
if test.expectedErr != nil {
expectedGames = make([]FaultDisputeGame, 0)
expectedGames = make([]types.GameData, 0)
}
require.ElementsMatch(t, expectedGames, translateGames(games))
})
}
}
func generateMockGames(count uint64) []FaultDisputeGame {
games := make([]FaultDisputeGame, count)
func generateMockGames(count uint64) []types.GameData {
games := make([]types.GameData, count)
for i := uint64(0); i < count; i++ {
games[i] = FaultDisputeGame{
games[i] = types.GameData{
Proxy: common.BigToAddress(big.NewInt(int64(i))),
Timestamp: i * 100,
}
......@@ -98,8 +99,8 @@ func generateMockGames(count uint64) []FaultDisputeGame {
return games
}
func translateGames(games []FaultDisputeGame) []FaultDisputeGame {
translated := make([]FaultDisputeGame, len(games))
func translateGames(games []types.GameData) []types.GameData {
translated := make([]types.GameData, len(games))
for i, game := range games {
translated[i] = translateFaultDisputeGame(game)
......@@ -108,8 +109,8 @@ func translateGames(games []FaultDisputeGame) []FaultDisputeGame {
return translated
}
func translateFaultDisputeGame(game FaultDisputeGame) FaultDisputeGame {
return FaultDisputeGame{
func translateFaultDisputeGame(game types.GameData) types.GameData {
return types.GameData{
Proxy: game.Proxy,
Timestamp: game.Timestamp,
}
......@@ -131,7 +132,7 @@ type mockMinimalDisputeGameFactoryCaller struct {
gameCountErr bool
indexErrors []bool
gameCount uint64
games []FaultDisputeGame
games []types.GameData
}
func newMockMinimalDisputeGameFactoryCaller(count uint64, gameCountErr bool, indexErrors bool) *mockMinimalDisputeGameFactoryCaller {
......
......@@ -8,6 +8,7 @@ import (
"time"
"github.com/ethereum-optimism/optimism/op-challenger/game/scheduler"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-service/clock"
"github.com/ethereum-optimism/optimism/op-service/eth"
......@@ -22,11 +23,11 @@ type blockNumberFetcher func(ctx context.Context) (uint64, error)
// gameSource loads information about the games available to play
type gameSource interface {
FetchAllGamesAtBlock(ctx context.Context, earliest uint64, blockNumber *big.Int) ([]FaultDisputeGame, error)
FetchAllGamesAtBlock(ctx context.Context, earliest uint64, blockNumber *big.Int) ([]types.GameData, error)
}
type gameScheduler interface {
Schedule([]common.Address) error
Schedule([]types.GameData) error
}
type gameMonitor struct {
......@@ -104,13 +105,13 @@ func (m *gameMonitor) progressGames(ctx context.Context, blockNum uint64) error
if err != nil {
return fmt.Errorf("failed to load games: %w", err)
}
var gamesToPlay []common.Address
var gamesToPlay []types.GameData
for _, game := range games {
if !m.allowedGame(game.Proxy) {
m.logger.Debug("Skipping game not on allow list", "game", game.Proxy)
continue
}
gamesToPlay = append(gamesToPlay, game.Proxy)
gamesToPlay = append(gamesToPlay, game)
}
if err := m.scheduler.Schedule(gamesToPlay); errors.Is(err, scheduler.ErrBusy) {
m.logger.Info("Scheduler still busy with previous update")
......
......@@ -7,6 +7,7 @@ import (
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
......@@ -51,7 +52,7 @@ func TestMonitorGames(t *testing.T) {
addr1 := common.Address{0xaa}
addr2 := common.Address{0xbb}
monitor, source, sched, mockHeadSource := setupMonitorTest(t, []common.Address{})
source.games = []FaultDisputeGame{newFDG(addr1, 9999), newFDG(addr2, 9999)}
source.games = []types.GameData{newFDG(addr1, 9999), newFDG(addr2, 9999)}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
......@@ -93,7 +94,7 @@ func TestMonitorGames(t *testing.T) {
addr1 := common.Address{0xaa}
addr2 := common.Address{0xbb}
monitor, source, sched, mockHeadSource := setupMonitorTest(t, []common.Address{})
source.games = []FaultDisputeGame{newFDG(addr1, 9999), newFDG(addr2, 9999)}
source.games = []types.GameData{newFDG(addr1, 9999), newFDG(addr2, 9999)}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
......@@ -139,7 +140,7 @@ func TestMonitorCreateAndProgressGameAgents(t *testing.T) {
addr1 := common.Address{0xaa}
addr2 := common.Address{0xbb}
source.games = []FaultDisputeGame{newFDG(addr1, 9999), newFDG(addr2, 9999)}
source.games = []types.GameData{newFDG(addr1, 9999), newFDG(addr2, 9999)}
require.NoError(t, monitor.progressGames(context.Background(), uint64(1)))
......@@ -151,7 +152,7 @@ func TestMonitorOnlyScheduleSpecifiedGame(t *testing.T) {
addr1 := common.Address{0xaa}
addr2 := common.Address{0xbb}
monitor, source, sched, _ := setupMonitorTest(t, []common.Address{addr2})
source.games = []FaultDisputeGame{newFDG(addr1, 9999), newFDG(addr2, 9999)}
source.games = []types.GameData{newFDG(addr1, 9999), newFDG(addr2, 9999)}
require.NoError(t, monitor.progressGames(context.Background(), uint64(1)))
......@@ -159,8 +160,8 @@ func TestMonitorOnlyScheduleSpecifiedGame(t *testing.T) {
require.Equal(t, []common.Address{addr2}, sched.scheduled[0])
}
func newFDG(proxy common.Address, timestamp uint64) FaultDisputeGame {
return FaultDisputeGame{
func newFDG(proxy common.Address, timestamp uint64) types.GameData {
return types.GameData{
Proxy: proxy,
Timestamp: timestamp,
}
......@@ -222,14 +223,14 @@ func (m *mockSubscription) Err() <-chan error {
}
type stubGameSource struct {
games []FaultDisputeGame
games []types.GameData
}
func (s *stubGameSource) FetchAllGamesAtBlock(
ctx context.Context,
earliest uint64,
blockNumber *big.Int,
) ([]FaultDisputeGame, error) {
) ([]types.GameData, error) {
return s.games, nil
}
......@@ -237,7 +238,11 @@ type stubScheduler struct {
scheduled [][]common.Address
}
func (s *stubScheduler) Schedule(games []common.Address) error {
s.scheduled = append(s.scheduled, games)
func (s *stubScheduler) Schedule(games []types.GameData) error {
var addrs []common.Address
for _, game := range games {
addrs = append(addrs, game.Proxy)
}
s.scheduled = append(s.scheduled, addrs)
return nil
}
......@@ -14,7 +14,7 @@ import (
var errUnknownGame = errors.New("unknown game")
type PlayerCreator func(address common.Address, dir string) (GamePlayer, error)
type PlayerCreator func(game types.GameData, dir string) (GamePlayer, error)
type gameState struct {
player GamePlayer
......@@ -44,10 +44,12 @@ type coordinator struct {
// To avoid deadlock, it may process results from the inbound resultQueue while adding jobs to the outbound jobQueue.
// Returns an error if a game couldn't be scheduled because of an error. It will continue attempting to progress
// all games even if an error occurs with one game.
func (c *coordinator) schedule(ctx context.Context, games []common.Address) error {
func (c *coordinator) schedule(ctx context.Context, games []types.GameData) error {
// First remove any game states we no longer require
for addr, state := range c.states {
if !state.inflight && !slices.Contains(games, addr) {
if !state.inflight && !slices.ContainsFunc(games, func(candidate types.GameData) bool {
return candidate.Proxy == addr
}) {
delete(c.states, addr)
}
}
......@@ -60,14 +62,14 @@ func (c *coordinator) schedule(ctx context.Context, games []common.Address) erro
// Next collect all the jobs to schedule and ensure all games are recorded in the states map.
// Otherwise, results may start being processed before all games are recorded, resulting in existing
// data directories potentially being deleted for games that are required.
for _, addr := range games {
if j, err := c.createJob(addr); err != nil {
errs = append(errs, fmt.Errorf("failed to create job for game %v: %w", addr, err))
for _, game := range games {
if j, err := c.createJob(game); err != nil {
errs = append(errs, fmt.Errorf("failed to create job for game %v: %w", game.Proxy, err))
} else if j != nil {
jobs = append(jobs, *j)
c.m.RecordGameUpdateScheduled()
}
state, ok := c.states[addr]
state, ok := c.states[game.Proxy]
if ok {
switch state.status {
case types.GameStatusInProgress:
......@@ -78,7 +80,7 @@ func (c *coordinator) schedule(ctx context.Context, games []common.Address) erro
gamesChallengerWon++
}
} else {
c.logger.Warn("Game not found in states map", "game", addr)
c.logger.Warn("Game not found in states map", "game", game.Proxy)
}
}
c.m.RecordGamesStatus(gamesInProgress, gamesDefenderWon, gamesChallengerWon)
......@@ -94,11 +96,11 @@ func (c *coordinator) schedule(ctx context.Context, games []common.Address) erro
// createJob updates the state for the specified game and returns the job to enqueue for it, if any
// Returns (nil, nil) when there is no error and no job to enqueue
func (c *coordinator) createJob(game common.Address) (*job, error) {
state, ok := c.states[game]
func (c *coordinator) createJob(game types.GameData) (*job, error) {
state, ok := c.states[game.Proxy]
if !ok {
state = &gameState{}
c.states[game] = state
c.states[game.Proxy] = state
}
if state.inflight {
c.logger.Debug("Not rescheduling already in-flight game", "game", game)
......@@ -106,7 +108,7 @@ func (c *coordinator) createJob(game common.Address) (*job, error) {
}
// Create the player separately to the state so we retry creating it if it fails on the first attempt.
if state.player == nil {
player, err := c.createPlayer(game, c.disk.DirForGame(game))
player, err := c.createPlayer(game, c.disk.DirForGame(game.Proxy))
if err != nil {
return nil, fmt.Errorf("failed to create game player: %w", err)
}
......@@ -118,7 +120,7 @@ func (c *coordinator) createJob(game common.Address) (*job, error) {
c.logger.Debug("Not rescheduling resolved game", "game", game, "status", state.status)
return nil, nil
}
return &job{addr: game, player: state.player, status: state.status}, nil
return &job{addr: game.Proxy, player: state.player, status: state.status}, nil
}
func (c *coordinator) enqueueJob(ctx context.Context, j job) error {
......
......@@ -20,7 +20,7 @@ func TestScheduleNewGames(t *testing.T) {
gameAddr2 := common.Address{0xbb}
gameAddr3 := common.Address{0xcc}
ctx := context.Background()
require.NoError(t, c.schedule(ctx, []common.Address{gameAddr1, gameAddr2, gameAddr3}))
require.NoError(t, c.schedule(ctx, asGames(gameAddr1, gameAddr2, gameAddr3)))
require.Len(t, workQueue, 3, "should schedule job for each game")
require.Len(t, games.created, 3, "should have created players")
......@@ -41,11 +41,11 @@ func TestSkipSchedulingInflightGames(t *testing.T) {
ctx := context.Background()
// Schedule the game once
require.NoError(t, c.schedule(ctx, []common.Address{gameAddr1}))
require.NoError(t, c.schedule(ctx, asGames(gameAddr1)))
require.Len(t, workQueue, 1, "should schedule game")
// And then attempt to schedule again
require.NoError(t, c.schedule(ctx, []common.Address{gameAddr1}))
require.NoError(t, c.schedule(ctx, asGames(gameAddr1)))
require.Len(t, workQueue, 1, "should not reschedule in-flight game")
}
......@@ -57,7 +57,7 @@ func TestExitWhenContextDoneWhileSchedulingJob(t *testing.T) {
cancel() // Context is cancelled
// Should not block because the context is done.
err := c.schedule(ctx, []common.Address{gameAddr1})
err := c.schedule(ctx, asGames(gameAddr1))
require.ErrorIs(t, err, context.Canceled)
require.Empty(t, workQueue, "should not have been able to schedule game")
}
......@@ -68,7 +68,7 @@ func TestScheduleGameAgainAfterCompletion(t *testing.T) {
ctx := context.Background()
// Schedule the game once
require.NoError(t, c.schedule(ctx, []common.Address{gameAddr1}))
require.NoError(t, c.schedule(ctx, asGames(gameAddr1)))
require.Len(t, workQueue, 1, "should schedule game")
// Read the job
......@@ -79,7 +79,7 @@ func TestScheduleGameAgainAfterCompletion(t *testing.T) {
require.NoError(t, c.processResult(j))
// And then attempt to schedule again
require.NoError(t, c.schedule(ctx, []common.Address{gameAddr1}))
require.NoError(t, c.schedule(ctx, asGames(gameAddr1)))
require.Len(t, workQueue, 1, "should reschedule completed game")
}
......@@ -113,7 +113,7 @@ func TestProcessResultsWhileJobQueueFull(t *testing.T) {
// Even though work queue length is only 1, should be able to schedule all three games
// by reading and processing results
require.NoError(t, c.schedule(ctx, []common.Address{gameAddr1, gameAddr2, gameAddr3}))
require.NoError(t, c.schedule(ctx, asGames(gameAddr1, gameAddr2, gameAddr3)))
require.Len(t, games.created, 3, "should have created 3 games")
loop:
......@@ -139,7 +139,7 @@ func TestDeleteDataForResolvedGames(t *testing.T) {
ctx := context.Background()
// First get game 3 marked as resolved
require.NoError(t, c.schedule(ctx, []common.Address{gameAddr3}))
require.NoError(t, c.schedule(ctx, asGames(gameAddr3)))
require.Len(t, workQueue, 1)
j := <-workQueue
j.status = types.GameStatusDefenderWon
......@@ -147,8 +147,8 @@ func TestDeleteDataForResolvedGames(t *testing.T) {
// But ensure its data directory is marked as existing
disk.DirForGame(gameAddr3)
gameAddrs := []common.Address{gameAddr1, gameAddr2, gameAddr3}
require.NoError(t, c.schedule(ctx, gameAddrs))
games := asGames(gameAddr1, gameAddr2, gameAddr3)
require.NoError(t, c.schedule(ctx, games))
// The work queue should only contain jobs for games 1 and 2
// A resolved game should not be scheduled for an update.
......@@ -158,7 +158,7 @@ func TestDeleteDataForResolvedGames(t *testing.T) {
// Game 1 progresses and is still in progress
// Game 2 progresses and is now resolved
// Game 3 hasn't yet progressed (update is still in flight)
for i := 0; i < len(gameAddrs)-1; i++ {
for i := 0; i < len(games)-1; i++ {
j := <-workQueue
if j.addr == gameAddr2 {
j.status = types.GameStatusDefenderWon
......@@ -179,8 +179,8 @@ func TestDoNotDeleteDataForGameThatFailedToCreatePlayer(t *testing.T) {
games.creationFails = gameAddr1
gameAddrs := []common.Address{gameAddr1, gameAddr2}
err := c.schedule(ctx, gameAddrs)
gameList := asGames(gameAddr1, gameAddr2)
err := c.schedule(ctx, gameList)
require.Error(t, err)
// Game 1 won't be scheduled because the player failed to be created
......@@ -194,8 +194,8 @@ func TestDoNotDeleteDataForGameThatFailedToCreatePlayer(t *testing.T) {
// Should create player for game 1 next time its scheduled
games.creationFails = common.Address{}
require.NoError(t, c.schedule(ctx, gameAddrs))
require.Len(t, workQueue, len(gameAddrs), "should schedule all games")
require.NoError(t, c.schedule(ctx, gameList))
require.Len(t, workQueue, len(gameList), "should schedule all games")
j := <-workQueue
require.Equal(t, gameAddr1, j.addr, "first job should be for first game")
......@@ -211,7 +211,7 @@ func TestDropOldGameStates(t *testing.T) {
ctx := context.Background()
// Start tracking game 1, 2 and 3
require.NoError(t, c.schedule(ctx, []common.Address{gameAddr1, gameAddr2, gameAddr3}))
require.NoError(t, c.schedule(ctx, asGames(gameAddr1, gameAddr2, gameAddr3)))
require.Len(t, workQueue, 3, "should schedule games")
// Complete processing of games 1 and 2, leaving 3 in flight
......@@ -219,7 +219,7 @@ func TestDropOldGameStates(t *testing.T) {
require.NoError(t, c.processResult(<-workQueue))
// Next update only has games 2 and 4
require.NoError(t, c.schedule(ctx, []common.Address{gameAddr2, gameAddr4}))
require.NoError(t, c.schedule(ctx, asGames(gameAddr2, gameAddr4)))
require.NotContains(t, c.states, gameAddr1, "should drop state for game 1")
require.Contains(t, c.states, gameAddr2, "should keep state for game 2 (still active)")
......@@ -263,7 +263,8 @@ type createdGames struct {
created map[common.Address]*stubGame
}
func (c *createdGames) CreateGame(addr common.Address, dir string) (GamePlayer, error) {
func (c *createdGames) CreateGame(fdg types.GameData, dir string) (GamePlayer, error) {
addr := fdg.Proxy
if c.creationFails == addr {
return nil, fmt.Errorf("refusing to create player for game: %v", addr)
}
......@@ -303,3 +304,13 @@ func (s *stubDiskManager) RemoveAllExcept(addrs []common.Address) error {
}
return nil
}
func asGames(addrs ...common.Address) []types.GameData {
var games []types.GameData
for _, addr := range addrs {
games = append(games, types.GameData{
Proxy: addr,
})
}
return games
}
......@@ -5,7 +5,7 @@ import (
"errors"
"sync"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum/go-ethereum/log"
)
......@@ -26,7 +26,7 @@ type Scheduler struct {
coordinator *coordinator
m SchedulerMetricer
maxConcurrency uint
scheduleQueue chan []common.Address
scheduleQueue chan []types.GameData
jobQueue chan job
resultQueue chan job
wg sync.WaitGroup
......@@ -41,7 +41,7 @@ func NewScheduler(logger log.Logger, m SchedulerMetricer, disk DiskManager, maxC
// scheduleQueue has a size of 1 so backpressure quickly propagates to the caller
// allowing them to potentially skip update cycles.
scheduleQueue := make(chan []common.Address, 1)
scheduleQueue := make(chan []types.GameData, 1)
return &Scheduler{
logger: logger,
......@@ -84,7 +84,7 @@ func (s *Scheduler) Close() error {
return nil
}
func (s *Scheduler) Schedule(games []common.Address) error {
func (s *Scheduler) Schedule(games []types.GameData) error {
select {
case s.scheduleQueue <- games:
return nil
......
......@@ -4,6 +4,7 @@ import (
"context"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/common"
......@@ -14,7 +15,7 @@ import (
func TestSchedulerProcessesGames(t *testing.T) {
logger := testlog.Logger(t, log.LvlInfo)
ctx := context.Background()
createPlayer := func(addr common.Address, dir string) (GamePlayer, error) {
createPlayer := func(g types.GameData, dir string) (GamePlayer, error) {
return &stubPlayer{}, nil
}
removeExceptCalls := make(chan []common.Address)
......@@ -25,7 +26,7 @@ func TestSchedulerProcessesGames(t *testing.T) {
gameAddr1 := common.Address{0xaa}
gameAddr2 := common.Address{0xbb}
gameAddr3 := common.Address{0xcc}
games := []common.Address{gameAddr1, gameAddr2, gameAddr3}
games := asGames(gameAddr1, gameAddr2, gameAddr3)
require.NoError(t, s.Schedule(games))
......@@ -34,7 +35,7 @@ func TestSchedulerProcessesGames(t *testing.T) {
kept := <-removeExceptCalls
require.Len(t, kept, len(games), "should keep all games")
for _, game := range games {
require.Containsf(t, kept, game, "should keep game %v", game)
require.Containsf(t, kept, game.Proxy, "should keep game %v", game.Proxy)
}
}
require.NoError(t, s.Close())
......@@ -42,7 +43,7 @@ func TestSchedulerProcessesGames(t *testing.T) {
func TestReturnBusyWhenScheduleQueueFull(t *testing.T) {
logger := testlog.Logger(t, log.LvlInfo)
createPlayer := func(addr common.Address, dir string) (GamePlayer, error) {
createPlayer := func(game types.GameData, dir string) (GamePlayer, error) {
return &stubPlayer{}, nil
}
removeExceptCalls := make(chan []common.Address)
......@@ -50,10 +51,10 @@ func TestReturnBusyWhenScheduleQueueFull(t *testing.T) {
s := NewScheduler(logger, metrics.NoopMetrics, disk, 2, createPlayer)
// Scheduler not started - first call fills the queue
require.NoError(t, s.Schedule([]common.Address{{0xaa}}))
require.NoError(t, s.Schedule(asGames(common.Address{0xaa})))
// Second call should return busy
err := s.Schedule([]common.Address{{0xaa}})
err := s.Schedule(asGames(common.Address{0xaa}))
require.ErrorIs(t, err, ErrBusy)
}
......
......@@ -8,7 +8,9 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault"
"github.com/ethereum-optimism/optimism/op-challenger/game/loader"
"github.com/ethereum-optimism/optimism/op-challenger/game/scheduler"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-challenger/version"
opClient "github.com/ethereum-optimism/optimism/op-service/client"
......@@ -17,7 +19,6 @@ import (
"github.com/ethereum-optimism/optimism/op-service/httputil"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
)
......@@ -87,11 +88,11 @@ func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*Se
m.StartBalanceMetrics(ctx, logger, l1Client, txMgr.From())
}
factory, err := bindings.NewDisputeGameFactory(cfg.GameFactoryAddress, l1Client)
factoryContract, err := bindings.NewDisputeGameFactory(cfg.GameFactoryAddress, l1Client)
if err != nil {
return nil, errors.Join(fmt.Errorf("failed to bind the fault dispute game factory contract: %w", err), s.Stop(ctx))
}
loader := NewGameLoader(factory)
loader := loader.NewGameLoader(factoryContract)
disk := newDiskManager(cfg.Datadir)
s.sched = scheduler.NewScheduler(
......@@ -99,8 +100,8 @@ func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*Se
m,
disk,
cfg.MaxConcurrency,
func(addr common.Address, dir string) (scheduler.GamePlayer, error) {
return fault.NewGamePlayer(ctx, logger, m, cfg, dir, addr, txMgr, l1Client)
func(game types.GameData, dir string) (scheduler.GamePlayer, error) {
return fault.NewGamePlayer(ctx, logger, m, cfg, dir, game.Proxy, txMgr, l1Client)
})
pollClient, err := opClient.NewRPCWithClient(ctx, logger, cfg.L1EthRpc, opClient.NewBaseRPCClient(l1Client.Client()), cfg.PollInterval)
......
......@@ -2,6 +2,8 @@ package types
import (
"fmt"
"github.com/ethereum/go-ethereum/common"
)
type GameStatus uint8
......@@ -33,3 +35,9 @@ func GameStatusFromUint8(i uint8) (GameStatus, error) {
}
return GameStatus(i), nil
}
type GameData struct {
GameType uint8
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