Commit 5f1b1b21 authored by refcell's avatar refcell Committed by GitHub

feat(op-dispute-mon): wire in extractor (#9565)

parent bb4fe5d5
...@@ -2,7 +2,6 @@ package mon ...@@ -2,7 +2,6 @@ package mon
import ( import (
"context" "context"
"fmt"
"github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-dispute-mon/mon/extract" "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/extract"
...@@ -41,19 +40,12 @@ func newDetector(logger log.Logger, metrics DetectorMetrics, creator GameCallerC ...@@ -41,19 +40,12 @@ func newDetector(logger log.Logger, metrics DetectorMetrics, creator GameCallerC
} }
} }
func (d *detector) Detect(ctx context.Context, games []types.GameMetadata) { func (d *detector) Detect(ctx context.Context, games []monTypes.EnrichedGameData) {
statBatch := monTypes.StatusBatch{} statBatch := monTypes.StatusBatch{}
detectBatch := monTypes.DetectionBatch{} detectBatch := monTypes.DetectionBatch{}
for _, game := range games { for _, game := range games {
// Fetch the game metadata to ensure the game status is recorded statBatch.Add(game.Status)
// regardless of whether the game agreement is checked. processed, err := d.checkAgreement(ctx, game.Proxy, game.L2BlockNumber, game.RootClaim, game.Status)
l2BlockNum, rootClaim, status, err := d.fetchGameMetadata(ctx, game)
if err != nil {
d.logger.Error("Failed to fetch game metadata", "err", err)
continue
}
statBatch.Add(status)
processed, err := d.checkAgreement(ctx, game.Proxy, l2BlockNum, rootClaim, status)
if err != nil { if err != nil {
d.logger.Error("Failed to process game", "err", err) d.logger.Error("Failed to process game", "err", err)
continue continue
...@@ -73,18 +65,6 @@ func (d *detector) recordBatch(batch monTypes.DetectionBatch) { ...@@ -73,18 +65,6 @@ func (d *detector) recordBatch(batch monTypes.DetectionBatch) {
d.metrics.RecordGameAgreement("disagree_challenger_wins", batch.DisagreeChallengerWins) d.metrics.RecordGameAgreement("disagree_challenger_wins", batch.DisagreeChallengerWins)
} }
func (d *detector) fetchGameMetadata(ctx context.Context, game types.GameMetadata) (uint64, common.Hash, types.GameStatus, error) {
loader, err := d.creator.CreateContract(game)
if err != nil {
return 0, common.Hash{}, 0, fmt.Errorf("failed to create contract: %w", err)
}
blockNum, rootClaim, status, err := loader.GetGameMetadata(ctx)
if err != nil {
return 0, common.Hash{}, 0, fmt.Errorf("failed to fetch game metadata: %w", err)
}
return blockNum, rootClaim, status, nil
}
func (d *detector) checkAgreement(ctx context.Context, addr common.Address, blockNum uint64, rootClaim common.Hash, status types.GameStatus) (monTypes.DetectionBatch, error) { func (d *detector) checkAgreement(ctx context.Context, addr common.Address, blockNum uint64, rootClaim common.Hash, status types.GameStatus) (monTypes.DetectionBatch, error) {
agree, expectedClaim, err := d.validator.CheckRootAgreement(ctx, blockNum, rootClaim) agree, expectedClaim, err := d.validator.CheckRootAgreement(ctx, blockNum, rootClaim)
if err != nil { if err != nil {
......
...@@ -20,15 +20,7 @@ func TestDetector_Detect(t *testing.T) { ...@@ -20,15 +20,7 @@ func TestDetector_Detect(t *testing.T) {
t.Run("NoGames", func(t *testing.T) { t.Run("NoGames", func(t *testing.T) {
detector, metrics, _, _, _ := setupDetectorTest(t) detector, metrics, _, _, _ := setupDetectorTest(t)
detector.Detect(context.Background(), []types.GameMetadata{}) detector.Detect(context.Background(), []monTypes.EnrichedGameData{})
metrics.Equals(t, 0, 0, 0)
metrics.Mapped(t, map[string]int{})
})
t.Run("MetadataFetchFails", func(t *testing.T) {
detector, metrics, creator, _, _ := setupDetectorTest(t)
creator.err = errors.New("boom")
detector.Detect(context.Background(), []types.GameMetadata{{}})
metrics.Equals(t, 0, 0, 0) metrics.Equals(t, 0, 0, 0)
metrics.Mapped(t, map[string]int{}) metrics.Mapped(t, map[string]int{})
}) })
...@@ -38,7 +30,7 @@ func TestDetector_Detect(t *testing.T) { ...@@ -38,7 +30,7 @@ func TestDetector_Detect(t *testing.T) {
rollup.err = errors.New("boom") rollup.err = errors.New("boom")
creator.caller.status = []types.GameStatus{types.GameStatusInProgress} creator.caller.status = []types.GameStatus{types.GameStatusInProgress}
creator.caller.rootClaim = []common.Hash{{}} creator.caller.rootClaim = []common.Hash{{}}
detector.Detect(context.Background(), []types.GameMetadata{{}}) detector.Detect(context.Background(), []monTypes.EnrichedGameData{{}})
metrics.Equals(t, 1, 0, 0) // Status should still be metriced here! metrics.Equals(t, 1, 0, 0) // Status should still be metriced here!
metrics.Mapped(t, map[string]int{}) metrics.Mapped(t, map[string]int{})
}) })
...@@ -47,7 +39,7 @@ func TestDetector_Detect(t *testing.T) { ...@@ -47,7 +39,7 @@ func TestDetector_Detect(t *testing.T) {
detector, metrics, creator, _, _ := setupDetectorTest(t) detector, metrics, creator, _, _ := setupDetectorTest(t)
creator.caller.status = []types.GameStatus{types.GameStatusInProgress} creator.caller.status = []types.GameStatus{types.GameStatusInProgress}
creator.caller.rootClaim = []common.Hash{{}} creator.caller.rootClaim = []common.Hash{{}}
detector.Detect(context.Background(), []types.GameMetadata{{}}) detector.Detect(context.Background(), []monTypes.EnrichedGameData{{}})
metrics.Equals(t, 1, 0, 0) metrics.Equals(t, 1, 0, 0)
metrics.Mapped(t, map[string]int{"in_progress": 1}) metrics.Mapped(t, map[string]int{"in_progress": 1})
}) })
...@@ -60,7 +52,7 @@ func TestDetector_Detect(t *testing.T) { ...@@ -60,7 +52,7 @@ func TestDetector_Detect(t *testing.T) {
types.GameStatusInProgress, types.GameStatusInProgress,
} }
creator.caller.rootClaim = []common.Hash{{}, {}, {}} creator.caller.rootClaim = []common.Hash{{}, {}, {}}
detector.Detect(context.Background(), []types.GameMetadata{{}, {}, {}}) detector.Detect(context.Background(), []monTypes.EnrichedGameData{{}, {}, {}})
metrics.Equals(t, 3, 0, 0) metrics.Equals(t, 3, 0, 0)
metrics.Mapped(t, map[string]int{"in_progress": 3}) metrics.Mapped(t, map[string]int{"in_progress": 3})
}) })
...@@ -124,35 +116,6 @@ func TestDetector_RecordBatch(t *testing.T) { ...@@ -124,35 +116,6 @@ func TestDetector_RecordBatch(t *testing.T) {
} }
} }
func TestDetector_FetchGameMetadata(t *testing.T) {
t.Parallel()
t.Run("CreateContractFails", func(t *testing.T) {
detector, _, creator, _, _ := setupDetectorTest(t)
creator.err = errors.New("boom")
_, _, _, err := detector.fetchGameMetadata(context.Background(), types.GameMetadata{})
require.ErrorIs(t, err, creator.err)
})
t.Run("GetGameMetadataFails", func(t *testing.T) {
detector, _, creator, _, _ := setupDetectorTest(t)
creator.caller = &mockGameCaller{err: errors.New("boom")}
creator.caller.status = []types.GameStatus{types.GameStatusInProgress}
creator.caller.rootClaim = []common.Hash{{}}
_, _, _, err := detector.fetchGameMetadata(context.Background(), types.GameMetadata{})
require.Error(t, err)
})
t.Run("Success", func(t *testing.T) {
detector, _, creator, _, _ := setupDetectorTest(t)
creator.caller.status = []types.GameStatus{types.GameStatusInProgress}
creator.caller.rootClaim = []common.Hash{{}}
_, _, status, err := detector.fetchGameMetadata(context.Background(), types.GameMetadata{})
require.NoError(t, err)
require.Equal(t, types.GameStatusInProgress, status)
})
}
func TestDetector_CheckAgreement_Fails(t *testing.T) { func TestDetector_CheckAgreement_Fails(t *testing.T) {
detector, _, _, rollup, _ := setupDetectorTest(t) detector, _, _, rollup, _ := setupDetectorTest(t)
rollup.err = errors.New("boom") rollup.err = errors.New("boom")
......
...@@ -39,7 +39,7 @@ func newForecast(logger log.Logger, metrics ForecastMetrics, creator GameCallerC ...@@ -39,7 +39,7 @@ func newForecast(logger log.Logger, metrics ForecastMetrics, creator GameCallerC
} }
} }
func (f *forecast) Forecast(ctx context.Context, games []types.GameMetadata) { func (f *forecast) Forecast(ctx context.Context, games []monTypes.EnrichedGameData) {
batch := monTypes.ForecastBatch{} batch := monTypes.ForecastBatch{}
for _, game := range games { for _, game := range games {
if err := f.forecastGame(ctx, game, &batch); err != nil { if err := f.forecastGame(ctx, game, &batch); err != nil {
...@@ -56,20 +56,15 @@ func (f *forecast) recordBatch(batch monTypes.ForecastBatch) { ...@@ -56,20 +56,15 @@ func (f *forecast) recordBatch(batch monTypes.ForecastBatch) {
f.metrics.RecordGameAgreement("disagree_defender_ahead", batch.DisagreeDefenderAhead) f.metrics.RecordGameAgreement("disagree_defender_ahead", batch.DisagreeDefenderAhead)
} }
func (f *forecast) forecastGame(ctx context.Context, game types.GameMetadata, metrics *monTypes.ForecastBatch) error { func (f *forecast) forecastGame(ctx context.Context, game monTypes.EnrichedGameData, metrics *monTypes.ForecastBatch) error {
loader, err := f.creator.CreateContract(game) if game.Status != types.GameStatusInProgress {
if err != nil { f.logger.Debug("Game is not in progress, skipping forecast", "game", game.Proxy, "status", game.Status)
return fmt.Errorf("%w: %w", ErrContractCreation, err) return nil
} }
// Get the game status, it must be in progress to forecast. loader, err := f.creator.CreateContract(game.GameMetadata)
l2BlockNum, rootClaim, status, err := loader.GetGameMetadata(ctx)
if err != nil { if err != nil {
return fmt.Errorf("%w: %w", ErrMetadataFetch, err) return fmt.Errorf("%w: %w", ErrContractCreation, err)
}
if status != types.GameStatusInProgress {
f.logger.Debug("Game is not in progress, skipping forecast", "game", game, "status", status)
return nil
} }
// Load all claims for the game. // Load all claims for the game.
...@@ -82,10 +77,10 @@ func (f *forecast) forecastGame(ctx context.Context, game types.GameMetadata, me ...@@ -82,10 +77,10 @@ func (f *forecast) forecastGame(ctx context.Context, game types.GameMetadata, me
tree := transform.CreateBidirectionalTree(claims) tree := transform.CreateBidirectionalTree(claims)
// Compute the resolution status of the game. // Compute the resolution status of the game.
status = Resolve(tree) status := Resolve(tree)
// Check the root agreement. // Check the root agreement.
agreement, expected, err := f.validator.CheckRootAgreement(ctx, l2BlockNum, rootClaim) agreement, expected, err := f.validator.CheckRootAgreement(ctx, game.L2BlockNumber, game.RootClaim)
if err != nil { if err != nil {
return fmt.Errorf("%w: %w", ErrRootAgreement, err) return fmt.Errorf("%w: %w", ErrRootAgreement, err)
} }
...@@ -94,19 +89,19 @@ func (f *forecast) forecastGame(ctx context.Context, game types.GameMetadata, me ...@@ -94,19 +89,19 @@ func (f *forecast) forecastGame(ctx context.Context, game types.GameMetadata, me
// If we agree with the output root proposal, the Defender should win, defending that claim. // If we agree with the output root proposal, the Defender should win, defending that claim.
if status == types.GameStatusChallengerWon { if status == types.GameStatusChallengerWon {
metrics.AgreeChallengerAhead++ metrics.AgreeChallengerAhead++
f.logger.Warn("Forecasting unexpected game result", "status", status, "game", game, "rootClaim", rootClaim, "expected", expected) f.logger.Warn("Forecasting unexpected game result", "status", status, "game", game.Proxy, "rootClaim", game.RootClaim, "expected", expected)
} else { } else {
metrics.AgreeDefenderAhead++ metrics.AgreeDefenderAhead++
f.logger.Debug("Forecasting expected game result", "status", status, "game", game, "rootClaim", rootClaim, "expected", expected) f.logger.Debug("Forecasting expected game result", "status", status, "game", game.Proxy, "rootClaim", game.RootClaim, "expected", expected)
} }
} else { } else {
// If we disagree with the output root proposal, the Challenger should win, challenging that claim. // If we disagree with the output root proposal, the Challenger should win, challenging that claim.
if status == types.GameStatusDefenderWon { if status == types.GameStatusDefenderWon {
metrics.DisagreeDefenderAhead++ metrics.DisagreeDefenderAhead++
f.logger.Warn("Forecasting unexpected game result", "status", status, "game", game, "rootClaim", rootClaim, "expected", expected) f.logger.Warn("Forecasting unexpected game result", "status", status, "game", game.Proxy, "rootClaim", game.RootClaim, "expected", expected)
} else { } else {
metrics.DisagreeChallengerAhead++ metrics.DisagreeChallengerAhead++
f.logger.Debug("Forecasting expected game result", "status", status, "game", game, "rootClaim", rootClaim, "expected", expected) f.logger.Debug("Forecasting expected game result", "status", status, "game", game.Proxy, "rootClaim", game.RootClaim, "expected", expected)
} }
} }
......
This diff is collapsed.
...@@ -6,18 +6,18 @@ import ( ...@@ -6,18 +6,18 @@ import (
"math/big" "math/big"
"time" "time"
"github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types"
"github.com/ethereum-optimism/optimism/op-service/clock" "github.com/ethereum-optimism/optimism/op-service/clock"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
) )
type Detect func(ctx context.Context, games []types.GameMetadata) type Detect func(ctx context.Context, games []types.EnrichedGameData)
type Forecast func(ctx context.Context, games []types.GameMetadata) type Forecast func(ctx context.Context, games []types.EnrichedGameData)
type BlockHashFetcher func(ctx context.Context, number *big.Int) (common.Hash, error) type BlockHashFetcher func(ctx context.Context, number *big.Int) (common.Hash, error)
type BlockNumberFetcher func(ctx context.Context) (uint64, error) type BlockNumberFetcher func(ctx context.Context) (uint64, error)
type FactoryGameFetcher func(ctx context.Context, blockHash common.Hash, earliestTimestamp uint64) ([]types.GameMetadata, error) type Extract func(ctx context.Context, blockHash common.Hash, minTimestamp uint64) ([]types.EnrichedGameData, error)
type gameMonitor struct { type gameMonitor struct {
logger log.Logger logger log.Logger
...@@ -32,7 +32,7 @@ type gameMonitor struct { ...@@ -32,7 +32,7 @@ type gameMonitor struct {
detect Detect detect Detect
forecast Forecast forecast Forecast
fetchGames FactoryGameFetcher extract Extract
fetchBlockHash BlockHashFetcher fetchBlockHash BlockHashFetcher
fetchBlockNumber BlockNumberFetcher fetchBlockNumber BlockNumberFetcher
} }
...@@ -45,7 +45,7 @@ func newGameMonitor( ...@@ -45,7 +45,7 @@ func newGameMonitor(
gameWindow time.Duration, gameWindow time.Duration,
detect Detect, detect Detect,
forecast Forecast, forecast Forecast,
factory FactoryGameFetcher, extract Extract,
fetchBlockNumber BlockNumberFetcher, fetchBlockNumber BlockNumberFetcher,
fetchBlockHash BlockHashFetcher, fetchBlockHash BlockHashFetcher,
) *gameMonitor { ) *gameMonitor {
...@@ -58,7 +58,7 @@ func newGameMonitor( ...@@ -58,7 +58,7 @@ func newGameMonitor(
gameWindow: gameWindow, gameWindow: gameWindow,
detect: detect, detect: detect,
forecast: forecast, forecast: forecast,
fetchGames: factory, extract: extract,
fetchBlockNumber: fetchBlockNumber, fetchBlockNumber: fetchBlockNumber,
fetchBlockHash: fetchBlockHash, fetchBlockHash: fetchBlockHash,
} }
...@@ -86,12 +86,12 @@ func (m *gameMonitor) monitorGames() error { ...@@ -86,12 +86,12 @@ func (m *gameMonitor) monitorGames() error {
if err != nil { if err != nil {
return fmt.Errorf("Failed to fetch block hash: %w", err) return fmt.Errorf("Failed to fetch block hash: %w", err)
} }
games, err := m.fetchGames(m.ctx, blockHash, m.minGameTimestamp()) enrichedGames, err := m.extract(m.ctx, blockHash, m.minGameTimestamp())
if err != nil { if err != nil {
return fmt.Errorf("failed to load games: %w", err) return fmt.Errorf("failed to load games: %w", err)
} }
m.detect(m.ctx, games) m.detect(m.ctx, enrichedGames)
m.forecast(m.ctx, games) m.forecast(m.ctx, enrichedGames)
return nil return nil
} }
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"time" "time"
"github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/game/types"
monTypes "github.com/ethereum-optimism/optimism/op-dispute-mon/mon/types"
"github.com/ethereum-optimism/optimism/op-service/clock" "github.com/ethereum-optimism/optimism/op-service/clock"
"github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
...@@ -70,7 +71,7 @@ func TestMonitor_MonitorGames(t *testing.T) { ...@@ -70,7 +71,7 @@ func TestMonitor_MonitorGames(t *testing.T) {
t.Run("DetectsWithNoGames", func(t *testing.T) { t.Run("DetectsWithNoGames", func(t *testing.T) {
monitor, factory, detector, _ := setupMonitorTest(t) monitor, factory, detector, _ := setupMonitorTest(t)
factory.games = []types.GameMetadata{} factory.games = []monTypes.EnrichedGameData{}
err := monitor.monitorGames() err := monitor.monitorGames()
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 1, detector.calls) require.Equal(t, 1, detector.calls)
...@@ -78,7 +79,7 @@ func TestMonitor_MonitorGames(t *testing.T) { ...@@ -78,7 +79,7 @@ func TestMonitor_MonitorGames(t *testing.T) {
t.Run("DetectsMultipleGames", func(t *testing.T) { t.Run("DetectsMultipleGames", func(t *testing.T) {
monitor, factory, detector, _ := setupMonitorTest(t) monitor, factory, detector, _ := setupMonitorTest(t)
factory.games = []types.GameMetadata{{}, {}, {}} factory.games = []monTypes.EnrichedGameData{{}, {}, {}}
err := monitor.monitorGames() err := monitor.monitorGames()
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 1, detector.calls) require.Equal(t, 1, detector.calls)
...@@ -90,7 +91,7 @@ func TestMonitor_StartMonitoring(t *testing.T) { ...@@ -90,7 +91,7 @@ func TestMonitor_StartMonitoring(t *testing.T) {
addr1 := common.Address{0xaa} addr1 := common.Address{0xaa}
addr2 := common.Address{0xbb} addr2 := common.Address{0xbb}
monitor, factory, detector, _ := setupMonitorTest(t) monitor, factory, detector, _ := setupMonitorTest(t)
factory.games = []types.GameMetadata{newFDG(addr1, 9999), newFDG(addr2, 9999)} factory.games = []monTypes.EnrichedGameData{newFDG(addr1, 9999), newFDG(addr2, 9999)}
factory.maxSuccess = len(factory.games) // Only allow two successful fetches factory.maxSuccess = len(factory.games) // Only allow two successful fetches
monitor.StartMonitoring() monitor.StartMonitoring()
...@@ -114,14 +115,17 @@ func TestMonitor_StartMonitoring(t *testing.T) { ...@@ -114,14 +115,17 @@ func TestMonitor_StartMonitoring(t *testing.T) {
}) })
} }
func newFDG(proxy common.Address, timestamp uint64) types.GameMetadata { func newFDG(proxy common.Address, timestamp uint64) monTypes.EnrichedGameData {
return types.GameMetadata{ return monTypes.EnrichedGameData{
Proxy: proxy, GameMetadata: types.GameMetadata{
Timestamp: timestamp, Proxy: proxy,
Timestamp: timestamp,
},
Status: types.GameStatusInProgress,
} }
} }
func setupMonitorTest(t *testing.T) (*gameMonitor, *mockFactory, *mockDetector, *mockForecast) { func setupMonitorTest(t *testing.T) (*gameMonitor, *mockExtractor, *mockDetector, *mockForecast) {
logger := testlog.Logger(t, log.LvlDebug) logger := testlog.Logger(t, log.LvlDebug)
fetchBlockNum := func(ctx context.Context) (uint64, error) { fetchBlockNum := func(ctx context.Context) (uint64, error) {
return 1, nil return 1, nil
...@@ -132,7 +136,7 @@ func setupMonitorTest(t *testing.T) (*gameMonitor, *mockFactory, *mockDetector, ...@@ -132,7 +136,7 @@ func setupMonitorTest(t *testing.T) (*gameMonitor, *mockFactory, *mockDetector,
monitorInterval := time.Duration(100 * time.Millisecond) monitorInterval := time.Duration(100 * time.Millisecond)
cl := clock.NewAdvancingClock(10 * time.Millisecond) cl := clock.NewAdvancingClock(10 * time.Millisecond)
cl.Start() cl.Start()
factory := &mockFactory{} extractor := &mockExtractor{}
detect := &mockDetector{} detect := &mockDetector{}
forecast := &mockForecast{} forecast := &mockForecast{}
monitor := newGameMonitor( monitor := newGameMonitor(
...@@ -143,18 +147,18 @@ func setupMonitorTest(t *testing.T) (*gameMonitor, *mockFactory, *mockDetector, ...@@ -143,18 +147,18 @@ func setupMonitorTest(t *testing.T) (*gameMonitor, *mockFactory, *mockDetector,
time.Duration(10*time.Second), time.Duration(10*time.Second),
detect.Detect, detect.Detect,
forecast.Forecast, forecast.Forecast,
factory.GetGamesAtOrAfter, extractor.Extract,
fetchBlockNum, fetchBlockNum,
fetchBlockHash, fetchBlockHash,
) )
return monitor, factory, detect, forecast return monitor, extractor, detect, forecast
} }
type mockForecast struct { type mockForecast struct {
calls int calls int
} }
func (m *mockForecast) Forecast(ctx context.Context, games []types.GameMetadata) { func (m *mockForecast) Forecast(ctx context.Context, games []monTypes.EnrichedGameData) {
m.calls++ m.calls++
} }
...@@ -162,22 +166,22 @@ type mockDetector struct { ...@@ -162,22 +166,22 @@ type mockDetector struct {
calls int calls int
} }
func (m *mockDetector) Detect(ctx context.Context, games []types.GameMetadata) { func (m *mockDetector) Detect(ctx context.Context, games []monTypes.EnrichedGameData) {
m.calls++ m.calls++
} }
type mockFactory struct { type mockExtractor struct {
fetchErr error fetchErr error
calls int calls int
maxSuccess int maxSuccess int
games []types.GameMetadata games []monTypes.EnrichedGameData
} }
func (m *mockFactory) GetGamesAtOrAfter( func (m *mockExtractor) Extract(
_ context.Context, _ context.Context,
_ common.Hash, _ common.Hash,
_ uint64, _ uint64,
) ([]types.GameMetadata, error) { ) ([]monTypes.EnrichedGameData, error) {
m.calls++ m.calls++
if m.fetchErr != nil { if m.fetchErr != nil {
return nil, m.fetchErr return nil, m.fetchErr
......
...@@ -35,6 +35,7 @@ type Service struct { ...@@ -35,6 +35,7 @@ type Service struct {
cl clock.Clock cl clock.Clock
extractor *extract.Extractor
forecast *forecast forecast *forecast
game *extract.GameCallerCreator game *extract.GameCallerCreator
rollupClient *sources.RollupClient rollupClient *sources.RollupClient
...@@ -84,6 +85,8 @@ func (s *Service) initFromConfig(ctx context.Context, cfg *config.Config) error ...@@ -84,6 +85,8 @@ func (s *Service) initFromConfig(ctx context.Context, cfg *config.Config) error
s.initOutputValidator() // Must be called before initForecast s.initOutputValidator() // Must be called before initForecast
s.initGameCallerCreator() // Must be called before initForecast s.initGameCallerCreator() // Must be called before initForecast
s.initExtractor()
s.initForecast(cfg) s.initForecast(cfg)
s.initDetector() s.initDetector()
...@@ -103,6 +106,10 @@ func (s *Service) initGameCallerCreator() { ...@@ -103,6 +106,10 @@ func (s *Service) initGameCallerCreator() {
s.game = extract.NewGameCallerCreator(s.metrics, batching.NewMultiCaller(s.l1Client.Client(), batching.DefaultBatchSize)) s.game = extract.NewGameCallerCreator(s.metrics, batching.NewMultiCaller(s.l1Client.Client(), batching.DefaultBatchSize))
} }
func (s *Service) initExtractor() {
s.extractor = extract.NewExtractor(s.logger, s.game.CreateContract, s.factoryContract.GetGamesAtOrAfter)
}
func (s *Service) initForecast(cfg *config.Config) { func (s *Service) initForecast(cfg *config.Config) {
s.forecast = newForecast(s.logger, s.metrics, s.game, s.validator) s.forecast = newForecast(s.logger, s.metrics, s.game, s.validator)
} }
...@@ -190,7 +197,7 @@ func (s *Service) initMonitor(ctx context.Context, cfg *config.Config) { ...@@ -190,7 +197,7 @@ func (s *Service) initMonitor(ctx context.Context, cfg *config.Config) {
cfg.GameWindow, cfg.GameWindow,
s.detector.Detect, s.detector.Detect,
s.forecast.Forecast, s.forecast.Forecast,
s.factoryContract.GetGamesAtOrAfter, s.extractor.Extract,
s.l1Client.BlockNumber, s.l1Client.BlockNumber,
blockHashFetcher, blockHashFetcher,
) )
......
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