Commit 83de09b5 authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

op-challenger: Use opts pattern for claim builder (#9650)

parent 3179d49f
......@@ -61,7 +61,7 @@ func TestLoadClaimsWhenGameNotResolvable(t *testing.T) {
claimBuilder := test.NewClaimBuilder(t, depth, alphabet.NewTraceProvider(big.NewInt(0), depth))
claimLoader.claims = []types.Claim{
claimBuilder.CreateRootClaim(true),
claimBuilder.CreateRootClaim(),
}
require.NoError(t, agent.Act(context.Background()))
......
......@@ -55,32 +55,32 @@ func TestCalculateNextActions(t *testing.T) {
name: "DoNotPerformDuplicateMoves",
setupGame: func(builder *faulttest.GameBuilder) {
// Expected move has already been made.
builder.Seq().AttackCorrect()
builder.Seq().Attack()
},
},
{
name: "RespondToAllClaimsAtDisagreeingLevel",
setupGame: func(builder *faulttest.GameBuilder) {
honestClaim := builder.Seq().AttackCorrect()
honestClaim.AttackCorrect().ExpectDefend()
honestClaim.DefendCorrect().ExpectDefend()
honestClaim.Attack(common.Hash{0xaa}).ExpectAttack()
honestClaim.Attack(common.Hash{0xbb}).ExpectAttack()
honestClaim.Defend(common.Hash{0xcc}).ExpectAttack()
honestClaim.Defend(common.Hash{0xdd}).ExpectAttack()
honestClaim := builder.Seq().Attack()
honestClaim.Attack().ExpectDefend()
honestClaim.Defend().ExpectDefend()
honestClaim.Attack(faulttest.WithValue(common.Hash{0xaa})).ExpectAttack()
honestClaim.Attack(faulttest.WithValue(common.Hash{0xbb})).ExpectAttack()
honestClaim.Defend(faulttest.WithValue(common.Hash{0xcc})).ExpectAttack()
honestClaim.Defend(faulttest.WithValue(common.Hash{0xdd})).ExpectAttack()
},
},
{
name: "StepAtMaxDepth",
setupGame: func(builder *faulttest.GameBuilder) {
lastHonestClaim := builder.Seq().
AttackCorrect().
AttackCorrect().
DefendCorrect().
DefendCorrect().
DefendCorrect()
lastHonestClaim.AttackCorrect().ExpectStepDefend()
lastHonestClaim.Attack(common.Hash{0xdd}).ExpectStepAttack()
Attack().
Attack().
Defend().
Defend().
Defend()
lastHonestClaim.Attack().ExpectStepDefend()
lastHonestClaim.Attack(faulttest.WithValue(common.Hash{0xdd})).ExpectStepAttack()
},
},
{
......@@ -91,23 +91,23 @@ func TestCalculateNextActions(t *testing.T) {
// Dishonest actor counters their own claims to set up a situation with an invalid prestate
// The honest actor should ignore path created by the dishonest actor, only supporting its own attack on the root claim
honestMove := builder.Seq().AttackCorrect() // This expected action is the winning move.
dishonestMove := honestMove.Attack(maliciousStateHash)
honestMove := builder.Seq().Attack() // This expected action is the winning move.
dishonestMove := honestMove.Attack(faulttest.WithValue(maliciousStateHash))
// The expected action by the honest actor
dishonestMove.ExpectAttack()
// The honest actor will ignore this poisoned path
dishonestMove.
Defend(maliciousStateHash).
Attack(maliciousStateHash)
Defend(faulttest.WithValue(maliciousStateHash)).
Attack(faulttest.WithValue(maliciousStateHash))
},
},
{
name: "Freeloader-ValidClaimAtInvalidAttackPosition",
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
AttackCorrect(). // Honest response to invalid root
DefendCorrect().ExpectDefend(). // Defender agrees at this point, we should defend
AttackCorrect().ExpectDefend() // Freeloader attacks instead of defends
Attack(). // Honest response to invalid root
Defend().ExpectDefend(). // Defender agrees at this point, we should defend
Attack().ExpectDefend() // Freeloader attacks instead of defends
},
runCondition: RunFreeloadersCountered,
},
......@@ -115,9 +115,9 @@ func TestCalculateNextActions(t *testing.T) {
name: "Freeloader-InvalidClaimAtInvalidAttackPosition",
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
AttackCorrect(). // Honest response to invalid root
DefendCorrect().ExpectDefend(). // Defender agrees at this point, we should defend
Attack(common.Hash{0xbb}).ExpectAttack() // Freeloader attacks with wrong claim instead of defends
Attack(). // Honest response to invalid root
Defend().ExpectDefend(). // Defender agrees at this point, we should defend
Attack(faulttest.WithValue(common.Hash{0xbb})).ExpectAttack() // Freeloader attacks with wrong claim instead of defends
},
runCondition: RunFreeloadersCountered,
},
......@@ -125,9 +125,9 @@ func TestCalculateNextActions(t *testing.T) {
name: "Freeloader-InvalidClaimAtValidDefensePosition",
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
AttackCorrect(). // Honest response to invalid root
DefendCorrect().ExpectDefend(). // Defender agrees at this point, we should defend
Defend(common.Hash{0xbb}).ExpectAttack() // Freeloader defends with wrong claim, we should attack
Attack(). // Honest response to invalid root
Defend().ExpectDefend(). // Defender agrees at this point, we should defend
Defend(faulttest.WithValue(common.Hash{0xbb})).ExpectAttack() // Freeloader defends with wrong claim, we should attack
},
runCondition: RunFreeloadersCountered,
},
......@@ -135,9 +135,9 @@ func TestCalculateNextActions(t *testing.T) {
name: "Freeloader-InvalidClaimAtValidAttackPosition",
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
AttackCorrect(). // Honest response to invalid root
Defend(common.Hash{0xaa}).ExpectAttack(). // Defender disagrees at this point, we should attack
Attack(common.Hash{0xbb}).ExpectAttack() // Freeloader attacks with wrong claim instead of defends
Attack(). // Honest response to invalid root
Defend(faulttest.WithValue(common.Hash{0xaa})).ExpectAttack(). // Defender disagrees at this point, we should attack
Attack(faulttest.WithValue(common.Hash{0xbb})).ExpectAttack() // Freeloader attacks with wrong claim instead of defends
},
runCondition: RunFreeloadersCountered,
},
......@@ -145,18 +145,18 @@ func TestCalculateNextActions(t *testing.T) {
name: "Freeloader-InvalidClaimAtInvalidDefensePosition",
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
AttackCorrect(). // Honest response to invalid root
Defend(common.Hash{0xaa}).ExpectAttack(). // Defender disagrees at this point, we should attack
Defend(common.Hash{0xbb}) // Freeloader defends with wrong claim but we must not respond to avoid poisoning
Attack(). // Honest response to invalid root
Defend(faulttest.WithValue(common.Hash{0xaa})).ExpectAttack(). // Defender disagrees at this point, we should attack
Defend(faulttest.WithValue(common.Hash{0xbb})) // Freeloader defends with wrong claim but we must not respond to avoid poisoning
},
},
{
name: "Freeloader-ValidClaimAtInvalidAttackPosition-RespondingToDishonestButCorrectAttack",
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
AttackCorrect(). // Honest response to invalid root
AttackCorrect().ExpectDefend(). // Defender attacks with correct value, we should defend
AttackCorrect().ExpectDefend() // Freeloader attacks with wrong claim, we should defend
Attack(). // Honest response to invalid root
Attack().ExpectDefend(). // Defender attacks with correct value, we should defend
Attack().ExpectDefend() // Freeloader attacks with wrong claim, we should defend
},
runCondition: RunFreeloadersCountered,
},
......@@ -164,10 +164,10 @@ func TestCalculateNextActions(t *testing.T) {
name: "Freeloader-DoNotCounterOwnClaim",
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
AttackCorrect(). // Honest response to invalid root
AttackCorrect().ExpectDefend(). // Defender attacks with correct value, we should defend
AttackCorrect(). // Freeloader attacks instead, we should defend
DefendCorrect() // We do defend and we shouldn't counter our own claim
Attack(). // Honest response to invalid root
Attack().ExpectDefend(). // Defender attacks with correct value, we should defend
Attack(). // Freeloader attacks instead, we should defend
Defend() // We do defend and we shouldn't counter our own claim
},
runCondition: RunFreeloadersCountered,
},
......@@ -175,11 +175,11 @@ func TestCalculateNextActions(t *testing.T) {
name: "Freeloader-ContinueDefendingAgainstFreeloader",
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq(). // invalid root
AttackCorrect(). // Honest response to invalid root
AttackCorrect().ExpectDefend(). // Defender attacks with correct value, we should defend
AttackCorrect(). // Freeloader attacks instead, we should defend
DefendCorrect(). // We do defend
Attack(common.Hash{0xaa}). // freeloader attacks our defense, we should attack
Attack(). // Honest response to invalid root
Attack().ExpectDefend(). // Defender attacks with correct value, we should defend
Attack(). // Freeloader attacks instead, we should defend
Defend(). // We do defend
Attack(faulttest.WithValue(common.Hash{0xaa})). // freeloader attacks our defense, we should attack
ExpectAttack()
},
runCondition: RunFreeloadersCountered,
......@@ -188,9 +188,9 @@ func TestCalculateNextActions(t *testing.T) {
name: "Freeloader-FreeloaderCountersRootClaim",
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
ExpectAttack(). // Honest response to invalid root
Attack(common.Hash{0xaa}). // freeloader
ExpectAttack() // Honest response to freeloader
ExpectAttack(). // Honest response to invalid root
Attack(faulttest.WithValue(common.Hash{0xaa})). // freeloader
ExpectAttack() // Honest response to freeloader
},
runCondition: RunFreeloadersCountered,
},
......@@ -210,7 +210,7 @@ func TestCalculateNextActions(t *testing.T) {
t.Skip("Freeloader countering enabled")
}
}
builder := claimBuilder.GameBuilder(test.rootClaimCorrect)
builder := claimBuilder.GameBuilder(faulttest.WithInvalidValue(!test.rootClaimCorrect))
test.setupGame(builder)
game := builder.Game
logClaims(t, game)
......
......@@ -41,9 +41,9 @@ func TestAttemptStep(t *testing.T) {
expectedOracleData: claimBuilder.CorrectOracleData(common.Big0),
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
Attack(common.Hash{0xaa}).
AttackCorrect().
Attack(common.Hash{0xbb})
Attack(faulttest.WithValue(common.Hash{0xaa})).
Attack().
Attack(faulttest.WithValue(common.Hash{0xbb}))
},
},
{
......@@ -54,9 +54,9 @@ func TestAttemptStep(t *testing.T) {
expectedOracleData: claimBuilder.CorrectOracleData(big.NewInt(1)),
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
Attack(common.Hash{0xaa}).
AttackCorrect().
AttackCorrect()
Attack(faulttest.WithValue(common.Hash{0xaa})).
Attack().
Attack()
},
},
{
......@@ -67,9 +67,9 @@ func TestAttemptStep(t *testing.T) {
expectedOracleData: claimBuilder.CorrectOracleData(big.NewInt(4)),
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
AttackCorrect().
DefendCorrect().
Attack(common.Hash{0xaa})
Attack().
Defend().
Attack(faulttest.WithValue(common.Hash{0xaa}))
},
},
{
......@@ -80,9 +80,9 @@ func TestAttemptStep(t *testing.T) {
expectedOracleData: claimBuilder.CorrectOracleData(big.NewInt(5)),
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
AttackCorrect().
DefendCorrect().
AttackCorrect()
Attack().
Defend().
Attack()
},
},
{
......@@ -93,9 +93,9 @@ func TestAttemptStep(t *testing.T) {
expectedOracleData: claimBuilder.CorrectOracleData(lastLeafTraceIndex),
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
AttackCorrect().
DefendCorrect().
Defend(common.Hash{0xaa})
Attack().
Defend().
Defend(faulttest.WithValue(common.Hash{0xaa}))
},
},
{
......@@ -106,15 +106,15 @@ func TestAttemptStep(t *testing.T) {
expectedOracleData: claimBuilder.CorrectOracleData(lastLeafTraceIndexPlusOne),
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
AttackCorrect().
DefendCorrect().
DefendCorrect()
Attack().
Defend().
Defend()
},
},
{
name: "CannotStepNonLeaf",
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().AttackCorrect().AttackCorrect()
builder.Seq().Attack().Attack()
},
expectedErr: ErrStepNonLeafNode,
agreeWithOutputRoot: true,
......@@ -123,9 +123,9 @@ func TestAttemptStep(t *testing.T) {
name: "CannotStepAgreedNode",
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
AttackCorrect().
Attack(common.Hash{0xaa}).
AttackCorrect()
Attack().
Attack(faulttest.WithValue(common.Hash{0xaa})).
Attack()
},
expectedErr: ErrStepIgnoreInvalidPath,
agreeWithOutputRoot: true,
......@@ -134,9 +134,9 @@ func TestAttemptStep(t *testing.T) {
name: "CannotStepInvalidPath",
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
Attack(common.Hash{0xaa}).
Attack(common.Hash{0xbb}).
Attack(common.Hash{0xcc})
Attack(faulttest.WithValue(common.Hash{0xaa})).
Attack(faulttest.WithValue(common.Hash{0xbb})).
Attack(faulttest.WithValue(common.Hash{0xcc}))
},
expectedErr: ErrStepIgnoreInvalidPath,
agreeWithOutputRoot: true,
......@@ -149,9 +149,9 @@ func TestAttemptStep(t *testing.T) {
expectedOracleData: claimBuilder.CorrectOracleData(big.NewInt(4)),
setupGame: func(builder *faulttest.GameBuilder) {
builder.Seq().
AttackCorrect().
DefendCorrect().
DefendCorrect()
Attack().
Defend().
Defend()
},
expectedErr: ErrStepIgnoreInvalidPath,
agreeWithOutputRoot: true,
......@@ -161,7 +161,7 @@ func TestAttemptStep(t *testing.T) {
for _, tableTest := range tests {
tableTest := tableTest
t.Run(tableTest.name, func(t *testing.T) {
builder := claimBuilder.GameBuilder(!tableTest.agreeWithOutputRoot)
builder := claimBuilder.GameBuilder(faulttest.WithInvalidValue(tableTest.agreeWithOutputRoot))
tableTest.setupGame(builder)
alphabetSolver := newClaimSolver(maxDepth, trace.NewSimpleTraceAccessor(claimBuilder.CorrectTraceProvider()))
game := builder.Game
......
......@@ -12,6 +12,55 @@ import (
var DefaultClaimant = common.Address{0x09, 0x23, 0x34, 0x45, 0x13, 0xb3}
type claimCfg struct {
value common.Hash
invalidValue bool
claimant common.Address
parentIdx int
}
func newClaimCfg(opts ...ClaimOpt) *claimCfg {
cfg := &claimCfg{}
for _, opt := range opts {
opt.Apply(cfg)
}
return cfg
}
type ClaimOpt interface {
Apply(cfg *claimCfg)
}
type claimOptFn func(cfg *claimCfg)
func (c claimOptFn) Apply(cfg *claimCfg) {
c(cfg)
}
func WithValue(value common.Hash) ClaimOpt {
return claimOptFn(func(cfg *claimCfg) {
cfg.value = value
})
}
func WithInvalidValue(invalid bool) ClaimOpt {
return claimOptFn(func(cfg *claimCfg) {
cfg.invalidValue = invalid
})
}
func WithClaimant(claimant common.Address) ClaimOpt {
return claimOptFn(func(cfg *claimCfg) {
cfg.claimant = claimant
})
}
func WithParent(claim types.Claim) ClaimOpt {
return claimOptFn(func(cfg *claimCfg) {
cfg.parentIdx = claim.ContractIndex
})
}
// ClaimBuilder is a test utility to enable creating claims in a wide range of situations
type ClaimBuilder struct {
require *require.Assertions
......@@ -67,81 +116,44 @@ func (c *ClaimBuilder) incorrectClaim(pos types.Position) common.Hash {
return common.BigToHash(pos.TraceIndex(c.maxDepth))
}
func (c *ClaimBuilder) claim(pos types.Position, correct bool) common.Hash {
if correct {
return c.CorrectClaimAtPosition(pos)
} else {
return c.incorrectClaim(pos)
}
}
func (c *ClaimBuilder) CreateRootClaim(correct bool) types.Claim {
value := c.claim(types.NewPositionFromGIndex(big.NewInt(1)), correct)
func (c *ClaimBuilder) claim(pos types.Position, opts ...ClaimOpt) types.Claim {
cfg := newClaimCfg(opts...)
claim := types.Claim{
ClaimData: types.ClaimData{
Value: value,
Position: types.NewPosition(0, common.Big0),
Position: pos,
},
Claimant: DefaultClaimant,
}
if cfg.claimant != (common.Address{}) {
claim.Claimant = cfg.claimant
}
if cfg.value != (common.Hash{}) {
claim.Value = cfg.value
} else if cfg.invalidValue {
claim.Value = c.incorrectClaim(pos)
} else {
claim.Value = c.CorrectClaimAtPosition(pos)
}
claim.ParentContractIndex = cfg.parentIdx
return claim
}
func (c *ClaimBuilder) CreateLeafClaim(traceIndex *big.Int, correct bool) types.Claim {
pos := types.NewPosition(c.maxDepth, traceIndex)
return types.Claim{
ClaimData: types.ClaimData{
Value: c.claim(pos, correct),
Position: pos,
},
Claimant: DefaultClaimant,
}
func (c *ClaimBuilder) CreateRootClaim(opts ...ClaimOpt) types.Claim {
pos := types.NewPositionFromGIndex(big.NewInt(1))
return c.claim(pos, opts...)
}
func (c *ClaimBuilder) AttackClaim(claim types.Claim, correct bool) types.Claim {
pos := claim.Position.Attack()
return types.Claim{
ClaimData: types.ClaimData{
Value: c.claim(pos, correct),
Position: pos,
},
ParentContractIndex: claim.ContractIndex,
Claimant: DefaultClaimant,
}
func (c *ClaimBuilder) CreateLeafClaim(traceIndex *big.Int, opts ...ClaimOpt) types.Claim {
pos := types.NewPosition(c.maxDepth, traceIndex)
return c.claim(pos, opts...)
}
func (c *ClaimBuilder) AttackClaimWithValue(claim types.Claim, value common.Hash) types.Claim {
func (c *ClaimBuilder) AttackClaim(claim types.Claim, opts ...ClaimOpt) types.Claim {
pos := claim.Position.Attack()
return types.Claim{
ClaimData: types.ClaimData{
Value: value,
Position: pos,
},
ParentContractIndex: claim.ContractIndex,
Claimant: DefaultClaimant,
}
return c.claim(pos, append([]ClaimOpt{WithParent(claim)}, opts...)...)
}
func (c *ClaimBuilder) DefendClaim(claim types.Claim, correct bool) types.Claim {
func (c *ClaimBuilder) DefendClaim(claim types.Claim, opts ...ClaimOpt) types.Claim {
pos := claim.Position.Defend()
return types.Claim{
ClaimData: types.ClaimData{
Value: c.claim(pos, correct),
Position: pos,
},
ParentContractIndex: claim.ContractIndex,
Claimant: DefaultClaimant,
}
}
func (c *ClaimBuilder) DefendClaimWithValue(claim types.Claim, value common.Hash) types.Claim {
pos := claim.Position.Defend()
return types.Claim{
ClaimData: types.ClaimData{
Value: value,
Position: pos,
},
ParentContractIndex: claim.ContractIndex,
Claimant: DefaultClaimant,
}
return c.claim(pos, append([]ClaimOpt{WithParent(claim)}, opts...)...)
}
......@@ -13,10 +13,10 @@ type GameBuilder struct {
ExpectedActions []types.Action
}
func (c *ClaimBuilder) GameBuilder(rootCorrect bool) *GameBuilder {
func (c *ClaimBuilder) GameBuilder(rootOpts ...ClaimOpt) *GameBuilder {
return &GameBuilder{
builder: c,
Game: types.NewGameState([]types.Claim{c.CreateRootClaim(rootCorrect)}, c.maxDepth),
Game: types.NewGameState([]types.Claim{c.CreateRootClaim(rootOpts...)}, c.maxDepth),
}
}
......@@ -46,8 +46,8 @@ func (s *GameBuilderSeq) addClaimToGame(claim *types.Claim) {
s.gameBuilder.Game = types.NewGameState(claims, s.builder.maxDepth)
}
func (s *GameBuilderSeq) AttackCorrect() *GameBuilderSeq {
claim := s.builder.AttackClaim(s.lastClaim, true)
func (s *GameBuilderSeq) Attack(opts ...ClaimOpt) *GameBuilderSeq {
claim := s.builder.AttackClaim(s.lastClaim, opts...)
s.addClaimToGame(&claim)
return &GameBuilderSeq{
gameBuilder: s.gameBuilder,
......@@ -56,8 +56,8 @@ func (s *GameBuilderSeq) AttackCorrect() *GameBuilderSeq {
}
}
func (s *GameBuilderSeq) Attack(value common.Hash) *GameBuilderSeq {
claim := s.builder.AttackClaimWithValue(s.lastClaim, value)
func (s *GameBuilderSeq) Defend(opts ...ClaimOpt) *GameBuilderSeq {
claim := s.builder.DefendClaim(s.lastClaim, opts...)
s.addClaimToGame(&claim)
return &GameBuilderSeq{
gameBuilder: s.gameBuilder,
......@@ -66,29 +66,14 @@ func (s *GameBuilderSeq) Attack(value common.Hash) *GameBuilderSeq {
}
}
func (s *GameBuilderSeq) DefendCorrect() *GameBuilderSeq {
claim := s.builder.DefendClaim(s.lastClaim, true)
s.addClaimToGame(&claim)
return &GameBuilderSeq{
gameBuilder: s.gameBuilder,
builder: s.builder,
lastClaim: claim,
func (s *GameBuilderSeq) Step(opts ...ClaimOpt) {
cfg := newClaimCfg(opts...)
claimant := DefaultClaimant
if cfg.claimant != (common.Address{}) {
claimant = cfg.claimant
}
}
func (s *GameBuilderSeq) Defend(value common.Hash) *GameBuilderSeq {
claim := s.builder.DefendClaimWithValue(s.lastClaim, value)
s.addClaimToGame(&claim)
return &GameBuilderSeq{
gameBuilder: s.gameBuilder,
builder: s.builder,
lastClaim: claim,
}
}
func (s *GameBuilderSeq) Step() {
claims := s.gameBuilder.Game.Claims()
claims[len(claims)-1].CounteredBy = DefaultClaimant
claims[len(claims)-1].CounteredBy = claimant
s.gameBuilder.Game = types.NewGameState(claims, s.builder.maxDepth)
}
......
......@@ -12,24 +12,24 @@ type SequenceBuilder struct {
// Seq starts building a claim by following a sequence of attack and defend moves from the root
// The returned SequenceBuilder can be used to add additional moves. e.g:
// claim := Seq(true).Attack(false).Attack(true).Defend(true).Get()
func (c *ClaimBuilder) Seq(rootCorrect bool) *SequenceBuilder {
claim := c.CreateRootClaim(rootCorrect)
func (c *ClaimBuilder) Seq(rootOpts ...ClaimOpt) *SequenceBuilder {
claim := c.CreateRootClaim(rootOpts...)
return &SequenceBuilder{
builder: c,
lastClaim: claim,
}
}
func (s *SequenceBuilder) Attack(correct bool) *SequenceBuilder {
claim := s.builder.AttackClaim(s.lastClaim, correct)
func (s *SequenceBuilder) Attack(opts ...ClaimOpt) *SequenceBuilder {
claim := s.builder.AttackClaim(s.lastClaim, opts...)
return &SequenceBuilder{
builder: s.builder,
lastClaim: claim,
}
}
func (s *SequenceBuilder) Defend(correct bool) *SequenceBuilder {
claim := s.builder.DefendClaim(s.lastClaim, correct)
func (s *SequenceBuilder) Defend(opts ...ClaimOpt) *SequenceBuilder {
claim := s.builder.DefendClaim(s.lastClaim, opts...)
return &SequenceBuilder{
builder: s.builder,
lastClaim: claim,
......
......@@ -147,12 +147,12 @@ func TestBottomProviderAttackingTopLeaf(t *testing.T) {
// If the ref is the leaf of the top claim, ensure we respect whether the test is setup
// to attack or defend the top leaf claim.
if ref.Depth() != splitDepth || !pos.RightOf(ref.Position) {
gameBuilder.SeqFrom(ref).AttackCorrect()
gameBuilder.SeqFrom(ref).Attack()
attackRef := latestClaim(gameBuilder)
testDescendantClaims(attackRef, attackRef.Position)
}
if ref.Depth() != splitDepth || pos.RightOf(ref.Position) {
gameBuilder.SeqFrom(ref).DefendCorrect()
gameBuilder.SeqFrom(ref).Defend()
defendRef := latestClaim(gameBuilder)
testDescendantClaims(defendRef, defendRef.Position)
}
......@@ -164,10 +164,10 @@ func TestBottomProviderAttackingTopLeaf(t *testing.T) {
func attackTopLeafGIndex8(_ *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) {
// Generate claims down to the top provider's leaf
seq := gameBuilder.Seq() // gindex 1, trace 7
seq = seq.AttackCorrect() // gindex 2, trace 3
seq = seq.AttackCorrect() // gindex 4, trace 1
seq.AttackCorrect() // gindex 8, trace 0
seq := gameBuilder.Seq() // gindex 1, trace 7
seq = seq.Attack() // gindex 2, trace 3
seq = seq.Attack() // gindex 4, trace 1
seq.Attack() // gindex 8, trace 0
expectPost = latestClaim(gameBuilder)
// No pre-claim as the first output root is being challenged.
......@@ -180,11 +180,11 @@ func attackTopLeafGIndex8(_ *testing.T, gameBuilder *test.GameBuilder) (ref type
func defendTopLeafGIndex8(_ *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) {
// Generate claims down to the top provider's leaf
seq := gameBuilder.Seq() // gindex 1, trace 7
seq = seq.AttackCorrect() // gindex 2, trace 3
seq = seq.AttackCorrect() // gindex 4, trace 1
seq := gameBuilder.Seq() // gindex 1, trace 7
seq = seq.Attack() // gindex 2, trace 3
seq = seq.Attack() // gindex 4, trace 1
expectPost = latestClaim(gameBuilder)
seq.AttackCorrect() // gindex 8, trace 0
seq.Attack() // gindex 8, trace 0
expectPre = latestClaim(gameBuilder)
ref = latestClaim(gameBuilder)
......@@ -193,11 +193,11 @@ func defendTopLeafGIndex8(_ *testing.T, gameBuilder *test.GameBuilder) (ref type
}
func attackTopLeafGIndex10(_ *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) {
seq := gameBuilder.Seq() // gindex 1, trace 7
seq = seq.AttackCorrect() // gindex 2, trace 3
seq = seq.AttackCorrect() // gindex 4, trace 1
seq := gameBuilder.Seq() // gindex 1, trace 7
seq = seq.Attack() // gindex 2, trace 3
seq = seq.Attack() // gindex 4, trace 1
expectPre = latestClaim(gameBuilder)
seq.DefendCorrect() // gindex 10, trace 2
seq.Defend() // gindex 10, trace 2
expectPost = latestClaim(gameBuilder)
ref = latestClaim(gameBuilder)
......@@ -206,11 +206,11 @@ func attackTopLeafGIndex10(_ *testing.T, gameBuilder *test.GameBuilder) (ref typ
}
func defendTopLeafGIndex10(_ *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) {
seq := gameBuilder.Seq() // gindex 1, trace 7
seq = seq.AttackCorrect() // gindex 2, trace 3
seq := gameBuilder.Seq() // gindex 1, trace 7
seq = seq.Attack() // gindex 2, trace 3
expectPost = latestClaim(gameBuilder)
seq = seq.AttackCorrect() // gindex 4, trace 1
seq.DefendCorrect() // gindex 10, trace 2
seq = seq.Attack() // gindex 4, trace 1
seq.Defend() // gindex 10, trace 2
expectPre = latestClaim(gameBuilder)
ref = latestClaim(gameBuilder)
......@@ -219,11 +219,11 @@ func defendTopLeafGIndex10(_ *testing.T, gameBuilder *test.GameBuilder) (ref typ
}
func attackTopLeafGIndex12(_ *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) {
seq := gameBuilder.Seq() // gindex 1, trace 7
seq = seq.AttackCorrect() // gindex 2, trace 3
seq := gameBuilder.Seq() // gindex 1, trace 7
seq = seq.Attack() // gindex 2, trace 3
expectPre = latestClaim(gameBuilder)
seq = seq.DefendCorrect() // gindex 6, trace 5
seq.AttackCorrect() // gindex 12, trace 4
seq = seq.Defend() // gindex 6, trace 5
seq.Attack() // gindex 12, trace 4
expectPost = latestClaim(gameBuilder)
ref = latestClaim(gameBuilder)
......@@ -232,11 +232,11 @@ func attackTopLeafGIndex12(_ *testing.T, gameBuilder *test.GameBuilder) (ref typ
}
func defendTopLeafGIndex12(_ *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) {
seq := gameBuilder.Seq() // gindex 1, trace 7
seq = seq.AttackCorrect() // gindex 2, trace 3
seq = seq.DefendCorrect() // gindex 6, trace 5
seq := gameBuilder.Seq() // gindex 1, trace 7
seq = seq.Attack() // gindex 2, trace 3
seq = seq.Defend() // gindex 6, trace 5
expectPost = latestClaim(gameBuilder)
seq.AttackCorrect() // gindex 12, trace 4
seq.Attack() // gindex 12, trace 4
expectPre = latestClaim(gameBuilder)
ref = latestClaim(gameBuilder)
......@@ -245,11 +245,11 @@ func defendTopLeafGIndex12(_ *testing.T, gameBuilder *test.GameBuilder) (ref typ
}
func attackTopLeafGIndex14(_ *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) {
seq := gameBuilder.Seq() // gindex 1, trace 7
seq = seq.AttackCorrect() // gindex 2, trace 3
seq = seq.DefendCorrect() // gindex 6, trace 5
seq := gameBuilder.Seq() // gindex 1, trace 7
seq = seq.Attack() // gindex 2, trace 3
seq = seq.Defend() // gindex 6, trace 5
expectPre = latestClaim(gameBuilder)
seq.DefendCorrect() // gindex 14, trace 6
seq.Defend() // gindex 14, trace 6
expectPost = latestClaim(gameBuilder)
ref = latestClaim(gameBuilder)
......@@ -260,9 +260,9 @@ func attackTopLeafGIndex14(_ *testing.T, gameBuilder *test.GameBuilder) (ref typ
func defendTopLeafGIndex14(_ *testing.T, gameBuilder *test.GameBuilder) (ref types.Claim, pos types.Position, expectPre types.Claim, expectPost types.Claim) {
seq := gameBuilder.Seq() // gindex 1, trace 7
expectPost = latestClaim(gameBuilder)
seq = seq.AttackCorrect() // gindex 2, trace 3
seq = seq.DefendCorrect() // gindex 6, trace 5
seq.DefendCorrect() // gindex 14, trace 6
seq = seq.Attack() // gindex 2, trace 3
seq = seq.Defend() // gindex 6, trace 5
seq.Defend() // gindex 14, trace 6
expectPre = latestClaim(gameBuilder)
ref = latestClaim(gameBuilder)
......@@ -277,7 +277,7 @@ func latestClaim(gameBuilder *test.GameBuilder) types.Claim {
func createClaimsToDepth(gameBuilder *test.GameBuilder, depth int) {
seq := gameBuilder.Seq()
for i := 0; i < depth; i++ {
seq = seq.AttackCorrect()
seq = seq.Attack()
}
}
......@@ -314,7 +314,7 @@ func setupAlphabetSplitSelector(t *testing.T) (*alphabet.AlphabetTraceProvider,
selector := NewSplitProviderSelector(top, splitDepth, bottomCreator)
claimBuilder := test.NewAlphabetClaimBuilder(t, big.NewInt(0), gameDepth)
gameBuilder := claimBuilder.GameBuilder(true)
gameBuilder := claimBuilder.GameBuilder()
return top, selector, gameBuilder
}
......
......@@ -21,7 +21,7 @@ func TestResolver_Resolve(t *testing.T) {
})
t.Run("SingleRootClaim", func(t *testing.T) {
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 4).GameBuilder(true)
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 4).GameBuilder()
tree := transform.CreateBidirectionalTree(builder.Game.Claims())
tree.Claims[0].Claim.CounteredBy = common.Address{}
status := Resolve(tree)
......@@ -29,45 +29,45 @@ func TestResolver_Resolve(t *testing.T) {
})
t.Run("ManyClaims_ChallengerWon", func(t *testing.T) {
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder(true)
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder()
builder.Seq(). // Defender winning
AttackCorrect(). // Challenger winning
AttackCorrect(). // Defender winning
DefendCorrect(). // Challenger winning
DefendCorrect(). // Defender winning
AttackCorrect() // Challenger winning
Attack(). // Challenger winning
Attack(). // Defender winning
Defend(). // Challenger winning
Defend(). // Defender winning
Attack() // Challenger winning
tree := transform.CreateBidirectionalTree(builder.Game.Claims())
status := Resolve(tree)
require.Equal(t, gameTypes.GameStatusChallengerWon, status)
})
t.Run("ManyClaims_DefenderWon", func(t *testing.T) {
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder(true)
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder()
builder.Seq(). // Defender winning
AttackCorrect(). // Challenger winning
AttackCorrect(). // Defender winning
DefendCorrect(). // Challenger winning
DefendCorrect() // Defender winning
Attack(). // Challenger winning
Attack(). // Defender winning
Defend(). // Challenger winning
Defend() // Defender winning
tree := transform.CreateBidirectionalTree(builder.Game.Claims())
status := Resolve(tree)
require.Equal(t, gameTypes.GameStatusDefenderWon, status)
})
t.Run("MultipleBranches_ChallengerWon", func(t *testing.T) {
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder(true)
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder()
forkPoint := builder.Seq(). // Defender winning
AttackCorrect(). // Challenger winning
AttackCorrect() // Defender winning
Attack(). // Challenger winning
Attack() // Defender winning
forkPoint.
DefendCorrect(). // Challenger winning
DefendCorrect(). // Defender winning
AttackCorrect() // Challenger winning
forkPoint.Defend(common.Hash{0xbb}). // Challenger winning
DefendCorrect(). // Defender winning
AttackCorrect(). // Challenger winning
Step() // Defender winning
forkPoint.Defend(common.Hash{0xcc}). // Challenger winning
DefendCorrect() // Defender winning
Defend(). // Challenger winning
Defend(). // Defender winning
Attack() // Challenger winning
forkPoint.Defend(test.WithValue(common.Hash{0xbb})). // Challenger winning
Defend(). // Defender winning
Attack(). // Challenger winning
Step() // Defender winning
forkPoint.Defend(test.WithValue(common.Hash{0xcc})). // Challenger winning
Defend() // Defender winning
tree := transform.CreateBidirectionalTree(builder.Game.Claims())
status := Resolve(tree)
// First fork has an uncountered claim with challenger winning so that invalidates the parent and wins the game
......@@ -75,19 +75,20 @@ func TestResolver_Resolve(t *testing.T) {
})
t.Run("MultipleBranches_DefenderWon", func(t *testing.T) {
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder(true)
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder()
forkPoint := builder.Seq(). // Defender winning
AttackCorrect(). // Challenger winning
AttackCorrect() // Defender winning
Attack(). // Challenger winning
Attack() // Defender winning
forkPoint.
DefendCorrect(). // Challenger winning
DefendCorrect() // Defender winning
forkPoint.Defend(common.Hash{0xbb}). // Challenger winning
DefendCorrect(). // Defender winning
AttackCorrect(). // Challenger winning
Step() // Defender winning
forkPoint.Defend(common.Hash{0xcc}). // Challenger winning
DefendCorrect() // Defender winning
Defend(). // Challenger winning
Defend() // Defender winning
forkPoint.Defend(test.WithValue(common.Hash{0xbb})). // Challenger winning
Defend(). // Defender winning
Attack(). // Challenger winning
Step() // Defender winning
forkPoint.Defend(test.WithValue(common.Hash{0xcc})). // Challenger winning
Defend() // Defender winning
tree := transform.CreateBidirectionalTree(builder.Game.Claims())
status := Resolve(tree)
// Defender won all forks
......@@ -95,13 +96,13 @@ func TestResolver_Resolve(t *testing.T) {
})
t.Run("SteppedClaimed_ChallengerWon", func(t *testing.T) {
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 4).GameBuilder(true)
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 4).GameBuilder()
builder.Seq(). // Defender winning
AttackCorrect(). // Challenger winning
AttackCorrect(). // Defender winning
DefendCorrect(). // Challenger winning
DefendCorrect(). // Defender winning
Step() // Challenger winning
Attack(). // Challenger winning
Attack(). // Defender winning
Defend(). // Challenger winning
Defend(). // Defender winning
Step() // Challenger winning
claims := builder.Game.Claims()
// Successful step so mark as countered
claims[len(claims)-1].CounteredBy = common.Address{0xaa}
......@@ -111,14 +112,14 @@ func TestResolver_Resolve(t *testing.T) {
})
t.Run("SteppedClaimed_DefenderWon", func(t *testing.T) {
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder(true)
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder()
builder.Seq(). // Defender winning
AttackCorrect(). // Challenger winning
AttackCorrect(). // Defender winning
DefendCorrect(). // Challenger winning
DefendCorrect(). // Defender winning
AttackCorrect(). // Challenger winning
Step() // Defender winning
Attack(). // Challenger winning
Attack(). // Defender winning
Defend(). // Challenger winning
Defend(). // Defender winning
Attack(). // Challenger winning
Step() // Defender winning
claims := builder.Game.Claims()
// Successful step so mark as countered
claims[len(claims)-1].CounteredBy = common.Address{0xaa}
......
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