Commit ffd953a1 authored by Michael Lynch's avatar Michael Lynch Committed by GitHub

refactor(challenger): Define a type for Depth values (#8807)

* wip: Create a type for position depth

* work in progress

* work in progress

* Rename PositionDepth to Depth

* Document Depth type

* Fix unit test

* Fix e2e tests

* Fix more e2e tests

* Fix GetMaxGameDepth function signature

* Fix imports

* Fix unit tests
parent bbf627a1
......@@ -33,11 +33,11 @@ type Agent struct {
solver *solver.GameSolver
loader ClaimLoader
responder Responder
maxDepth int
maxDepth types.Depth
log log.Logger
}
func NewAgent(m metrics.Metricer, loader ClaimLoader, maxDepth int, trace types.TraceAccessor, responder Responder, log log.Logger) *Agent {
func NewAgent(m metrics.Metricer, loader ClaimLoader, maxDepth types.Depth, trace types.TraceAccessor, responder Responder, log log.Logger) *Agent {
return &Agent{
metrics: m,
solver: solver.NewGameSolver(maxDepth, trace),
......@@ -169,6 +169,6 @@ func (a *Agent) newGameFromContracts(ctx context.Context) (types.Game, error) {
if len(claims) == 0 {
return nil, errors.New("no claims")
}
game := types.NewGameState(claims, uint64(a.maxDepth))
game := types.NewGameState(claims, a.maxDepth)
return game, nil
}
......@@ -56,8 +56,8 @@ func TestLoadClaimsWhenGameNotResolvable(t *testing.T) {
agent, claimLoader, responder := setupTestAgent(t)
responder.callResolveErr = errors.New("game is not resolvable")
responder.callResolveClaimErr = errors.New("claim is not resolvable")
depth := 4
claimBuilder := test.NewClaimBuilder(t, depth, alphabet.NewTraceProvider("abcdefg", uint64(depth)))
depth := types.Depth(4)
claimBuilder := test.NewClaimBuilder(t, depth, alphabet.NewTraceProvider("abcdefg", depth))
claimLoader.claims = []types.Claim{
claimBuilder.CreateRootClaim(true),
......@@ -73,8 +73,8 @@ func TestLoadClaimsWhenGameNotResolvable(t *testing.T) {
func setupTestAgent(t *testing.T) (*Agent, *stubClaimLoader, *stubResponder) {
logger := testlog.Logger(t, log.LvlInfo)
claimLoader := &stubClaimLoader{}
depth := 4
provider := alphabet.NewTraceProvider("abcd", uint64(depth))
depth := types.Depth(4)
provider := alphabet.NewTraceProvider("abcd", depth)
responder := &stubResponder{}
agent := NewAgent(metrics.NoopMetrics, claimLoader, depth, trace.NewSimpleTraceAccessor(provider), responder, logger)
return agent, claimLoader, responder
......
......@@ -83,12 +83,12 @@ func (c *FaultDisputeGameContract) GetGenesisOutputRoot(ctx context.Context) (co
return genesisOutputRoot.GetHash(0), nil
}
func (c *FaultDisputeGameContract) GetSplitDepth(ctx context.Context) (uint64, error) {
func (c *FaultDisputeGameContract) GetSplitDepth(ctx context.Context) (types.Depth, error) {
splitDepth, err := c.multiCaller.SingleCall(ctx, batching.BlockLatest, c.contract.Call(methodSplitDepth))
if err != nil {
return 0, fmt.Errorf("failed to retrieve split depth: %w", err)
}
return splitDepth.GetBigInt(0).Uint64(), nil
return types.Depth(splitDepth.GetBigInt(0).Uint64()), nil
}
func (f *FaultDisputeGameContract) UpdateOracleTx(ctx context.Context, claimIdx uint64, data *types.PreimageOracleData) (txmgr.TxCandidate, error) {
......@@ -127,12 +127,12 @@ func (f *FaultDisputeGameContract) GetGameDuration(ctx context.Context) (uint64,
return result.GetUint64(0), nil
}
func (f *FaultDisputeGameContract) GetMaxGameDepth(ctx context.Context) (uint64, error) {
func (f *FaultDisputeGameContract) GetMaxGameDepth(ctx context.Context) (types.Depth, error) {
result, err := f.multiCaller.SingleCall(ctx, batching.BlockLatest, f.contract.Call(methodMaxGameDepth))
if err != nil {
return 0, fmt.Errorf("failed to fetch max game depth: %w", err)
}
return result.GetBigInt(0).Uint64(), nil
return types.Depth(result.GetBigInt(0).Uint64()), nil
}
func (f *FaultDisputeGameContract) GetAbsolutePrestateHash(ctx context.Context) (common.Hash, error) {
......
......@@ -50,7 +50,7 @@ func TestSimpleGetters(t *testing.T) {
methodAlias: "maxGameDepth",
method: methodMaxGameDepth,
result: big.NewInt(128),
expected: uint64(128),
expected: faultTypes.Depth(128),
call: func(game *FaultDisputeGameContract) (any, error) {
return game.GetMaxGameDepth(context.Background())
},
......@@ -250,8 +250,8 @@ func TestGetBlockRange(t *testing.T) {
func TestGetSplitDepth(t *testing.T) {
stubRpc, contract := setupFaultDisputeGameTest(t)
expectedSplitDepth := uint64(15)
stubRpc.SetResponse(fdgAddr, methodSplitDepth, batching.BlockLatest, nil, []interface{}{new(big.Int).SetUint64(expectedSplitDepth)})
expectedSplitDepth := faultTypes.Depth(15)
stubRpc.SetResponse(fdgAddr, methodSplitDepth, batching.BlockLatest, nil, []interface{}{new(big.Int).SetUint64(uint64(expectedSplitDepth))})
splitDepth, err := contract.GetSplitDepth(context.Background())
require.NoError(t, err)
require.Equal(t, expectedSplitDepth, splitDepth)
......
......@@ -33,10 +33,10 @@ type GameContract interface {
GameInfo
ClaimLoader
GetStatus(ctx context.Context) (gameTypes.GameStatus, error)
GetMaxGameDepth(ctx context.Context) (uint64, error)
GetMaxGameDepth(ctx context.Context) (types.Depth, error)
}
type resourceCreator func(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (types.TraceAccessor, error)
type resourceCreator func(ctx context.Context, logger log.Logger, gameDepth types.Depth, dir string) (types.TraceAccessor, error)
func NewGamePlayer(
ctx context.Context,
......@@ -85,7 +85,7 @@ func NewGamePlayer(
return nil, fmt.Errorf("failed to create the responder: %w", err)
}
agent := NewAgent(m, loader, int(gameDepth), accessor, responder, logger)
agent := NewAgent(m, loader, gameDepth, accessor, responder, logger)
return &GamePlayer{
act: agent.Act,
loader: loader,
......
......@@ -81,7 +81,7 @@ func registerAlphabet(
if err != nil {
return nil, err
}
creator := func(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (faultTypes.TraceAccessor, error) {
creator := func(ctx context.Context, logger log.Logger, gameDepth faultTypes.Depth, dir string) (faultTypes.TraceAccessor, error) {
accessor, err := outputs.NewOutputAlphabetTraceAccessor(logger, m, prestateProvider, rollupClient, splitDepth, prestateBlock, poststateBlock)
if err != nil {
return nil, err
......@@ -116,7 +116,7 @@ func registerCannon(
return nil, err
}
prestateProvider := outputs.NewPrestateProvider(ctx, logger, rollupClient, prestateBlock)
creator := func(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (faultTypes.TraceAccessor, error) {
creator := func(ctx context.Context, logger log.Logger, gameDepth faultTypes.Depth, dir string) (faultTypes.TraceAccessor, error) {
splitDepth, err := contract.GetSplitDepth(ctx)
if err != nil {
return nil, fmt.Errorf("failed to load split depth: %w", err)
......
......@@ -12,7 +12,7 @@ type GameSolver struct {
claimSolver *claimSolver
}
func NewGameSolver(gameDepth int, trace types.TraceAccessor) *GameSolver {
func NewGameSolver(gameDepth types.Depth, trace types.TraceAccessor) *GameSolver {
return &GameSolver{
claimSolver: newClaimSolver(gameDepth, trace),
}
......@@ -32,7 +32,7 @@ func (s *GameSolver) CalculateNextActions(ctx context.Context, game types.Game)
for _, claim := range game.Claims() {
var action *types.Action
var err error
if uint64(claim.Depth()) == game.MaxDepth() {
if claim.Depth() == game.MaxDepth() {
action, err = s.calculateStep(ctx, game, agreeWithRootClaim, claim)
} else {
action, err = s.calculateMove(ctx, game, agreeWithRootClaim, claim)
......
......@@ -7,12 +7,13 @@ import (
faulttest "github.com/ethereum-optimism/optimism/op-challenger/game/fault/test"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
func TestCalculateNextActions(t *testing.T) {
maxDepth := 4
maxDepth := types.Depth(4)
claimBuilder := faulttest.NewAlphabetClaimBuilder(t, maxDepth)
tests := []struct {
......
......@@ -36,7 +36,7 @@ func onlyStepAtMaxDepth(game types.Game, action types.Action) error {
if action.Type == types.ActionTypeStep {
return nil
}
parentDepth := uint64(game.Claims()[action.ParentIdx].Position.Depth())
parentDepth := game.Claims()[action.ParentIdx].Position.Depth()
if parentDepth >= game.MaxDepth() {
return fmt.Errorf("parent at max depth (%v) but attempting to perform %v action instead of step",
parentDepth, action.Type)
......@@ -48,7 +48,7 @@ func onlyMoveBeforeMaxDepth(game types.Game, action types.Action) error {
if action.Type == types.ActionTypeMove {
return nil
}
parentDepth := uint64(game.Claims()[action.ParentIdx].Position.Depth())
parentDepth := game.Claims()[action.ParentIdx].Position.Depth()
if parentDepth < game.MaxDepth() {
return fmt.Errorf("parent (%v) not at max depth (%v) but attempting to perform %v action instead of move",
parentDepth, game.MaxDepth(), action.Type)
......
......@@ -18,11 +18,11 @@ var (
// claimSolver uses a [TraceProvider] to determine the moves to make in a dispute game.
type claimSolver struct {
trace types.TraceAccessor
gameDepth int
gameDepth types.Depth
}
// newClaimSolver creates a new [claimSolver] using the provided [TraceProvider].
func newClaimSolver(gameDepth int, trace types.TraceAccessor) *claimSolver {
func newClaimSolver(gameDepth types.Depth, trace types.TraceAccessor) *claimSolver {
return &claimSolver{
trace,
gameDepth,
......
......@@ -13,7 +13,7 @@ import (
)
func TestAttemptStep(t *testing.T) {
maxDepth := 3
maxDepth := types.Depth(3)
claimBuilder := faulttest.NewAlphabetClaimBuilder(t, maxDepth)
// Last accessible leaf is the second last trace index
......
......@@ -8,22 +8,22 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
)
func NewAlphabetWithProofProvider(t *testing.T, maxDepth int, oracleError error) *alphabetWithProofProvider {
func NewAlphabetWithProofProvider(t *testing.T, maxDepth types.Depth, oracleError error) *alphabetWithProofProvider {
return &alphabetWithProofProvider{
alphabet.NewTraceProvider("abcdefghijklmnopqrstuvwxyz", uint64(maxDepth)),
uint64(maxDepth),
alphabet.NewTraceProvider("abcdefghijklmnopqrstuvwxyz", maxDepth),
maxDepth,
oracleError,
}
}
func NewAlphabetClaimBuilder(t *testing.T, maxDepth int) *ClaimBuilder {
func NewAlphabetClaimBuilder(t *testing.T, maxDepth types.Depth) *ClaimBuilder {
alphabetProvider := NewAlphabetWithProofProvider(t, maxDepth, nil)
return NewClaimBuilder(t, maxDepth, alphabetProvider)
}
type alphabetWithProofProvider struct {
*alphabet.AlphabetTraceProvider
depth uint64
depth types.Depth
OracleError error
}
......@@ -32,7 +32,7 @@ func (a *alphabetWithProofProvider) GetStepData(ctx context.Context, i types.Pos
if err != nil {
return nil, nil, nil, err
}
traceIndex := i.TraceIndex(int(a.depth)).Uint64()
traceIndex := i.TraceIndex(a.depth).Uint64()
data := types.NewPreimageOracleData([]byte{byte(traceIndex)}, []byte{byte(traceIndex - 1)}, uint32(traceIndex-1))
return preimage, []byte{byte(traceIndex - 1)}, data, nil
}
......@@ -13,12 +13,12 @@ import (
// ClaimBuilder is a test utility to enable creating claims in a wide range of situations
type ClaimBuilder struct {
require *require.Assertions
maxDepth int
maxDepth types.Depth
correct types.TraceProvider
}
// NewClaimBuilder creates a new [ClaimBuilder].
func NewClaimBuilder(t *testing.T, maxDepth int, provider types.TraceProvider) *ClaimBuilder {
func NewClaimBuilder(t *testing.T, maxDepth types.Depth, provider types.TraceProvider) *ClaimBuilder {
return &ClaimBuilder{
require: require.New(t),
maxDepth: maxDepth,
......
......@@ -16,7 +16,7 @@ type GameBuilder struct {
func (c *ClaimBuilder) GameBuilder(rootCorrect bool) *GameBuilder {
return &GameBuilder{
builder: c,
Game: types.NewGameState([]types.Claim{c.CreateRootClaim(rootCorrect)}, uint64(c.maxDepth)),
Game: types.NewGameState([]types.Claim{c.CreateRootClaim(rootCorrect)}, c.maxDepth),
}
}
......@@ -43,7 +43,7 @@ func (g *GameBuilder) SeqFrom(claim types.Claim) *GameBuilderSeq {
func (s *GameBuilderSeq) addClaimToGame(claim *types.Claim) {
claim.ContractIndex = len(s.gameBuilder.Game.Claims())
claims := append(s.gameBuilder.Game.Claims(), *claim)
s.gameBuilder.Game = types.NewGameState(claims, uint64(s.builder.maxDepth))
s.gameBuilder.Game = types.NewGameState(claims, s.builder.maxDepth)
}
func (s *GameBuilderSeq) AttackCorrect() *GameBuilderSeq {
......
......@@ -14,8 +14,8 @@ import (
func TestAccessor_UsesSelector(t *testing.T) {
ctx := context.Background()
depth := uint64(4)
provider1 := test.NewAlphabetWithProofProvider(t, int(depth), nil)
depth := types.Depth(4)
provider1 := test.NewAlphabetWithProofProvider(t, depth, nil)
provider2 := alphabet.NewTraceProvider("qrstuv", depth)
claim := types.Claim{}
game := types.NewGameState([]types.Claim{claim}, depth)
......
......@@ -29,12 +29,12 @@ var (
type AlphabetTraceProvider struct {
AlphabetPrestateProvider
state []string
depth uint64
depth types.Depth
maxLen uint64
}
// NewTraceProvider returns a new [AlphabetProvider].
func NewTraceProvider(state string, depth uint64) *AlphabetTraceProvider {
func NewTraceProvider(state string, depth types.Depth) *AlphabetTraceProvider {
return &AlphabetTraceProvider{
state: strings.Split(state, ""),
depth: depth,
......@@ -43,7 +43,7 @@ func NewTraceProvider(state string, depth uint64) *AlphabetTraceProvider {
}
func (ap *AlphabetTraceProvider) GetStepData(ctx context.Context, i types.Position) ([]byte, []byte, *types.PreimageOracleData, error) {
traceIndex := i.TraceIndex(int(ap.depth))
traceIndex := i.TraceIndex(ap.depth)
if traceIndex.Cmp(common.Big0) == 0 {
return absolutePrestate, []byte{}, nil, nil
}
......@@ -55,7 +55,7 @@ func (ap *AlphabetTraceProvider) GetStepData(ctx context.Context, i types.Positi
}
// We extend the deepest hash to the maximum depth if the trace is not expansive.
if traceIndex.Cmp(big.NewInt(int64(len(ap.state)))) >= 0 {
return ap.GetStepData(ctx, types.NewPosition(int(ap.depth), big.NewInt(int64(len(ap.state)))))
return ap.GetStepData(ctx, types.NewPosition(ap.depth, big.NewInt(int64(len(ap.state)))))
}
key := preimage.LocalIndexKey(L2ClaimBlockNumberLocalIndex).PreimageKey()
preimageData := types.NewPreimageOracleData(key[:], nil, 0)
......@@ -64,12 +64,12 @@ func (ap *AlphabetTraceProvider) GetStepData(ctx context.Context, i types.Positi
// Get returns the claim value at the given index in the trace.
func (ap *AlphabetTraceProvider) Get(ctx context.Context, i types.Position) (common.Hash, error) {
if uint64(i.Depth()) > ap.depth {
if i.Depth() > ap.depth {
return common.Hash{}, fmt.Errorf("%w depth: %v max: %v", ErrIndexTooLarge, i.Depth(), ap.depth)
}
// Step data returns the pre-state, so add 1 to get the state for index i
ti := i.TraceIndex(int(ap.depth))
postPosition := types.NewPosition(int(ap.depth), new(big.Int).Add(ti, big.NewInt(1)))
ti := i.TraceIndex(ap.depth)
postPosition := types.NewPosition(ap.depth, new(big.Int).Add(ti, big.NewInt(1)))
claimBytes, _, _, err := ap.GetStepData(ctx, postPosition)
if err != nil {
return common.Hash{}, err
......
......@@ -20,8 +20,8 @@ func alphabetClaim(index *big.Int, letter string) common.Hash {
// TestAlphabetProvider_Get_ClaimsByTraceIndex tests the [fault.AlphabetProvider] Get function.
func TestAlphabetProvider_Get_ClaimsByTraceIndex(t *testing.T) {
// Create a new alphabet provider.
depth := 3
canonicalProvider := NewTraceProvider("abcdefgh", uint64(depth))
depth := types.Depth(3)
canonicalProvider := NewTraceProvider("abcdefgh", depth)
// Build a list of traces.
traces := []struct {
......@@ -53,8 +53,8 @@ func TestAlphabetProvider_Get_ClaimsByTraceIndex(t *testing.T) {
// TestGetPreimage_Succeeds tests the GetPreimage function
// returns the correct pre-image for a index.
func TestGetStepData_Succeeds(t *testing.T) {
depth := 2
ap := NewTraceProvider("abc", uint64(depth))
depth := types.Depth(2)
ap := NewTraceProvider("abc", depth)
expected := BuildAlphabetPreimage(big.NewInt(0), "a")
pos := types.NewPosition(depth, big.NewInt(1))
retrieved, proof, data, err := ap.GetStepData(context.Background(), pos)
......@@ -69,8 +69,8 @@ func TestGetStepData_Succeeds(t *testing.T) {
// TestGetPreimage_TooLargeIndex_Fails tests the GetPreimage
// function errors if the index is too large.
func TestGetStepData_TooLargeIndex_Fails(t *testing.T) {
depth := 2
ap := NewTraceProvider("abc", uint64(depth))
depth := types.Depth(2)
ap := NewTraceProvider("abc", depth)
pos := types.NewPosition(depth, big.NewInt(5))
_, _, _, err := ap.GetStepData(context.Background(), pos)
require.ErrorIs(t, err, ErrIndexTooLarge)
......@@ -78,8 +78,8 @@ func TestGetStepData_TooLargeIndex_Fails(t *testing.T) {
// TestGet_Succeeds tests the Get function.
func TestGet_Succeeds(t *testing.T) {
depth := 2
ap := NewTraceProvider("abc", uint64(depth))
depth := types.Depth(2)
ap := NewTraceProvider("abc", depth)
pos := types.NewPosition(depth, big.NewInt(0))
claim, err := ap.Get(context.Background(), pos)
require.NoError(t, err)
......@@ -90,16 +90,16 @@ func TestGet_Succeeds(t *testing.T) {
// TestGet_IndexTooLarge tests the Get function with an index
// greater than the number of indices: 2^depth - 1.
func TestGet_IndexTooLarge(t *testing.T) {
depth := 2
ap := NewTraceProvider("abc", uint64(depth))
depth := types.Depth(2)
ap := NewTraceProvider("abc", depth)
pos := types.NewPosition(depth, big.NewInt(4))
_, err := ap.Get(context.Background(), pos)
require.ErrorIs(t, err, ErrIndexTooLarge)
}
func TestGet_DepthTooLarge(t *testing.T) {
depth := 2
ap := NewTraceProvider("abc", uint64(depth))
depth := types.Depth(2)
ap := NewTraceProvider("abc", depth)
pos := types.NewPosition(depth+1, big.NewInt(0))
_, err := ap.Get(context.Background(), pos)
require.ErrorIs(t, err, ErrIndexTooLarge)
......@@ -108,8 +108,8 @@ func TestGet_DepthTooLarge(t *testing.T) {
// TestGet_Extends tests the Get function with an index that is larger
// than the trace, but smaller than the maximum depth.
func TestGet_Extends(t *testing.T) {
depth := 2
ap := NewTraceProvider("abc", uint64(depth))
depth := types.Depth(2)
ap := NewTraceProvider("abc", depth)
pos := types.NewPosition(depth, big.NewInt(3))
claim, err := ap.Get(context.Background(), pos)
require.NoError(t, err)
......
......@@ -46,7 +46,7 @@ type CannonTraceProvider struct {
dir string
prestate string
generator ProofGenerator
gameDepth uint64
gameDepth types.Depth
localContext common.Hash
// lastStep stores the last step in the actual trace if known. 0 indicates unknown.
......@@ -54,7 +54,7 @@ type CannonTraceProvider struct {
lastStep uint64
}
func NewTraceProvider(logger log.Logger, m CannonMetricer, cfg *config.Config, localContext common.Hash, localInputs LocalGameInputs, dir string, gameDepth uint64) *CannonTraceProvider {
func NewTraceProvider(logger log.Logger, m CannonMetricer, cfg *config.Config, localContext common.Hash, localInputs LocalGameInputs, dir string, gameDepth types.Depth) *CannonTraceProvider {
return &CannonTraceProvider{
logger: logger,
dir: dir,
......@@ -65,12 +65,12 @@ func NewTraceProvider(logger log.Logger, m CannonMetricer, cfg *config.Config, l
}
}
func (p *CannonTraceProvider) SetMaxDepth(gameDepth uint64) {
func (p *CannonTraceProvider) SetMaxDepth(gameDepth types.Depth) {
p.gameDepth = gameDepth
}
func (p *CannonTraceProvider) Get(ctx context.Context, pos types.Position) (common.Hash, error) {
traceIndex := pos.TraceIndex(int(p.gameDepth))
traceIndex := pos.TraceIndex(p.gameDepth)
if !traceIndex.IsUint64() {
return common.Hash{}, errors.New("trace index out of bounds")
}
......@@ -87,7 +87,7 @@ func (p *CannonTraceProvider) Get(ctx context.Context, pos types.Position) (comm
}
func (p *CannonTraceProvider) GetStepData(ctx context.Context, pos types.Position) ([]byte, []byte, *types.PreimageOracleData, error) {
traceIndex := pos.TraceIndex(int(p.gameDepth))
traceIndex := pos.TraceIndex(p.gameDepth)
if !traceIndex.IsUint64() {
return nil, nil, nil, errors.New("trace index out of bounds")
}
......
......@@ -25,7 +25,7 @@ import (
var testData embed.FS
func PositionFromTraceIndex(provider *CannonTraceProvider, idx *big.Int) types.Position {
return types.NewPosition(int(provider.gameDepth), idx)
return types.NewPosition(provider.gameDepth, idx)
}
func TestGet(t *testing.T) {
......
......@@ -18,16 +18,16 @@ func NewOutputAlphabetTraceAccessor(
m metrics.Metricer,
prestateProvider types.PrestateProvider,
rollupClient OutputRollupClient,
splitDepth uint64,
splitDepth types.Depth,
prestateBlock uint64,
poststateBlock uint64,
) (*trace.Accessor, error) {
outputProvider := NewTraceProviderFromInputs(logger, prestateProvider, rollupClient, splitDepth, prestateBlock, poststateBlock)
alphabetCreator := func(ctx context.Context, localContext common.Hash, depth uint64, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
alphabetCreator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
provider := alphabet.NewTraceProvider(localContext.Hex(), depth)
return provider, nil
}
cache := NewProviderCache(m, "output_alphabet_provider", alphabetCreator)
selector := split.NewSplitProviderSelector(outputProvider, int(splitDepth), OutputRootSplitAdapter(outputProvider, cache.GetOrCreate))
selector := split.NewSplitProviderSelector(outputProvider, splitDepth, OutputRootSplitAdapter(outputProvider, cache.GetOrCreate))
return trace.NewAccessor(selector), nil
}
......@@ -25,12 +25,12 @@ func NewOutputCannonTraceAccessor(
prestateProvider types.PrestateProvider,
rollupClient OutputRollupClient,
dir string,
splitDepth uint64,
splitDepth types.Depth,
prestateBlock uint64,
poststateBlock uint64,
) (*trace.Accessor, error) {
outputProvider := NewTraceProviderFromInputs(logger, prestateProvider, rollupClient, splitDepth, prestateBlock, poststateBlock)
cannonCreator := func(ctx context.Context, localContext common.Hash, depth uint64, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
cannonCreator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
logger := logger.New("pre", agreed.OutputRoot, "post", claimed.OutputRoot, "localContext", localContext)
subdir := filepath.Join(dir, localContext.Hex())
localInputs, err := cannon.FetchLocalInputsFromProposals(ctx, contract, l2Client, agreed, claimed)
......@@ -42,6 +42,6 @@ func NewOutputCannonTraceAccessor(
}
cache := NewProviderCache(m, "output_cannon_provider", cannonCreator)
selector := split.NewSplitProviderSelector(outputProvider, int(splitDepth), OutputRootSplitAdapter(outputProvider, cache.GetOrCreate))
selector := split.NewSplitProviderSelector(outputProvider, splitDepth, OutputRootSplitAdapter(outputProvider, cache.GetOrCreate))
return trace.NewAccessor(selector), nil
}
......@@ -32,10 +32,10 @@ type OutputTraceProvider struct {
rollupClient OutputRollupClient
prestateBlock uint64
poststateBlock uint64
gameDepth uint64
gameDepth types.Depth
}
func NewTraceProvider(ctx context.Context, logger log.Logger, rollupRpc string, gameDepth, prestateBlock, poststateBlock uint64) (*OutputTraceProvider, error) {
func NewTraceProvider(ctx context.Context, logger log.Logger, rollupRpc string, gameDepth types.Depth, prestateBlock, poststateBlock uint64) (*OutputTraceProvider, error) {
rollupClient, err := dial.DialRollupClientWithTimeout(ctx, dial.DefaultDialTimeout, logger, rollupRpc)
if err != nil {
return nil, err
......@@ -44,7 +44,7 @@ func NewTraceProvider(ctx context.Context, logger log.Logger, rollupRpc string,
return NewTraceProviderFromInputs(logger, prestateProvider, rollupClient, gameDepth, prestateBlock, poststateBlock), nil
}
func NewTraceProviderFromInputs(logger log.Logger, prestateProvider types.PrestateProvider, rollupClient OutputRollupClient, gameDepth, prestateBlock, poststateBlock uint64) *OutputTraceProvider {
func NewTraceProviderFromInputs(logger log.Logger, prestateProvider types.PrestateProvider, rollupClient OutputRollupClient, gameDepth types.Depth, prestateBlock, poststateBlock uint64) *OutputTraceProvider {
return &OutputTraceProvider{
PrestateProvider: prestateProvider,
logger: logger,
......@@ -56,7 +56,7 @@ func NewTraceProviderFromInputs(logger log.Logger, prestateProvider types.Presta
}
func (o *OutputTraceProvider) BlockNumber(pos types.Position) (uint64, error) {
traceIndex := pos.TraceIndex(int(o.gameDepth))
traceIndex := pos.TraceIndex(o.gameDepth)
if !traceIndex.IsUint64() {
return 0, fmt.Errorf("%w: %v", ErrIndexTooBig, traceIndex)
}
......
......@@ -14,7 +14,7 @@ type ProviderCache struct {
creator ProposalTraceProviderCreator
}
func (c *ProviderCache) GetOrCreate(ctx context.Context, localContext common.Hash, depth uint64, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
func (c *ProviderCache) GetOrCreate(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
provider, ok := c.cache.Get(localContext)
if ok {
return provider, nil
......
......@@ -23,9 +23,9 @@ func TestProviderCache(t *testing.T) {
L2BlockNumber: big.NewInt(35),
OutputRoot: common.Hash{0xcc},
}
depth := uint64(6)
depth := types.Depth(6)
var createdProvider types.TraceProvider
creator := func(ctx context.Context, localContext common.Hash, depth uint64, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
creator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
createdProvider = alphabet.NewTraceProvider("abcdef", depth)
return createdProvider, nil
}
......@@ -57,7 +57,7 @@ func TestProviderCache(t *testing.T) {
func TestProviderCache_DoNotCacheErrors(t *testing.T) {
callCount := 0
providerErr := errors.New("boom")
creator := func(ctx context.Context, localContext common.Hash, depth uint64, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
creator := func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
callCount++
return nil, providerErr
}
......
......@@ -18,7 +18,7 @@ import (
var (
prestateBlock = uint64(100)
poststateBlock = uint64(200)
gameDepth = uint64(7) // 128 leaf nodes
gameDepth = types.Depth(7) // 128 leaf nodes
prestateOutputRoot = common.HexToHash("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
firstOutputRoot = common.HexToHash("0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
poststateOutputRoot = common.HexToHash("0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc")
......@@ -27,7 +27,7 @@ var (
func TestGet(t *testing.T) {
t.Run("ErrorsTraceIndexOutOfBounds", func(t *testing.T) {
deepGame := uint64(164)
deepGame := types.Depth(164)
provider, _ := setupWithTestData(t, prestateBlock, poststateBlock, deepGame)
pos := types.NewPosition(0, big.NewInt(0))
_, err := provider.Get(context.Background(), pos)
......@@ -36,14 +36,14 @@ func TestGet(t *testing.T) {
t.Run("FirstBlockAfterPrestate", func(t *testing.T) {
provider, _ := setupWithTestData(t, prestateBlock, poststateBlock)
value, err := provider.Get(context.Background(), types.NewPosition(int(gameDepth), big.NewInt(0)))
value, err := provider.Get(context.Background(), types.NewPosition(gameDepth, big.NewInt(0)))
require.NoError(t, err)
require.Equal(t, firstOutputRoot, value)
})
t.Run("MissingOutputAtBlock", func(t *testing.T) {
provider, _ := setupWithTestData(t, prestateBlock, poststateBlock)
_, err := provider.Get(context.Background(), types.NewPosition(int(gameDepth), big.NewInt(1)))
_, err := provider.Get(context.Background(), types.NewPosition(gameDepth, big.NewInt(1)))
require.ErrorIs(t, err, errNoOutputAtBlock)
})
......@@ -68,14 +68,14 @@ func TestGetBlockNumber(t *testing.T) {
pos types.Position
expected uint64
}{
{"FirstBlockAfterPrestate", types.NewPosition(int(gameDepth), big.NewInt(0)), prestateBlock + 1},
{"FirstBlockAfterPrestate", types.NewPosition(gameDepth, big.NewInt(0)), prestateBlock + 1},
{"PostStateBlock", types.NewPositionFromGIndex(big.NewInt(228)), poststateBlock},
{"AfterPostStateBlock", types.NewPositionFromGIndex(big.NewInt(229)), poststateBlock},
{"Root", types.NewPositionFromGIndex(big.NewInt(1)), poststateBlock},
{"MiddleNode1", types.NewPosition(int(gameDepth-1), big.NewInt(2)), 106},
{"MiddleNode2", types.NewPosition(int(gameDepth-1), big.NewInt(3)), 108},
{"Leaf1", types.NewPosition(int(gameDepth), big.NewInt(1)), prestateBlock + 2},
{"Leaf2", types.NewPosition(int(gameDepth), big.NewInt(2)), prestateBlock + 3},
{"MiddleNode1", types.NewPosition(gameDepth-1, big.NewInt(2)), 106},
{"MiddleNode2", types.NewPosition(gameDepth-1, big.NewInt(3)), 108},
{"Leaf1", types.NewPosition(gameDepth, big.NewInt(1)), prestateBlock + 2},
{"Leaf2", types.NewPosition(gameDepth, big.NewInt(2)), prestateBlock + 3},
}
for _, test := range tests {
test := test
......@@ -88,7 +88,7 @@ func TestGetBlockNumber(t *testing.T) {
}
t.Run("ErrorsTraceIndexOutOfBounds", func(t *testing.T) {
deepGame := uint64(164)
deepGame := types.Depth(164)
provider, _ := setupWithTestData(t, prestateBlock, poststateBlock, deepGame)
pos := types.NewPosition(0, big.NewInt(0))
_, err := provider.BlockNumber(pos)
......@@ -102,7 +102,7 @@ func TestGetStepData(t *testing.T) {
require.ErrorIs(t, err, ErrGetStepData)
}
func setupWithTestData(t *testing.T, prestateBlock, poststateBlock uint64, customGameDepth ...uint64) (*OutputTraceProvider, *stubRollupClient) {
func setupWithTestData(t *testing.T, prestateBlock, poststateBlock uint64, customGameDepth ...types.Depth) (*OutputTraceProvider, *stubRollupClient) {
rollupClient := stubRollupClient{
outputs: map[uint64]*eth.OutputResponse{
prestateBlock: {
......
......@@ -12,10 +12,10 @@ import (
"github.com/ethereum/go-ethereum/crypto"
)
type ProposalTraceProviderCreator func(ctx context.Context, localContext common.Hash, depth uint64, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error)
type ProposalTraceProviderCreator func(ctx context.Context, localContext common.Hash, depth types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error)
func OutputRootSplitAdapter(topProvider *OutputTraceProvider, creator ProposalTraceProviderCreator) split.ProviderCreator {
return func(ctx context.Context, depth uint64, pre types.Claim, post types.Claim) (types.TraceProvider, error) {
return func(ctx context.Context, depth types.Depth, pre types.Claim, post types.Claim) (types.TraceProvider, error) {
localContext := createLocalContext(pre, post)
usePrestateBlock := pre == (types.Claim{})
var agreed contracts.Proposal
......
......@@ -54,7 +54,7 @@ func TestOutputRootSplitAdapter(t *testing.T) {
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
topDepth := 10
topDepth := types.Depth(10)
adapter, creator := setupAdapterTest(t, topDepth)
preClaim := types.Claim{
ClaimData: types.ClaimData{
......@@ -92,7 +92,7 @@ func TestOutputRootSplitAdapter(t *testing.T) {
}
func TestOutputRootSplitAdapter_FromAbsolutePrestate(t *testing.T) {
topDepth := 10
topDepth := types.Depth(10)
adapter, creator := setupAdapterTest(t, topDepth)
postClaim := types.Claim{
......@@ -120,7 +120,7 @@ func TestOutputRootSplitAdapter_FromAbsolutePrestate(t *testing.T) {
require.Equal(t, expectedClaimed, creator.claimed)
}
func setupAdapterTest(t *testing.T, topDepth int) (split.ProviderCreator, *capturingCreator) {
func setupAdapterTest(t *testing.T, topDepth types.Depth) (split.ProviderCreator, *capturingCreator) {
prestateBlock := uint64(20)
poststateBlock := uint64(40)
creator := &capturingCreator{}
......@@ -134,7 +134,7 @@ func setupAdapterTest(t *testing.T, topDepth int) (split.ProviderCreator, *captu
prestateProvider := &stubPrestateProvider{
absolutePrestate: prestateOutputRoot,
}
topProvider := NewTraceProviderFromInputs(testlog.Logger(t, log.LvlInfo), prestateProvider, rollupClient, uint64(topDepth), prestateBlock, poststateBlock)
topProvider := NewTraceProviderFromInputs(testlog.Logger(t, log.LvlInfo), prestateProvider, rollupClient, topDepth, prestateBlock, poststateBlock)
adapter := OutputRootSplitAdapter(topProvider, creator.Create)
return adapter, creator
}
......@@ -145,7 +145,7 @@ type capturingCreator struct {
claimed contracts.Proposal
}
func (c *capturingCreator) Create(_ context.Context, localContext common.Hash, _ uint64, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
func (c *capturingCreator) Create(_ context.Context, localContext common.Hash, _ types.Depth, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
c.localContext = localContext
c.agreed = agreed
c.claimed = claimed
......
......@@ -14,9 +14,9 @@ var (
errRefClaimNotDeepEnough = errors.New("reference claim is not deep enough")
)
type ProviderCreator func(ctx context.Context, depth uint64, pre types.Claim, post types.Claim) (types.TraceProvider, error)
type ProviderCreator func(ctx context.Context, depth types.Depth, pre types.Claim, post types.Claim) (types.TraceProvider, error)
func NewSplitProviderSelector(topProvider types.TraceProvider, topDepth int, bottomProviderCreator ProviderCreator) trace.ProviderSelector {
func NewSplitProviderSelector(topProvider types.TraceProvider, topDepth types.Depth, bottomProviderCreator ProviderCreator) trace.ProviderSelector {
return func(ctx context.Context, game types.Game, ref types.Claim, pos types.Position) (types.TraceProvider, error) {
if pos.Depth() <= topDepth {
return topProvider, nil
......@@ -58,17 +58,17 @@ func NewSplitProviderSelector(topProvider types.TraceProvider, topDepth int, bot
}
// The top game runs from depth 0 to split depth *inclusive*.
// The - 1 here accounts for the fact that the split depth is included in the top game.
bottomDepth := game.MaxDepth() - uint64(topDepth) - 1
bottomDepth := game.MaxDepth() - topDepth - 1
provider, err := bottomProviderCreator(ctx, bottomDepth, pre, post)
if err != nil {
return nil, err
}
// Translate such that the root of the bottom game is the level below the top game leaf
return trace.Translate(provider, uint64(topDepth)+1), nil
return trace.Translate(provider, topDepth+1), nil
}
}
func findAncestorAtDepth(game types.Game, claim types.Claim, depth int) (types.Claim, error) {
func findAncestorAtDepth(game types.Game, claim types.Claim, depth types.Depth) (types.Claim, error) {
for claim.Depth() > depth {
parent, err := game.GetParent(claim)
if err != nil {
......@@ -79,7 +79,7 @@ func findAncestorAtDepth(game types.Game, claim types.Claim, depth int) (types.C
return claim, nil
}
func findAncestorWithTraceIndex(game types.Game, ref types.Claim, depth int, traceIdx *big.Int) (types.Claim, error) {
func findAncestorWithTraceIndex(game types.Game, ref types.Claim, depth types.Depth, traceIdx *big.Int) (types.Claim, error) {
candidate := ref
for candidate.TraceIndex(depth).Cmp(traceIdx) != 0 {
parent, err := game.GetParent(candidate)
......
......@@ -304,7 +304,7 @@ func asBottomTraceProvider(t *testing.T, actual types.TraceProvider) *bottomTrac
func setupAlphabetSplitSelector(t *testing.T) (*alphabet.AlphabetTraceProvider, trace.ProviderSelector, *test.GameBuilder) {
top := alphabet.NewTraceProvider("abcdef", splitDepth)
bottomCreator := func(ctx context.Context, depth uint64, pre types.Claim, post types.Claim) (types.TraceProvider, error) {
bottomCreator := func(ctx context.Context, depth types.Depth, pre types.Claim, post types.Claim) (types.TraceProvider, error) {
return &bottomTraceProvider{
pre: pre,
post: post,
......
......@@ -8,14 +8,14 @@ import (
)
type TranslatingProvider struct {
rootDepth uint64
rootDepth types.Depth
provider types.TraceProvider
}
// Translate returns a new TraceProvider that translates any requested positions before passing them on to the
// specified provider.
// The translation is done such that the root node for provider is at rootDepth.
func Translate(provider types.TraceProvider, rootDepth uint64) types.TraceProvider {
func Translate(provider types.TraceProvider, rootDepth types.Depth) types.TraceProvider {
return &TranslatingProvider{
rootDepth: rootDepth,
provider: provider,
......
......@@ -32,7 +32,7 @@ type Game interface {
// AgreeWithClaimLevel returns if the game state agrees with the provided claim level.
AgreeWithClaimLevel(claim Claim, agreeWithRootClaim bool) bool
MaxDepth() uint64
MaxDepth() Depth
}
type claimID common.Hash
......@@ -51,12 +51,12 @@ type gameState struct {
// claims is the list of claims in the same order as the contract
claims []Claim
claimIDs map[claimID]bool
depth uint64
depth Depth
}
// NewGameState returns a new game state.
// The provided [Claim] is used as the root node.
func NewGameState(claims []Claim, depth uint64) *gameState {
func NewGameState(claims []Claim, depth Depth) *gameState {
claimIDs := make(map[claimID]bool)
for _, claim := range claims {
claimIDs[computeClaimID(claim)] = true
......@@ -89,7 +89,7 @@ func (g *gameState) Claims() []Claim {
return append([]Claim(nil), g.claims...)
}
func (g *gameState) MaxDepth() uint64 {
func (g *gameState) MaxDepth() Depth {
return g.depth
}
......
......@@ -12,13 +12,18 @@ var (
ErrPositionDepthTooSmall = errors.New("position depth is too small")
)
// Depth is the depth of a position in a game tree where the root level has
// depth 0, the root's children have depth 1, their children have depth 2, and
// so on.
type Depth uint64
// Position is a golang wrapper around the dispute game Position type.
type Position struct {
depth int
depth Depth
indexAtDepth *big.Int
}
func NewPosition(depth int, indexAtDepth *big.Int) Position {
func NewPosition(depth Depth, indexAtDepth *big.Int) Position {
return Position{
depth: depth,
indexAtDepth: indexAtDepth,
......@@ -46,17 +51,17 @@ func (p Position) MoveRight() Position {
// RelativeToAncestorAtDepth returns a new position for a subtree.
// [ancestor] is the depth of the subtree root node.
func (p Position) RelativeToAncestorAtDepth(ancestor uint64) (Position, error) {
if ancestor > uint64(p.depth) {
func (p Position) RelativeToAncestorAtDepth(ancestor Depth) (Position, error) {
if ancestor > p.depth {
return Position{}, ErrPositionDepthTooSmall
}
newPosDepth := uint64(p.depth) - ancestor
newPosDepth := p.depth - ancestor
nodesAtDepth := 1 << newPosDepth
newIndexAtDepth := new(big.Int).Mod(p.indexAtDepth, big.NewInt(int64(nodesAtDepth)))
return NewPosition(int(newPosDepth), newIndexAtDepth), nil
return NewPosition(newPosDepth, newIndexAtDepth), nil
}
func (p Position) Depth() int {
func (p Position) Depth() Depth {
return p.depth
}
......@@ -71,13 +76,13 @@ func (p Position) IsRootPosition() bool {
return p.depth == 0 && common.Big0.Cmp(p.indexAtDepth) == 0
}
func (p Position) lshIndex(amount int) *big.Int {
func (p Position) lshIndex(amount Depth) *big.Int {
return new(big.Int).Lsh(p.IndexAtDepth(), uint(amount))
}
// TraceIndex calculates the what the index of the claim value would be inside the trace.
// It is equivalent to going right until the final depth has been reached.
func (p Position) TraceIndex(maxDepth int) *big.Int {
func (p Position) TraceIndex(maxDepth Depth) *big.Int {
// When we go right, we do a shift left and set the bottom bit to be 1.
// To do this in a single step, do all the shifts at once & or in all 1s for the bottom bits.
rd := maxDepth - p.depth
......@@ -128,7 +133,7 @@ func (p Position) Defend() Position {
return p.parent().move(true).move(false)
}
func (p Position) Print(maxDepth int) {
func (p Position) Print(maxDepth Depth) {
fmt.Printf("GIN: %4b\tTrace Position is %4b\tTrace Depth is: %d\tTrace Index is: %d\n", p.ToGIndex(), p.indexAtDepth, p.depth, p.TraceIndex(maxDepth))
}
......@@ -137,11 +142,11 @@ func (p Position) ToGIndex() *big.Int {
}
// bigMSB returns the index of the most significant bit
func bigMSB(x *big.Int) int {
func bigMSB(x *big.Int) Depth {
if x.Cmp(big.NewInt(0)) == 0 {
return 0
}
out := 0
out := Depth(0)
for ; x.Cmp(big.NewInt(0)) != 0; out++ {
x = new(big.Int).Rsh(x, 1)
}
......
......@@ -18,7 +18,7 @@ func TestBigMSB(t *testing.T) {
require.True(t, ok)
tests := []struct {
input *big.Int
expected int
expected Depth
}{
{bi(0), 0},
{bi(1), 0},
......@@ -104,9 +104,9 @@ func TestTraceIndexOfRootWithLargeDepth(t *testing.T) {
// TestTraceIndex creates the position & then tests the trace index function.
func TestTraceIndex(t *testing.T) {
tests := []struct {
depth int
depth Depth
indexAtDepth *big.Int
maxDepth int
maxDepth Depth
traceIndexExpected *big.Int
}{
{depth: 0, indexAtDepth: bi(0), maxDepth: 4, traceIndexExpected: bi(15)},
......@@ -209,7 +209,7 @@ func TestRelativeToAncestorAtDepth(t *testing.T) {
tests := []struct {
gindex int64
newRootDepth uint64
newRootDepth Depth
expectedGIndex int64
}{
{gindex: 5, newRootDepth: 1, expectedGIndex: 3},
......@@ -304,7 +304,7 @@ func TestRelativeMoves(t *testing.T) {
expectedRelativePosition := test(NewPositionFromGIndex(big.NewInt(1)))
relative := NewPositionFromGIndex(big.NewInt(3))
start := test(relative)
relativePosition, err := start.RelativeToAncestorAtDepth(uint64(relative.Depth()))
relativePosition, err := start.RelativeToAncestorAtDepth(relative.Depth())
require.NoError(t, err)
require.Equal(t, expectedRelativePosition.ToGIndex(), relativePosition.ToGIndex())
})
......
......@@ -4,6 +4,7 @@ import (
"context"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
)
......@@ -25,7 +26,7 @@ func (g *AlphabetGameHelper) StartChallenger(ctx context.Context, l1Endpoint str
return c
}
func (g *AlphabetGameHelper) CreateHonestActor(alphabetTrace string, depth uint64) *HonestHelper {
func (g *AlphabetGameHelper) CreateHonestActor(alphabetTrace string, depth types.Depth) *HonestHelper {
return &HonestHelper{
t: g.t,
require: g.require,
......@@ -34,6 +35,6 @@ func (g *AlphabetGameHelper) CreateHonestActor(alphabetTrace string, depth uint6
}
}
func (g *AlphabetGameHelper) CreateDishonestHelper(alphabetTrace string, depth uint64, defender bool) *DishonestHelper {
func (g *AlphabetGameHelper) CreateDishonestHelper(alphabetTrace string, depth types.Depth, defender bool) *DishonestHelper {
return newDishonestHelper(&g.FaultGameHelper, g.CreateHonestActor(alphabetTrace, depth), defender)
}
......@@ -42,26 +42,26 @@ func (c *ClaimHelper) IsRootClaim() bool {
func (c *ClaimHelper) IsOutputRoot(ctx context.Context) bool {
splitDepth := c.game.SplitDepth(ctx)
return int64(c.position.Depth()) <= splitDepth
return c.position.Depth() <= splitDepth
}
func (c *ClaimHelper) IsOutputRootLeaf(ctx context.Context) bool {
splitDepth := c.game.SplitDepth(ctx)
return int64(c.position.Depth()) == splitDepth
return c.position.Depth() == splitDepth
}
func (c *ClaimHelper) IsBottomGameRoot(ctx context.Context) bool {
splitDepth := c.game.SplitDepth(ctx)
return int64(c.position.Depth()) == splitDepth+1
return c.position.Depth() == splitDepth+1
}
func (c *ClaimHelper) IsMaxDepth(ctx context.Context) bool {
maxDepth := c.game.MaxDepth(ctx)
return int64(c.position.Depth()) == maxDepth
return c.position.Depth() == maxDepth
}
func (c *ClaimHelper) Depth() int64 {
return int64(c.position.Depth())
func (c *ClaimHelper) Depth() types.Depth {
return c.position.Depth()
}
// WaitForCounterClaim waits for the claim to be countered by another claim being posted.
......
......@@ -76,7 +76,7 @@ func (d *DishonestHelper) ExhaustDishonestClaims(ctx context.Context) {
// honest level, invalid defense
pos := types.NewPositionFromGIndex(claimData.Position)
if int64(pos.Depth()) == depth {
if pos.Depth() == depth {
return
}
......
......@@ -58,10 +58,10 @@ func (g *FaultGameHelper) WaitForClaimCount(ctx context.Context, count int64) {
}
}
func (g *FaultGameHelper) MaxDepth(ctx context.Context) int64 {
func (g *FaultGameHelper) MaxDepth(ctx context.Context) types.Depth {
depth, err := g.game.MaxGameDepth(&bind.CallOpts{Context: ctx})
g.require.NoError(err, "Failed to load game depth")
return depth.Int64()
return types.Depth(depth.Uint64())
}
func (g *FaultGameHelper) waitForClaim(ctx context.Context, errorMsg string, predicate func(claim ContractClaim) bool) {
......@@ -141,7 +141,7 @@ func (g *FaultGameHelper) getClaimPosition(ctx context.Context, claimIdx int64)
return types.NewPositionFromGIndex(g.getClaim(ctx, claimIdx).Position)
}
func (g *FaultGameHelper) WaitForClaimAtDepth(ctx context.Context, depth int) {
func (g *FaultGameHelper) WaitForClaimAtDepth(ctx context.Context, depth types.Depth) {
g.waitForClaim(
ctx,
fmt.Sprintf("Could not find claim depth %v", depth),
......@@ -158,7 +158,7 @@ func (g *FaultGameHelper) WaitForClaimAtMaxDepth(ctx context.Context, countered
fmt.Sprintf("Could not find claim depth %v with countered=%v", maxDepth, countered),
func(claim ContractClaim) bool {
pos := types.NewPositionFromGIndex(claim.Position)
return int64(pos.Depth()) == maxDepth && claim.Countered == countered
return pos.Depth() == maxDepth && claim.Countered == countered
})
}
......@@ -248,7 +248,7 @@ func (g *FaultGameHelper) WaitForInactivity(ctx context.Context, numInactiveBloc
// When the game has reached the maximum depth it waits for the honest challenger to counter the leaf claim with step.
func (g *FaultGameHelper) DefendRootClaim(ctx context.Context, performMove func(parentClaimIdx int64)) {
maxDepth := g.MaxDepth(ctx)
for claimCount := int64(1); claimCount < maxDepth; {
for claimCount := int64(1); types.Depth(claimCount) < maxDepth; {
g.LogGameData(ctx)
claimCount++
// Wait for the challenger to counter
......@@ -270,7 +270,7 @@ func (g *FaultGameHelper) DefendRootClaim(ctx context.Context, performMove func(
// Since the output root is invalid, it should not be possible for the Stepper to call step successfully.
func (g *FaultGameHelper) ChallengeRootClaim(ctx context.Context, performMove func(parentClaimIdx int64), attemptStep Stepper) {
maxDepth := g.MaxDepth(ctx)
for claimCount := int64(1); claimCount < maxDepth; {
for claimCount := int64(1); types.Depth(claimCount) < maxDepth; {
g.LogGameData(ctx)
// Perform our move
performMove(claimCount - 1)
......@@ -287,7 +287,7 @@ func (g *FaultGameHelper) ChallengeRootClaim(ctx context.Context, performMove fu
g.LogGameData(ctx)
// It's on us to call step if we want to win but shouldn't be possible
attemptStep(maxDepth)
attemptStep(int64(maxDepth))
}
func (g *FaultGameHelper) WaitForNewClaim(ctx context.Context, checkPoint int64) (int64, error) {
......@@ -342,7 +342,7 @@ func (g *FaultGameHelper) ResolveClaim(ctx context.Context, claimIdx int64) {
func (g *FaultGameHelper) gameData(ctx context.Context) string {
opts := &bind.CallOpts{Context: ctx}
maxDepth := int(g.MaxDepth(ctx))
maxDepth := g.MaxDepth(ctx)
claimCount, err := g.game.ClaimDataLen(opts)
info := fmt.Sprintf("Claim count: %v\n", claimCount)
g.require.NoError(err, "Fetching claim count")
......
......@@ -12,6 +12,7 @@ import (
"github.com/ethereum-optimism/optimism/op-chain-ops/deployer"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs"
faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/l2oo"
......@@ -138,7 +139,7 @@ func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string
splitDepth, err := game.SplitDepth(&bind.CallOpts{Context: ctx})
h.require.NoError(err, "Failed to load split depth")
prestateProvider := outputs.NewPrestateProvider(ctx, logger, rollupClient, prestateBlock.Uint64())
provider := outputs.NewTraceProviderFromInputs(logger, prestateProvider, rollupClient, splitDepth.Uint64(), prestateBlock.Uint64(), poststateBlock.Uint64())
provider := outputs.NewTraceProviderFromInputs(logger, prestateProvider, rollupClient, faultTypes.Depth(splitDepth.Uint64()), prestateBlock.Uint64(), poststateBlock.Uint64())
return &OutputCannonGameHelper{
OutputGameHelper: OutputGameHelper{
......@@ -190,7 +191,7 @@ func (h *FactoryHelper) StartOutputAlphabetGame(ctx context.Context, l2Node stri
splitDepth, err := game.SplitDepth(&bind.CallOpts{Context: ctx})
h.require.NoError(err, "Failed to load split depth")
prestateProvider := outputs.NewPrestateProvider(ctx, logger, rollupClient, prestateBlock.Uint64())
provider := outputs.NewTraceProviderFromInputs(logger, prestateProvider, rollupClient, splitDepth.Uint64(), prestateBlock.Uint64(), poststateBlock.Uint64())
provider := outputs.NewTraceProviderFromInputs(logger, prestateProvider, rollupClient, faultTypes.Depth(splitDepth.Uint64()), prestateBlock.Uint64(), poststateBlock.Uint64())
return &OutputAlphabetGameHelper{
OutputGameHelper: OutputGameHelper{
......
......@@ -42,7 +42,7 @@ func (g *OutputAlphabetGameHelper) CreateHonestActor(ctx context.Context, l2Node
g.require.NoError(err, "Failed to create game contact")
prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx)
g.require.NoError(err, "Get block range")
splitDepth := uint64(g.SplitDepth(ctx))
splitDepth := g.SplitDepth(ctx)
rollupClient := g.system.RollupClient(l2Node)
prestateProvider := outputs.NewPrestateProvider(ctx, logger, rollupClient, prestateBlock)
correctTrace, err := outputs.NewOutputAlphabetTraceAccessor(logger, metrics.NoopMetrics, prestateProvider, rollupClient, splitDepth, prestateBlock, poststateBlock)
......
......@@ -56,7 +56,7 @@ func (g *OutputCannonGameHelper) CreateHonestActor(ctx context.Context, l2Node s
prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx)
g.require.NoError(err, "Failed to load block range")
dir := filepath.Join(cfg.Datadir, "honest")
splitDepth := uint64(g.SplitDepth(ctx))
splitDepth := g.SplitDepth(ctx)
rollupClient := g.system.RollupClient(l2Node)
prestateProvider := outputs.NewPrestateProvider(ctx, logger, rollupClient, prestateBlock)
accessor, err := outputs.NewOutputCannonTraceAccessor(
......
......@@ -36,10 +36,10 @@ func (g *OutputGameHelper) Addr() common.Address {
return g.addr
}
func (g *OutputGameHelper) SplitDepth(ctx context.Context) int64 {
func (g *OutputGameHelper) SplitDepth(ctx context.Context) types.Depth {
splitDepth, err := g.game.SplitDepth(&bind.CallOpts{Context: ctx})
g.require.NoError(err, "failed to load split depth")
return splitDepth.Int64()
return types.Depth(splitDepth.Uint64())
}
func (g *OutputGameHelper) L2BlockNum(ctx context.Context) uint64 {
......@@ -152,10 +152,10 @@ type ContractClaim struct {
Clock *big.Int
}
func (g *OutputGameHelper) MaxDepth(ctx context.Context) int64 {
func (g *OutputGameHelper) MaxDepth(ctx context.Context) types.Depth {
depth, err := g.game.MaxGameDepth(&bind.CallOpts{Context: ctx})
g.require.NoError(err, "Failed to load game depth")
return depth.Int64()
return types.Depth(depth.Uint64())
}
func (g *OutputGameHelper) waitForClaim(ctx context.Context, errorMsg string, predicate func(claimIdx int64, claim ContractClaim) bool) (int64, ContractClaim) {
......@@ -238,7 +238,7 @@ func (g *OutputGameHelper) getClaim(ctx context.Context, claimIdx int64) Contrac
return claimData
}
func (g *OutputGameHelper) WaitForClaimAtDepth(ctx context.Context, depth int) {
func (g *OutputGameHelper) WaitForClaimAtDepth(ctx context.Context, depth types.Depth) {
g.waitForClaim(
ctx,
fmt.Sprintf("Could not find claim depth %v", depth),
......@@ -255,7 +255,7 @@ func (g *OutputGameHelper) WaitForClaimAtMaxDepth(ctx context.Context, countered
fmt.Sprintf("Could not find claim depth %v with countered=%v", maxDepth, countered),
func(_ int64, claim ContractClaim) bool {
pos := types.NewPositionFromGIndex(claim.Position)
return int64(pos.Depth()) == maxDepth && claim.Countered == countered
return pos.Depth() == maxDepth && claim.Countered == countered
})
}
......@@ -459,8 +459,8 @@ func (g *OutputGameHelper) ResolveClaim(ctx context.Context, claimIdx int64) {
func (g *OutputGameHelper) gameData(ctx context.Context) string {
opts := &bind.CallOpts{Context: ctx}
maxDepth := int(g.MaxDepth(ctx))
splitDepth := int(g.SplitDepth(ctx))
maxDepth := g.MaxDepth(ctx)
splitDepth := g.SplitDepth(ctx)
claimCount, err := g.game.ClaimDataLen(opts)
info := fmt.Sprintf("Claim count: %v\n", claimCount)
g.require.NoError(err, "Fetching claim count")
......
......@@ -83,7 +83,7 @@ func (h *OutputHonestHelper) StepFails(ctx context.Context, claimIdx int64, isAt
func (h *OutputHonestHelper) loadState(ctx context.Context, claimIdx int64) (types.Game, types.Claim) {
claims, err := h.contract.GetAllClaims(ctx)
h.require.NoError(err, "Failed to load claims from game")
game := types.NewGameState(claims, uint64(h.game.MaxDepth(ctx)))
game := types.NewGameState(claims, h.game.MaxDepth(ctx))
claim := game.Claims()[claimIdx]
return game, claim
......
......@@ -4,6 +4,7 @@ import (
"context"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame"
......@@ -30,25 +31,25 @@ func TestOutputAlphabetGame(t *testing.T) {
game.LogGameData(ctx)
// Challenger should post an output root to counter claims down to the leaf level of the top game
splitDepth := game.SplitDepth(ctx)
for i := int64(1); i < splitDepth; i += 2 {
for i := int64(1); types.Depth(i) < splitDepth; i += 2 {
game.WaitForCorrectOutputRoot(ctx, i)
game.Attack(ctx, i, common.Hash{0xaa})
game.LogGameData(ctx)
}
// Wait for the challenger to post the first claim in the alphabet trace
game.WaitForClaimAtDepth(ctx, int(splitDepth+1))
game.WaitForClaimAtDepth(ctx, splitDepth+1)
game.LogGameData(ctx)
game.Attack(ctx, splitDepth+1, common.Hash{0x00, 0xcc})
game.Attack(ctx, int64(splitDepth)+1, common.Hash{0x00, 0xcc})
gameDepth := game.MaxDepth(ctx)
for i := splitDepth + 3; i < gameDepth; i += 2 {
// Wait for challenger to respond
game.WaitForClaimAtDepth(ctx, int(i))
game.WaitForClaimAtDepth(ctx, types.Depth(i))
game.LogGameData(ctx)
// Respond to push the game down to the max depth
game.Defend(ctx, i, common.Hash{0x00, 0xdd})
game.Defend(ctx, int64(i), common.Hash{0x00, 0xdd})
game.LogGameData(ctx)
}
game.LogGameData(ctx)
......
......@@ -5,6 +5,7 @@ import (
"fmt"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame"
......@@ -122,7 +123,7 @@ func TestOutputCannon_PublishCannonRootClaim(t *testing.T) {
game.StartChallenger(ctx, "sequencer", "Challenger", challenger.WithPrivKey(sys.Cfg.Secrets.Alice))
splitDepth := game.SplitDepth(ctx)
game.WaitForClaimAtDepth(ctx, int(splitDepth)+1)
game.WaitForClaimAtDepth(ctx, splitDepth+1)
})
}
}
......@@ -133,7 +134,7 @@ func TestOutputCannonDisputeGame(t *testing.T) {
tests := []struct {
name string
defendClaimDepth int64
defendClaimDepth types.Depth
}{
{"StepFirst", 0},
{"StepMiddle", 28},
......
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