Commit d134c7c6 authored by Adrian Sutton's avatar Adrian Sutton

op-challenger: Remove Claim.Parent

We can more easily retrieve the parent from the game when needed.
parent 8a3c8964
......@@ -100,18 +100,6 @@ func (l *loader) fetchClaim(ctx context.Context, arrIndex uint64) (types.Claim,
ParentContractIndex: int(fetchedClaim.ParentIndex),
}
if !claim.IsRootPosition() {
parentIndex := uint64(fetchedClaim.ParentIndex)
parentClaim, err := l.caller.ClaimData(&callOpts, new(big.Int).SetUint64(parentIndex))
if err != nil {
return types.Claim{}, err
}
claim.Parent = types.ClaimData{
Value: parentClaim.Claim,
Position: types.NewPositionFromGIndex(parentClaim.Position),
}
}
return claim, nil
}
......
......@@ -128,10 +128,6 @@ func TestLoader_FetchClaims(t *testing.T) {
Value: expectedClaims[1].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[1].Position),
},
Parent: types.ClaimData{
Value: expectedClaims[0].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[0].Position),
},
Countered: false,
Clock: uint64(0),
ContractIndex: 1,
......@@ -142,10 +138,6 @@ func TestLoader_FetchClaims(t *testing.T) {
Value: expectedClaims[2].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[2].Position),
},
Parent: types.ClaimData{
Value: expectedClaims[1].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[1].Position),
},
Countered: false,
Clock: uint64(0),
ContractIndex: 2,
......
......@@ -49,7 +49,7 @@ func (s *GameSolver) calculateStep(ctx context.Context, game types.Game, claim t
return nil, nil
}
step, err := s.claimSolver.AttemptStep(ctx, game, claim)
if err == ErrStepIgnoreInvalidPath {
if errors.Is(err, ErrStepIgnoreInvalidPath) {
return nil, nil
}
if err != nil {
......@@ -78,7 +78,7 @@ func (s *GameSolver) calculateMove(ctx context.Context, game types.Game, claim t
}
return &types.Action{
Type: types.ActionTypeMove,
IsAttack: !move.DefendsParent(),
IsAttack: !game.DefendsParent(*move),
ParentIdx: move.ParentContractIndex,
Value: move.Value,
}, nil
......
......@@ -134,7 +134,6 @@ func (s *claimSolver) attack(ctx context.Context, claim types.Claim) (*types.Cla
}
return &types.Claim{
ClaimData: types.ClaimData{Value: value, Position: position},
Parent: claim.ClaimData,
ParentContractIndex: claim.ContractIndex,
}, nil
}
......@@ -151,7 +150,6 @@ func (s *claimSolver) defend(ctx context.Context, claim types.Claim) (*types.Cla
}
return &types.Claim{
ClaimData: types.ClaimData{Value: value, Position: position},
Parent: claim.ClaimData,
ParentContractIndex: claim.ContractIndex,
}, nil
}
......@@ -176,12 +174,15 @@ func (s *claimSolver) agreeWithClaimPath(ctx context.Context, game types.Game, c
if !agree {
return false, nil
}
if claim.IsRoot() || claim.Parent.IsRootPosition() {
if claim.IsRoot() {
return true, nil
}
parent, err := game.GetParent(claim)
if err != nil {
return false, err
return false, fmt.Errorf("failed to get parent of claim %v: %w", claim.ContractIndex, err)
}
if parent.IsRoot() {
return true, nil
}
grandParent, err := game.GetParent(parent)
if err != nil {
......
......@@ -85,17 +85,12 @@ func (c *ClaimBuilder) CreateRootClaim(correct bool) types.Claim {
}
func (c *ClaimBuilder) CreateLeafClaim(traceIndex *big.Int, correct bool) types.Claim {
parentPos := types.NewPosition(c.maxDepth-1, common.Big0)
pos := types.NewPosition(c.maxDepth, traceIndex)
return types.Claim{
ClaimData: types.ClaimData{
Value: c.claim(pos, correct),
Position: pos,
},
Parent: types.ClaimData{
Value: c.claim(parentPos, !correct),
Position: parentPos,
},
}
}
......@@ -106,7 +101,6 @@ func (c *ClaimBuilder) AttackClaim(claim types.Claim, correct bool) types.Claim
Value: c.claim(pos, correct),
Position: pos,
},
Parent: claim.ClaimData,
ParentContractIndex: claim.ContractIndex,
}
}
......@@ -118,7 +112,6 @@ func (c *ClaimBuilder) AttackClaimWithValue(claim types.Claim, value common.Hash
Value: value,
Position: pos,
},
Parent: claim.ClaimData,
ParentContractIndex: claim.ContractIndex,
}
}
......@@ -130,7 +123,6 @@ func (c *ClaimBuilder) DefendClaim(claim types.Claim, correct bool) types.Claim
Value: c.claim(pos, correct),
Position: pos,
},
Parent: claim.ClaimData,
ParentContractIndex: claim.ContractIndex,
}
}
......@@ -142,7 +134,6 @@ func (c *ClaimBuilder) DefendClaimWithValue(claim types.Claim, value common.Hash
Value: value,
Position: pos,
},
Parent: claim.ClaimData,
ParentContractIndex: claim.ContractIndex,
}
}
......@@ -24,6 +24,10 @@ type Game interface {
// GetParent returns the parent of the provided claim.
GetParent(claim Claim) (Claim, error)
// DefendsParent returns true if and only if the claim is a defense (i.e. goes right) of
// its parent.
DefendsParent(claim Claim) bool
// IsDuplicate returns true if the provided [Claim] already exists in the game state
// referencing the same parent claim
IsDuplicate(claim Claim) bool
......@@ -102,6 +106,14 @@ func (g *gameState) GetParent(claim Claim) (Claim, error) {
return *parent, nil
}
func (g *gameState) DefendsParent(claim Claim) bool {
parent := g.getParent(claim)
if parent == nil {
return false
}
return claim.RightOf(parent.Position)
}
func (g *gameState) getParent(claim Claim) *Claim {
if claim.IsRoot() {
return nil
......
......@@ -25,7 +25,6 @@ func createTestClaims() (Claim, Claim, Claim, Claim) {
Value: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000364"),
Position: NewPosition(1, common.Big0),
},
Parent: root.ClaimData,
ContractIndex: 1,
ParentContractIndex: 0,
}
......@@ -34,7 +33,6 @@ func createTestClaims() (Claim, Claim, Claim, Claim) {
Value: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000578"),
Position: NewPosition(2, big.NewInt(2)),
},
Parent: top.ClaimData,
ContractIndex: 2,
ParentContractIndex: 1,
}
......@@ -44,7 +42,6 @@ func createTestClaims() (Claim, Claim, Claim, Claim) {
Value: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000465"),
Position: NewPosition(3, big.NewInt(4)),
},
Parent: middle.ClaimData,
ContractIndex: 3,
ParentContractIndex: 2,
}
......@@ -75,3 +72,78 @@ func TestGame_Claims(t *testing.T) {
actual := g.Claims()
require.ElementsMatch(t, expected, actual)
}
func TestGame_DefendsParent(t *testing.T) {
tests := []struct {
name string
game *gameState
expected bool
}{
{
name: "LeftChildAttacks",
game: buildGameWithClaim(big.NewInt(2), big.NewInt(1)),
expected: false,
},
{
name: "RightChildDoesntDefend",
game: buildGameWithClaim(big.NewInt(3), big.NewInt(1)),
expected: false,
},
{
name: "SubChildDoesntDefend",
game: buildGameWithClaim(big.NewInt(4), big.NewInt(1)),
expected: false,
},
{
name: "SubSecondChildDoesntDefend",
game: buildGameWithClaim(big.NewInt(5), big.NewInt(1)),
expected: false,
},
{
name: "RightLeftChildDefendsParent",
game: buildGameWithClaim(big.NewInt(6), big.NewInt(1)),
expected: true,
},
{
name: "SubThirdChildDefends",
game: buildGameWithClaim(big.NewInt(7), big.NewInt(1)),
expected: true,
},
{
name: "RootDoesntDefend",
game: NewGameState(false, []Claim{
{
ClaimData: ClaimData{
Position: NewPositionFromGIndex(big.NewInt(0)),
},
ContractIndex: 0,
},
}, testMaxDepth),
expected: false,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
claims := test.game.Claims()
require.Equal(t, test.expected, test.game.DefendsParent(claims[len(claims)-1]))
})
}
}
func buildGameWithClaim(claimGIndex *big.Int, parentGIndex *big.Int) *gameState {
parentClaim := Claim{
ClaimData: ClaimData{
Position: NewPositionFromGIndex(parentGIndex),
},
ContractIndex: 0,
}
claim := Claim{
ClaimData: ClaimData{
Position: NewPositionFromGIndex(claimGIndex),
},
ContractIndex: 1,
ParentContractIndex: 0,
}
return NewGameState(false, []Claim{parentClaim, claim}, testMaxDepth)
}
......@@ -104,7 +104,6 @@ type Claim struct {
// to be changed/removed to avoid invalid/stale contract state.
Countered bool
Clock uint64
Parent ClaimData
// Location of the claim & it's parent inside the contract. Does not exist
// for claims that have not made it to the contract.
ContractIndex int
......@@ -115,9 +114,3 @@ type Claim struct {
func (c *Claim) IsRoot() bool {
return c.Position.IsRootPosition()
}
// DefendsParent returns true if the the claim is a defense (i.e. goes right) of the
// parent. It returns false if the claim is an attack (i.e. goes left) of the parent.
func (c *Claim) DefendsParent() bool {
return c.RightOf(c.Parent.Position)
}
......@@ -54,59 +54,3 @@ func TestIsRootPosition(t *testing.T) {
})
}
}
func buildClaim(gindex *big.Int, parentGIndex *big.Int) Claim {
return Claim{
ClaimData: ClaimData{
Position: NewPositionFromGIndex(gindex),
},
Parent: ClaimData{
Position: NewPositionFromGIndex(parentGIndex),
},
}
}
func TestDefendsParent(t *testing.T) {
tests := []struct {
name string
claim Claim
expected bool
}{
{
name: "LeftChildAttacks",
claim: buildClaim(big.NewInt(2), big.NewInt(1)),
expected: false,
},
{
name: "RightChildDoesntDefend",
claim: buildClaim(big.NewInt(3), big.NewInt(1)),
expected: false,
},
{
name: "SubChildDoesntDefend",
claim: buildClaim(big.NewInt(4), big.NewInt(1)),
expected: false,
},
{
name: "SubSecondChildDoesntDefend",
claim: buildClaim(big.NewInt(5), big.NewInt(1)),
expected: false,
},
{
name: "RightLeftChildDefendsParent",
claim: buildClaim(big.NewInt(6), big.NewInt(1)),
expected: true,
},
{
name: "SubThirdChildDefends",
claim: buildClaim(big.NewInt(7), big.NewInt(1)),
expected: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
require.Equal(t, test.expected, test.claim.DefendsParent())
})
}
}
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