Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions op-challenger2/cmd/list_claims.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,12 @@ func listClaims(ctx context.Context, game contracts.FaultDisputeGameContract, ve
}

// 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 := maxDepth - splitDepth - 1
// The - nbits here accounts for the fact that the split depth is included in the top game.
nbits, err := game.GetNBits(ctx)
if err != nil {
return fmt.Errorf("failed to retrieve nbits: %w", err)
}
bottomDepth := maxDepth - splitDepth - types.Depth(nbits)

resolved, err := game.IsResolved(ctx, rpcblock.Latest, claims...)
if err != nil {
Expand Down
22 changes: 14 additions & 8 deletions op-challenger2/game/fault/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,15 @@ func TestDoNotMakeMovesWhenL2BlockNumberChallenged(t *testing.T) {
}

func createClaimsWithClaimants(t *testing.T, d types.Depth) []types.Claim {
claimBuilder := test.NewClaimBuilder(t, d, alphabet.NewTraceProvider(big.NewInt(0), d))
nbits := uint64(1)
splitDepth := types.Depth(3)
claimBuilder := test.NewClaimBuilder2(t, d, nbits, splitDepth, alphabet.NewTraceProvider(big.NewInt(0), d))
rootClaim := claimBuilder.CreateRootClaim()
claim1 := rootClaim
claim1.Claimant = common.BigToAddress(big.NewInt(1))
claim2 := claimBuilder.AttackClaim(claim1)
claim2 := claimBuilder.AttackClaim2(claim1, nil, 0)
claim2.Claimant = common.BigToAddress(big.NewInt(2))
claim3 := claimBuilder.AttackClaim(claim2)
claim3 := claimBuilder.AttackClaim2(claim2, nil, 0)
claim3.Claimant = common.BigToAddress(big.NewInt(3))
return []types.Claim{claim1, claim2, claim3}
}
Expand Down Expand Up @@ -150,14 +152,16 @@ func TestSkipAttemptingToResolveClaimsWhenClockNotExpired(t *testing.T) {
responder.callResolveErr = errors.New("game is not resolvable")
responder.callResolveClaimErr = errors.New("claim is not resolvable")
depth := types.Depth(4)
claimBuilder := test.NewClaimBuilder(t, depth, alphabet.NewTraceProvider(big.NewInt(0), depth))
nbits := uint64(1)
splitDepth := types.Depth(3)
claimBuilder := test.NewClaimBuilder2(t, depth, nbits, splitDepth, alphabet.NewTraceProvider(big.NewInt(0), depth))

rootTime := l1Time.Add(-agent.maxClockDuration - 5*time.Minute)
gameBuilder := claimBuilder.GameBuilder(test.WithClock(rootTime, 0))
gameBuilder.Seq().
Attack(test.WithClock(rootTime.Add(5*time.Minute), 5*time.Minute)).
Defend(test.WithClock(rootTime.Add(7*time.Minute), 2*time.Minute)).
Attack(test.WithClock(rootTime.Add(11*time.Minute), 4*time.Minute))
Attack2(nil, 0, test.WithClock(rootTime.Add(5*time.Minute), 5*time.Minute)).
Attack2(nil, 1, test.WithClock(rootTime.Add(7*time.Minute), 2*time.Minute)).
Attack2(nil, 0, test.WithClock(rootTime.Add(11*time.Minute), 4*time.Minute))
claimLoader.claims = gameBuilder.Game.Claims()

require.NoError(t, agent.Act(context.Background()))
Expand All @@ -173,7 +177,9 @@ func TestLoadClaimsWhenGameNotResolvable(t *testing.T) {
responder.callResolveErr = errors.New("game is not resolvable")
responder.callResolveClaimErr = errors.New("claim is not resolvable")
depth := types.Depth(4)
claimBuilder := test.NewClaimBuilder(t, depth, alphabet.NewTraceProvider(big.NewInt(0), depth))
nbits := uint64(1)
splitDepth := types.Depth(3)
claimBuilder := test.NewClaimBuilder2(t, depth, nbits, splitDepth, alphabet.NewTraceProvider(big.NewInt(0), depth))

claimLoader.claims = []types.Claim{
claimBuilder.CreateRootClaim(),
Expand Down
3 changes: 3 additions & 0 deletions op-challenger2/game/fault/contracts/faultdisputegame.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ func mustParseAbi(json []byte) *abi.ABI {
}

func SubValuesHash(values []common.Hash) common.Hash {
if len(values) == 0 {
return common.Hash{}
}
nelem := len(values)
hashes := make([]common.Hash, nelem)
copy(hashes, values)
Expand Down
10 changes: 10 additions & 0 deletions op-challenger2/game/fault/contracts/faultdisputegame_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,8 @@ func TestSubValuesHash(t *testing.T) {
allClaims := [][]common.Hash{
{{0x01}, {0x02}, {0x03}},
{{0x01}, {0x02}, {0x03}, {0x04}},
{},
nil,
}
Hash := crypto.Keccak256Hash
tests := []struct {
Expand All @@ -970,6 +972,14 @@ func TestSubValuesHash(t *testing.T) {
claims: allClaims[1],
expectedHash: Hash(Hash(allClaims[1][0][:], allClaims[1][1][:]).Bytes(), Hash(allClaims[1][2][:], allClaims[1][3][:]).Bytes()),
},
{
claims: allClaims[2],
expectedHash: common.Hash{},
},
{
claims: allClaims[3],
expectedHash: common.Hash{},
},
}

for _, test := range tests {
Expand Down
32 changes: 16 additions & 16 deletions op-challenger2/game/fault/solver/actors.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,63 +43,63 @@ var doNothingActor builderFn = func(builder *test.GameBuilder) bool {
}

var correctAttackLastClaim = respondLastClaim(func(seq *test.GameBuilderSeq) {
seq.Attack()
seq.Attack2(nil, 0)
})

var correctDefendLastClaim = respondLastClaim(func(seq *test.GameBuilderSeq) {
if seq.IsRoot() {
// Must attack the root
seq.Attack()
seq.Attack2(nil, 0)
} else {
seq.Defend()
seq.Attack2(nil, 1)
}
})

var incorrectAttackLastClaim = respondLastClaim(func(seq *test.GameBuilderSeq) {
seq.Attack(test.WithValue(common.Hash{0xaa}))
seq.Attack2(nil, 0, test.WithValue(common.Hash{0xaa}))
})

var incorrectDefendLastClaim = respondLastClaim(func(seq *test.GameBuilderSeq) {
if seq.IsRoot() {
// Must attack the root
seq.Attack(test.WithValue(common.Hash{0xdd}))
seq.Attack2(nil, 0, test.WithValue(common.Hash{0xdd}))
} else {
seq.Defend(test.WithValue(common.Hash{0xdd}))
seq.Attack2(nil, 1, test.WithValue(common.Hash{0xdd}))
}
})

var attackEverythingCorrect = respondAllClaims(func(seq *test.GameBuilderSeq) {
seq.Attack()
seq.Attack2(nil, 0)
})

var defendEverythingCorrect = respondAllClaims(func(seq *test.GameBuilderSeq) {
if seq.IsRoot() {
// Must attack root
seq.Attack()
seq.Attack2(nil, 0)
} else {
seq.Defend()
seq.Attack2(nil, 1)
}
})

var attackEverythingIncorrect = respondAllClaims(func(seq *test.GameBuilderSeq) {
seq.Attack(test.WithValue(common.Hash{0xaa}))
seq.Attack2(nil, 0, test.WithValue(common.Hash{0xaa}))
})

var defendEverythingIncorrect = respondAllClaims(func(seq *test.GameBuilderSeq) {
if seq.IsRoot() {
// Must attack root
seq.Attack(test.WithValue(common.Hash{0xbb}))
seq.Attack2(nil, 0, test.WithValue(common.Hash{0xbb}))
} else {
seq.Defend(test.WithValue(common.Hash{0xbb}))
seq.Attack2(nil, 1, test.WithValue(common.Hash{0xbb}))
}
})

var exhaustive = respondAllClaims(func(seq *test.GameBuilderSeq) {
seq.Attack()
seq.Attack(test.WithValue(common.Hash{0xaa}))
seq.Attack2(nil, 0)
seq.Attack2(nil, 0, test.WithValue(common.Hash{0xaa}))
if !seq.IsRoot() {
seq.Defend()
seq.Defend(test.WithValue(common.Hash{0xdd}))
seq.Attack2(nil, 1)
seq.Attack2(nil, 1, test.WithValue(common.Hash{0xdd}))
}
})

Expand Down
14 changes: 10 additions & 4 deletions op-challenger2/game/fault/solver/game_solver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ func TestCalculateNextActions_ChallengeL2BlockNumber(t *testing.T) {
challenge := &types.InvalidL2BlockNumberChallenge{
Output: &eth.OutputResponse{OutputRoot: eth.Bytes32{0xbb}},
}
claimBuilder := faulttest.NewAlphabetClaimBuilder(t, startingBlock, maxDepth)
traceProvider := faulttest.NewAlphabetWithProofProvider(t, startingBlock, maxDepth, nil)
nbits := uint64(1)
splitDepth := types.Depth(3)
claimBuilder := faulttest.NewAlphabetClaimBuilder2(t, startingBlock, maxDepth, nbits, splitDepth)
traceProvider := faulttest.NewAlphabetWithProofProvider(t, startingBlock, maxDepth, nil, 0, faulttest.OracleDefaultKey)
solver := NewGameSolver(maxDepth, trace.NewSimpleTraceAccessor(traceProvider), types.CallDataType)

// Do not challenge when provider returns error indicating l2 block is valid
Expand All @@ -43,7 +45,9 @@ func TestCalculateNextActions_ChallengeL2BlockNumber(t *testing.T) {
func TestCalculateNextActions(t *testing.T) {
maxDepth := types.Depth(6)
startingL2BlockNumber := big.NewInt(0)
claimBuilder := faulttest.NewAlphabetClaimBuilder(t, startingL2BlockNumber, maxDepth)
nbits := uint64(1)
splitDepth := types.Depth(3)
claimBuilder := faulttest.NewAlphabetClaimBuilder2(t, startingL2BlockNumber, maxDepth, nbits, splitDepth)

tests := []struct {
name string
Expand Down Expand Up @@ -306,7 +310,9 @@ func TestMultipleRounds(t *testing.T) {

maxDepth := types.Depth(6)
startingL2BlockNumber := big.NewInt(50)
claimBuilder := faulttest.NewAlphabetClaimBuilder(t, startingL2BlockNumber, maxDepth)
nbits := uint64(1)
splitDepth := types.Depth(3)
claimBuilder := faulttest.NewAlphabetClaimBuilder2(t, startingL2BlockNumber, maxDepth, nbits, splitDepth)
builder := claimBuilder.GameBuilder(faulttest.WithInvalidValue(!rootClaimCorrect))
game := builder.Game

Expand Down
12 changes: 8 additions & 4 deletions op-challenger2/game/fault/solver/honest_claims_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import (

func TestHonestClaimTracker_RootClaim(t *testing.T) {
tracker := newHonestClaimTracker()
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(3), 4)
nBits := uint64(1)
splitDepth := types.Depth(3)
builder := test.NewAlphabetClaimBuilder2(t, big.NewInt(3), 4, nBits, splitDepth)

claim := builder.Seq().Get()
require.False(t, tracker.IsHonest(claim))
Expand All @@ -22,11 +24,13 @@ func TestHonestClaimTracker_RootClaim(t *testing.T) {

func TestHonestClaimTracker_ChildClaim(t *testing.T) {
tracker := newHonestClaimTracker()
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(3), 4)
nBits := uint64(1)
splitDepth := types.Depth(3)
builder := test.NewAlphabetClaimBuilder2(t, big.NewInt(3), 4, nBits, splitDepth)

seq := builder.Seq().Attack().Defend()
seq := builder.Seq().Attack2(nil, 0).Attack2(nil, 1)
parent := seq.Get()
child := seq.Attack().Get()
child := seq.Attack2(nil, 0).Get()
require.Zero(t, child.ContractIndex, "should work for claims that are not in the game state yet")

tracker.AddHonestClaim(parent, child)
Expand Down
60 changes: 31 additions & 29 deletions op-challenger2/game/fault/solver/solver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import (
func TestAttemptStep(t *testing.T) {
maxDepth := types.Depth(3)
startingL2BlockNumber := big.NewInt(0)
claimBuilder := faulttest.NewAlphabetClaimBuilder(t, startingL2BlockNumber, maxDepth)
nbits := uint64(1)
splitDepth := types.Depth(3)
claimBuilder := faulttest.NewAlphabetClaimBuilder2(t, startingL2BlockNumber, maxDepth, nbits, splitDepth)

// Last accessible leaf is the second last trace index
// The root node is used for the last trace index and can only be attacked.
Expand All @@ -42,9 +44,9 @@ func TestAttemptStep(t *testing.T) {
expectedOracleData: claimBuilder.CorrectOracleData(common.Big0),
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
Attack(faulttest.WithValue(common.Hash{0xaa})).
Attack().
Attack(faulttest.WithValue(common.Hash{0xbb}))
Attack2(nil, 0, faulttest.WithValue(common.Hash{0xaa})).
Attack2(nil, 0).
Attack2(nil, 0, faulttest.WithValue(common.Hash{0xbb}))
},
},
{
Expand All @@ -55,9 +57,9 @@ func TestAttemptStep(t *testing.T) {
expectedOracleData: claimBuilder.CorrectOracleData(big.NewInt(1)),
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
Attack(faulttest.WithValue(common.Hash{0xaa})).
Attack().
Attack()
Attack2(nil, 0, faulttest.WithValue(common.Hash{0xaa})).
Attack2(nil, 0).
Attack2(nil, 0)
},
},
{
Expand All @@ -68,9 +70,9 @@ func TestAttemptStep(t *testing.T) {
expectedOracleData: claimBuilder.CorrectOracleData(big.NewInt(4)),
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
Attack().
Defend().
Attack(faulttest.WithValue(common.Hash{0xaa}))
Attack2(nil, 0).
Attack2(nil, 1).
Attack2(nil, 0, faulttest.WithValue(common.Hash{0xaa}))
},
},
{
Expand All @@ -81,9 +83,9 @@ func TestAttemptStep(t *testing.T) {
expectedOracleData: claimBuilder.CorrectOracleData(big.NewInt(5)),
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
Attack().
Defend().
Attack()
Attack2(nil, 0).
Attack2(nil, 1).
Attack2(nil, 0)
},
},
{
Expand All @@ -94,9 +96,9 @@ func TestAttemptStep(t *testing.T) {
expectedOracleData: claimBuilder.CorrectOracleData(lastLeafTraceIndex),
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
Attack().
Defend().
Defend(faulttest.WithValue(common.Hash{0xaa}))
Attack2(nil, 0).
Attack2(nil, 1).
Attack2(nil, 1, faulttest.WithValue(common.Hash{0xaa}))
},
},
{
Expand All @@ -107,15 +109,15 @@ func TestAttemptStep(t *testing.T) {
expectedOracleData: claimBuilder.CorrectOracleData(lastLeafTraceIndexPlusOne),
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
Attack().
Defend().
Defend()
Attack2(nil, 0).
Attack2(nil, 1).
Attack2(nil, 1)
},
},
{
name: "CannotStepNonLeaf",
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().Attack().Attack()
builder.Seq().Attack2(nil, 0).Attack2(nil, 0)
},
expectedErr: ErrStepNonLeafNode,
agreeWithOutputRoot: true,
Expand All @@ -124,9 +126,9 @@ func TestAttemptStep(t *testing.T) {
name: "CannotStepAgreedNode",
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
Attack().
Attack(faulttest.WithValue(common.Hash{0xaa})).
Attack()
Attack2(nil, 0).
Attack2(nil, 0, faulttest.WithValue(common.Hash{0xaa})).
Attack2(nil, 0)
},
expectNoStep: true,
agreeWithOutputRoot: true,
Expand All @@ -135,9 +137,9 @@ func TestAttemptStep(t *testing.T) {
name: "CannotStepInvalidPath",
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
Attack(faulttest.WithValue(common.Hash{0xaa})).
Attack(faulttest.WithValue(common.Hash{0xbb})).
Attack(faulttest.WithValue(common.Hash{0xcc}))
Attack2(nil, 0, faulttest.WithValue(common.Hash{0xaa})).
Attack2(nil, 0, faulttest.WithValue(common.Hash{0xbb})).
Attack2(nil, 0, faulttest.WithValue(common.Hash{0xcc}))
},
expectNoStep: true,
agreeWithOutputRoot: true,
Expand All @@ -150,9 +152,9 @@ func TestAttemptStep(t *testing.T) {
expectedOracleData: claimBuilder.CorrectOracleData(big.NewInt(4)),
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
Attack().
Defend().
Defend()
Attack2(nil, 0).
Attack2(nil, 1).
Attack2(nil, 1)
},
expectNoStep: true,
agreeWithOutputRoot: true,
Expand Down
Loading