Commit 33d0e509 authored by OptimismBot's avatar OptimismBot Committed by GitHub

Merge pull request #7003 from ethereum-optimism/refcell/delete-caller

fix(op-challenger): Combine Fault Caller and Loader Components
parents aac273a9 5669b83f
...@@ -19,9 +19,13 @@ type Responder interface { ...@@ -19,9 +19,13 @@ type Responder interface {
Step(ctx context.Context, stepData types.StepCallData) error Step(ctx context.Context, stepData types.StepCallData) error
} }
type ClaimLoader interface {
FetchClaims(ctx context.Context) ([]types.Claim, error)
}
type Agent struct { type Agent struct {
solver *solver.Solver solver *solver.Solver
loader Loader loader ClaimLoader
responder Responder responder Responder
updater types.OracleUpdater updater types.OracleUpdater
maxDepth int maxDepth int
...@@ -29,7 +33,7 @@ type Agent struct { ...@@ -29,7 +33,7 @@ type Agent struct {
log log.Logger log log.Logger
} }
func NewAgent(loader Loader, maxDepth int, trace types.TraceProvider, responder Responder, updater types.OracleUpdater, agreeWithProposedOutput bool, log log.Logger) *Agent { func NewAgent(loader ClaimLoader, maxDepth int, trace types.TraceProvider, responder Responder, updater types.OracleUpdater, agreeWithProposedOutput bool, log log.Logger) *Agent {
return &Agent{ return &Agent{
solver: solver.NewSolver(maxDepth, trace), solver: solver.NewSolver(maxDepth, trace),
loader: loader, loader: loader,
......
package fault
import (
"context"
"math/big"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-challenger/fault/types"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
)
type FaultDisputeGameCaller interface {
Status(opts *bind.CallOpts) (uint8, error)
ClaimDataLen(opts *bind.CallOpts) (*big.Int, error)
}
type FaultCaller struct {
contract FaultDisputeGameCaller
}
func NewFaultCaller(caller FaultDisputeGameCaller) *FaultCaller {
return &FaultCaller{
caller,
}
}
func NewFaultCallerFromBindings(fdgAddr common.Address, client bind.ContractCaller) (*FaultCaller, error) {
caller, err := bindings.NewFaultDisputeGameCaller(fdgAddr, client)
if err != nil {
return nil, err
}
return &FaultCaller{
caller,
}, nil
}
// GetGameStatus returns the current game status.
// 0: In Progress
// 1: Challenger Won
// 2: Defender Won
func (fc *FaultCaller) GetGameStatus(ctx context.Context) (types.GameStatus, error) {
status, err := fc.contract.Status(&bind.CallOpts{Context: ctx})
return types.GameStatus(status), err
}
// GetClaimCount returns the number of claims in the game.
func (fc *FaultCaller) GetClaimCount(ctx context.Context) (uint64, error) {
count, err := fc.contract.ClaimDataLen(&bind.CallOpts{Context: ctx})
if err != nil {
return 0, err
}
return count.Uint64(), nil
}
package fault
import (
"context"
"errors"
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/fault/types"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/stretchr/testify/require"
)
var (
errMock = errors.New("mock error")
)
type mockFaultDisputeGameCaller struct {
status uint8
errStatus bool
claimDataLen *big.Int
errClaimDataLen bool
}
func (m *mockFaultDisputeGameCaller) Status(opts *bind.CallOpts) (uint8, error) {
if m.errStatus {
return 0, errMock
}
return m.status, nil
}
func (m *mockFaultDisputeGameCaller) ClaimDataLen(opts *bind.CallOpts) (*big.Int, error) {
if m.errClaimDataLen {
return nil, errMock
}
return m.claimDataLen, nil
}
func TestFaultCaller_GetGameStatus(t *testing.T) {
tests := []struct {
name string
caller FaultDisputeGameCaller
expectedStatus types.GameStatus
expectedErr error
}{
{
name: "success",
caller: &mockFaultDisputeGameCaller{
status: 1,
},
expectedStatus: types.GameStatusChallengerWon,
expectedErr: nil,
},
{
name: "error",
caller: &mockFaultDisputeGameCaller{
errStatus: true,
},
expectedStatus: 0,
expectedErr: errMock,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
fc := NewFaultCaller(test.caller)
status, err := fc.GetGameStatus(context.Background())
require.Equal(t, test.expectedStatus, status)
require.Equal(t, test.expectedErr, err)
})
}
}
func TestFaultCaller_GetClaimCount(t *testing.T) {
tests := []struct {
name string
caller FaultDisputeGameCaller
expectedClaimDataLen uint64
expectedErr error
}{
{
name: "success",
caller: &mockFaultDisputeGameCaller{
claimDataLen: big.NewInt(1),
},
expectedClaimDataLen: 1,
expectedErr: nil,
},
{
name: "error",
caller: &mockFaultDisputeGameCaller{
errClaimDataLen: true,
},
expectedClaimDataLen: 0,
expectedErr: errMock,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
fc := NewFaultCaller(test.caller)
claimDataLen, err := fc.GetClaimCount(context.Background())
require.Equal(t, test.expectedClaimDataLen, claimDataLen)
require.Equal(t, test.expectedErr, err)
})
}
}
...@@ -6,10 +6,10 @@ import ( ...@@ -6,10 +6,10 @@ import (
"math/big" "math/big"
"testing" "testing"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum-optimism/optimism/op-challenger/fault/types"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
...@@ -144,6 +144,9 @@ func newMockMinimalDisputeGameFactoryCaller(count uint64, gameCountErr bool, ind ...@@ -144,6 +144,9 @@ func newMockMinimalDisputeGameFactoryCaller(count uint64, gameCountErr bool, ind
games: generateMockGames(count), games: generateMockGames(count),
} }
} }
func (m *mockMinimalDisputeGameFactoryCaller) Status(opts *bind.CallOpts) (uint8, error) {
return uint8(types.GameStatusInProgress), nil
}
func (m *mockMinimalDisputeGameFactoryCaller) GameCount(opts *bind.CallOpts) (*big.Int, error) { func (m *mockMinimalDisputeGameFactoryCaller) GameCount(opts *bind.CallOpts) (*big.Int, error) {
if m.gameCountErr { if m.gameCountErr {
......
...@@ -4,8 +4,11 @@ import ( ...@@ -4,8 +4,11 @@ import (
"context" "context"
"math/big" "math/big"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-challenger/fault/types" "github.com/ethereum-optimism/optimism/op-challenger/fault/types"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
) )
// MinimalFaultDisputeGameCaller is a minimal interface around [bindings.FaultDisputeGameCaller]. // MinimalFaultDisputeGameCaller is a minimal interface around [bindings.FaultDisputeGameCaller].
...@@ -18,18 +21,12 @@ type MinimalFaultDisputeGameCaller interface { ...@@ -18,18 +21,12 @@ type MinimalFaultDisputeGameCaller interface {
Position *big.Int Position *big.Int
Clock *big.Int Clock *big.Int
}, error) }, error)
Status(opts *bind.CallOpts) (uint8, error)
ClaimDataLen(opts *bind.CallOpts) (*big.Int, error) ClaimDataLen(opts *bind.CallOpts) (*big.Int, error)
MAXGAMEDEPTH(opts *bind.CallOpts) (*big.Int, error) MAXGAMEDEPTH(opts *bind.CallOpts) (*big.Int, error)
ABSOLUTEPRESTATE(opts *bind.CallOpts) ([32]byte, error) ABSOLUTEPRESTATE(opts *bind.CallOpts) ([32]byte, error)
} }
// Loader is a minimal interface for loading onchain [Claim] data.
type Loader interface {
FetchClaims(ctx context.Context) ([]types.Claim, error)
FetchGameDepth(ctx context.Context) (uint64, error)
FetchAbsolutePrestateHash(ctx context.Context) ([]byte, error)
}
// loader pulls in fault dispute game claim data periodically and over subscriptions. // loader pulls in fault dispute game claim data periodically and over subscriptions.
type loader struct { type loader struct {
caller MinimalFaultDisputeGameCaller caller MinimalFaultDisputeGameCaller
...@@ -42,6 +39,30 @@ func NewLoader(caller MinimalFaultDisputeGameCaller) *loader { ...@@ -42,6 +39,30 @@ func NewLoader(caller MinimalFaultDisputeGameCaller) *loader {
} }
} }
// NewLoaderFromBindings creates a new [loader] from a [bindings.FaultDisputeGameCaller].
func NewLoaderFromBindings(fdgAddr common.Address, client bind.ContractCaller) (*loader, error) {
caller, err := bindings.NewFaultDisputeGameCaller(fdgAddr, client)
if err != nil {
return nil, err
}
return NewLoader(caller), nil
}
// GetGameStatus returns the current game status.
func (l *loader) GetGameStatus(ctx context.Context) (types.GameStatus, error) {
status, err := l.caller.Status(&bind.CallOpts{Context: ctx})
return types.GameStatus(status), err
}
// GetClaimCount returns the number of claims in the game.
func (l *loader) GetClaimCount(ctx context.Context) (uint64, error) {
count, err := l.caller.ClaimDataLen(&bind.CallOpts{Context: ctx})
if err != nil {
return 0, err
}
return count.Uint64(), nil
}
// FetchGameDepth fetches the game depth from the fault dispute game. // FetchGameDepth fetches the game depth from the fault dispute game.
func (l *loader) FetchGameDepth(ctx context.Context) (uint64, error) { func (l *loader) FetchGameDepth(ctx context.Context) (uint64, error) {
callOpts := bind.CallOpts{ callOpts := bind.CallOpts{
......
...@@ -18,15 +18,171 @@ var ( ...@@ -18,15 +18,171 @@ var (
mockClaimLenError = fmt.Errorf("claim len errored") mockClaimLenError = fmt.Errorf("claim len errored")
mockMaxGameDepthError = fmt.Errorf("max game depth errored") mockMaxGameDepthError = fmt.Errorf("max game depth errored")
mockPrestateError = fmt.Errorf("prestate errored") mockPrestateError = fmt.Errorf("prestate errored")
mockStatusError = fmt.Errorf("status errored")
) )
// TestLoader_GetGameStatus tests fetching the game status.
func TestLoader_GetGameStatus(t *testing.T) {
tests := []struct {
name string
status uint8
expectedError bool
}{
{
name: "challenger won status",
status: uint8(types.GameStatusChallengerWon),
},
{
name: "defender won status",
status: uint8(types.GameStatusDefenderWon),
},
{
name: "in progress status",
status: uint8(types.GameStatusInProgress),
},
{
name: "error bubbled up",
expectedError: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.status = test.status
mockCaller.statusError = test.expectedError
loader := NewLoader(mockCaller)
status, err := loader.GetGameStatus(context.Background())
if test.expectedError {
require.ErrorIs(t, err, mockStatusError)
} else {
require.NoError(t, err)
require.Equal(t, types.GameStatus(test.status), status)
}
})
}
}
// TestLoader_FetchGameDepth tests fetching the game depth.
func TestLoader_FetchGameDepth(t *testing.T) {
t.Run("Succeeds", func(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.maxGameDepth = 10
loader := NewLoader(mockCaller)
depth, err := loader.FetchGameDepth(context.Background())
require.NoError(t, err)
require.Equal(t, uint64(10), depth)
})
t.Run("Errors", func(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.maxGameDepthError = true
loader := NewLoader(mockCaller)
depth, err := loader.FetchGameDepth(context.Background())
require.ErrorIs(t, mockMaxGameDepthError, err)
require.Equal(t, depth, uint64(0))
})
}
// TestLoader_FetchAbsolutePrestateHash tests fetching the absolute prestate hash.
func TestLoader_FetchAbsolutePrestateHash(t *testing.T) {
t.Run("Succeeds", func(t *testing.T) {
mockCaller := newMockCaller()
loader := NewLoader(mockCaller)
prestate, err := loader.FetchAbsolutePrestateHash(context.Background())
require.NoError(t, err)
require.ElementsMatch(t, common.HexToHash("0xdEad"), prestate)
})
t.Run("Errors", func(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.prestateError = true
loader := NewLoader(mockCaller)
prestate, err := loader.FetchAbsolutePrestateHash(context.Background())
require.Error(t, err)
require.ElementsMatch(t, common.Hash{}, prestate)
})
}
// TestLoader_FetchClaims tests fetching claims.
func TestLoader_FetchClaims(t *testing.T) {
t.Run("Succeeds", func(t *testing.T) {
mockCaller := newMockCaller()
expectedClaims := mockCaller.returnClaims
loader := NewLoader(mockCaller)
claims, err := loader.FetchClaims(context.Background())
require.NoError(t, err)
require.ElementsMatch(t, []types.Claim{
{
ClaimData: types.ClaimData{
Value: expectedClaims[0].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[0].Position.Uint64()),
},
Parent: types.ClaimData{
Value: expectedClaims[0].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[0].Position.Uint64()),
},
Countered: false,
Clock: uint64(0),
ContractIndex: 0,
},
{
ClaimData: types.ClaimData{
Value: expectedClaims[1].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[1].Position.Uint64()),
},
Parent: types.ClaimData{
Value: expectedClaims[0].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[1].Position.Uint64()),
},
Countered: false,
Clock: uint64(0),
ContractIndex: 1,
},
{
ClaimData: types.ClaimData{
Value: expectedClaims[2].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[2].Position.Uint64()),
},
Parent: types.ClaimData{
Value: expectedClaims[0].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[2].Position.Uint64()),
},
Countered: false,
Clock: uint64(0),
ContractIndex: 2,
},
}, claims)
})
t.Run("Claim Data Errors", func(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.claimDataError = true
loader := NewLoader(mockCaller)
claims, err := loader.FetchClaims(context.Background())
require.ErrorIs(t, err, mockClaimDataError)
require.Empty(t, claims)
})
t.Run("Claim Len Errors", func(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.claimLenError = true
loader := NewLoader(mockCaller)
claims, err := loader.FetchClaims(context.Background())
require.ErrorIs(t, err, mockClaimLenError)
require.Empty(t, claims)
})
}
type mockCaller struct { type mockCaller struct {
claimDataError bool claimDataError bool
claimLenError bool claimLenError bool
maxGameDepthError bool maxGameDepthError bool
prestateError bool prestateError bool
statusError bool
maxGameDepth uint64 maxGameDepth uint64
currentIndex uint64 currentIndex uint64
status uint8
returnClaims []struct { returnClaims []struct {
ParentIndex uint32 ParentIndex uint32
Countered bool Countered bool
...@@ -88,6 +244,13 @@ func (m *mockCaller) ClaimData(opts *bind.CallOpts, arg0 *big.Int) (struct { ...@@ -88,6 +244,13 @@ func (m *mockCaller) ClaimData(opts *bind.CallOpts, arg0 *big.Int) (struct {
return returnClaim, nil return returnClaim, nil
} }
func (m *mockCaller) Status(opts *bind.CallOpts) (uint8, error) {
if m.statusError {
return 0, mockStatusError
}
return m.status, nil
}
func (m *mockCaller) ClaimDataLen(opts *bind.CallOpts) (*big.Int, error) { func (m *mockCaller) ClaimDataLen(opts *bind.CallOpts) (*big.Int, error) {
if m.claimLenError { if m.claimLenError {
return big.NewInt(0), mockClaimLenError return big.NewInt(0), mockClaimLenError
...@@ -108,116 +271,3 @@ func (m *mockCaller) ABSOLUTEPRESTATE(opts *bind.CallOpts) ([32]byte, error) { ...@@ -108,116 +271,3 @@ func (m *mockCaller) ABSOLUTEPRESTATE(opts *bind.CallOpts) ([32]byte, error) {
} }
return common.HexToHash("0xdEad"), nil return common.HexToHash("0xdEad"), nil
} }
// TestLoader_FetchGameDepth tests [loader.FetchGameDepth].
func TestLoader_FetchGameDepth(t *testing.T) {
t.Run("Succeeds", func(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.maxGameDepth = 10
loader := NewLoader(mockCaller)
depth, err := loader.FetchGameDepth(context.Background())
require.NoError(t, err)
require.Equal(t, uint64(10), depth)
})
t.Run("Errors", func(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.maxGameDepthError = true
loader := NewLoader(mockCaller)
depth, err := loader.FetchGameDepth(context.Background())
require.ErrorIs(t, mockMaxGameDepthError, err)
require.Equal(t, depth, uint64(0))
})
}
// TestLoader_FetchAbsolutePrestateHash tests the [loader.FetchAbsolutePrestateHash] function.
func TestLoader_FetchAbsolutePrestateHash(t *testing.T) {
t.Run("Succeeds", func(t *testing.T) {
mockCaller := newMockCaller()
loader := NewLoader(mockCaller)
prestate, err := loader.FetchAbsolutePrestateHash(context.Background())
require.NoError(t, err)
require.ElementsMatch(t, common.HexToHash("0xdEad"), prestate)
})
t.Run("Errors", func(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.prestateError = true
loader := NewLoader(mockCaller)
prestate, err := loader.FetchAbsolutePrestateHash(context.Background())
require.Error(t, err)
require.ElementsMatch(t, common.Hash{}, prestate)
})
}
// TestLoader_FetchClaims_Succeeds tests [loader.FetchClaims].
func TestLoader_FetchClaims_Succeeds(t *testing.T) {
mockCaller := newMockCaller()
expectedClaims := mockCaller.returnClaims
loader := NewLoader(mockCaller)
claims, err := loader.FetchClaims(context.Background())
require.NoError(t, err)
require.ElementsMatch(t, []types.Claim{
{
ClaimData: types.ClaimData{
Value: expectedClaims[0].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[0].Position.Uint64()),
},
Parent: types.ClaimData{
Value: expectedClaims[0].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[0].Position.Uint64()),
},
Countered: false,
Clock: uint64(0),
ContractIndex: 0,
},
{
ClaimData: types.ClaimData{
Value: expectedClaims[1].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[1].Position.Uint64()),
},
Parent: types.ClaimData{
Value: expectedClaims[0].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[1].Position.Uint64()),
},
Countered: false,
Clock: uint64(0),
ContractIndex: 1,
},
{
ClaimData: types.ClaimData{
Value: expectedClaims[2].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[2].Position.Uint64()),
},
Parent: types.ClaimData{
Value: expectedClaims[0].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[2].Position.Uint64()),
},
Countered: false,
Clock: uint64(0),
ContractIndex: 2,
},
}, claims)
}
// TestLoader_FetchClaims_ClaimDataErrors tests [loader.FetchClaims]
// when the claim fetcher [ClaimData] function call errors.
func TestLoader_FetchClaims_ClaimDataErrors(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.claimDataError = true
loader := NewLoader(mockCaller)
claims, err := loader.FetchClaims(context.Background())
require.ErrorIs(t, err, mockClaimDataError)
require.Empty(t, claims)
}
// TestLoader_FetchClaims_ClaimLenErrors tests [loader.FetchClaims]
// when the claim fetcher [ClaimDataLen] function call errors.
func TestLoader_FetchClaims_ClaimLenErrors(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.claimLenError = true
loader := NewLoader(mockCaller)
claims, err := loader.FetchClaims(context.Background())
require.ErrorIs(t, err, mockClaimLenError)
require.Empty(t, claims)
}
...@@ -27,7 +27,7 @@ type GameInfo interface { ...@@ -27,7 +27,7 @@ type GameInfo interface {
type GamePlayer struct { type GamePlayer struct {
agent Actor agent Actor
agreeWithProposedOutput bool agreeWithProposedOutput bool
caller GameInfo loader GameInfo
logger log.Logger logger log.Logger
completed bool completed bool
...@@ -84,15 +84,10 @@ func NewGamePlayer( ...@@ -84,15 +84,10 @@ func NewGamePlayer(
return nil, fmt.Errorf("failed to create the responder: %w", err) return nil, fmt.Errorf("failed to create the responder: %w", err)
} }
caller, err := NewFaultCallerFromBindings(addr, client)
if err != nil {
return nil, fmt.Errorf("failed to bind the fault contract: %w", err)
}
return &GamePlayer{ return &GamePlayer{
agent: NewAgent(loader, int(gameDepth), provider, responder, updater, cfg.AgreeWithProposedOutput, logger), agent: NewAgent(loader, int(gameDepth), provider, responder, updater, cfg.AgreeWithProposedOutput, logger),
agreeWithProposedOutput: cfg.AgreeWithProposedOutput, agreeWithProposedOutput: cfg.AgreeWithProposedOutput,
caller: caller, loader: loader,
logger: logger, logger: logger,
}, nil }, nil
} }
...@@ -107,7 +102,7 @@ func (g *GamePlayer) ProgressGame(ctx context.Context) bool { ...@@ -107,7 +102,7 @@ func (g *GamePlayer) ProgressGame(ctx context.Context) bool {
if err := g.agent.Act(ctx); err != nil { if err := g.agent.Act(ctx); err != nil {
g.logger.Error("Error when acting on game", "err", err) g.logger.Error("Error when acting on game", "err", err)
} }
if status, err := g.caller.GetGameStatus(ctx); err != nil { if status, err := g.loader.GetGameStatus(ctx); err != nil {
g.logger.Warn("Unable to retrieve game status", "err", err) g.logger.Warn("Unable to retrieve game status", "err", err)
} else { } else {
g.logGameStatus(ctx, status) g.logGameStatus(ctx, status)
...@@ -119,7 +114,7 @@ func (g *GamePlayer) ProgressGame(ctx context.Context) bool { ...@@ -119,7 +114,7 @@ func (g *GamePlayer) ProgressGame(ctx context.Context) bool {
func (g *GamePlayer) logGameStatus(ctx context.Context, status types.GameStatus) { func (g *GamePlayer) logGameStatus(ctx context.Context, status types.GameStatus) {
if status == types.GameStatusInProgress { if status == types.GameStatusInProgress {
claimCount, err := g.caller.GetClaimCount(ctx) claimCount, err := g.loader.GetClaimCount(ctx)
if err != nil { if err != nil {
g.logger.Error("Failed to get claim count for in progress game", "err", err) g.logger.Error("Failed to get claim count for in progress game", "err", err)
return return
......
...@@ -115,7 +115,7 @@ func setupProgressGameTest(t *testing.T, agreeWithProposedRoot bool) (*testlog.C ...@@ -115,7 +115,7 @@ func setupProgressGameTest(t *testing.T, agreeWithProposedRoot bool) (*testlog.C
game := &GamePlayer{ game := &GamePlayer{
agent: gameState, agent: gameState,
agreeWithProposedOutput: agreeWithProposedRoot, agreeWithProposedOutput: agreeWithProposedRoot,
caller: gameState, loader: gameState,
logger: logger, logger: logger,
} }
return handler, game, gameState return handler, game, gameState
......
...@@ -19,13 +19,16 @@ import ( ...@@ -19,13 +19,16 @@ import (
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
) )
// Service provides a clean interface for the challenger to interact // Service exposes top-level fault dispute game challenger functionality.
// with the fault package.
type Service interface { type Service interface {
// MonitorGame monitors the fault dispute game and attempts to progress it. // MonitorGame monitors the fault dispute game and attempts to progress it.
MonitorGame(context.Context) error MonitorGame(context.Context) error
} }
type Loader interface {
FetchAbsolutePrestateHash(ctx context.Context) ([]byte, error)
}
type service struct { type service struct {
logger log.Logger logger log.Logger
metrics metrics.Metricer metrics metrics.Metricer
......
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