Commit 85f230ce authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

op-dispute-mon: Track left most claim when resolving games. (#9651)

* op-challenger: Use opts pattern for claim builder

* op-dispute-mon: Track left most claim when resolving games.
parent 83de09b5
package resolution package resolution
import ( import (
"math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types"
...@@ -14,9 +16,14 @@ func Resolve(tree *monTypes.BidirectionalTree) gameTypes.GameStatus { ...@@ -14,9 +16,14 @@ func Resolve(tree *monTypes.BidirectionalTree) gameTypes.GameStatus {
for i := len(tree.Claims) - 1; i >= 0; i-- { for i := len(tree.Claims) - 1; i >= 0; i-- {
claim := tree.Claims[i] claim := tree.Claims[i]
counterClaimant := claim.Claim.CounteredBy counterClaimant := claim.Claim.CounteredBy
var leftmostCounter *big.Int
for _, child := range claim.Children { for _, child := range claim.Children {
if child.Claim.CounteredBy == (common.Address{}) { if child.Claim.CounteredBy != (common.Address{}) {
continue // Ignore countered claims
}
if leftmostCounter == nil || child.Claim.Position.IndexAtDepth().Cmp(leftmostCounter) < 0 {
counterClaimant = child.Claim.Claimant counterClaimant = child.Claim.Claimant
leftmostCounter = child.Claim.Position.IndexAtDepth()
} }
} }
claim.Claim.CounteredBy = counterClaimant claim.Claim.CounteredBy = counterClaimant
......
...@@ -95,6 +95,45 @@ func TestResolver_Resolve(t *testing.T) { ...@@ -95,6 +95,45 @@ func TestResolver_Resolve(t *testing.T) {
require.Equal(t, gameTypes.GameStatusDefenderWon, status) require.Equal(t, gameTypes.GameStatusDefenderWon, status)
}) })
t.Run("UseLeftMostUncounteredClaim", func(t *testing.T) {
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 5).GameBuilder()
expectedRootCounteredBy := common.Address{0xaa}
forkPoint := builder.Seq(). // Defender winning
Attack(test.WithClaimant(expectedRootCounteredBy)). // Challenger winning
Attack() // Defender winning
// Left most child of forkPoint, but has been countered
forkPoint.
Attack(test.WithValue(common.Hash{0xaa}), test.WithClaimant(common.Address{0xbb})).
Defend()
// Uncountered child, but not leftmost
forkPoint.
Defend(test.WithValue(common.Hash{0xbb}), test.WithClaimant(common.Address{0xcc})). // Challenger winning
Defend(). // Defender winning
Defend() // Challenger winning
// Left most child that is ultimately uncountered and should be used as CounteredBy
expectedCounteredBy := common.Address{0xdd}
forkPoint.
Attack(test.WithClaimant(expectedCounteredBy)).
Defend().
Defend()
// Uncountered child,
forkPoint.
Defend(test.WithClaimant(common.Address{0xee})). // Challenger winning
Defend(). // Defender winning
Defend() // Challenger winning
tree := transform.CreateBidirectionalTree(builder.Game.Claims())
status := Resolve(tree)
// Defender won all forks
require.Equal(t, gameTypes.GameStatusChallengerWon, status)
forkPointClaim := tree.Claims[2].Claim
require.Equal(t, expectedCounteredBy, forkPointClaim.CounteredBy)
require.Equal(t, expectedRootCounteredBy, tree.Claims[0].Claim.CounteredBy)
})
t.Run("SteppedClaimed_ChallengerWon", func(t *testing.T) { t.Run("SteppedClaimed_ChallengerWon", func(t *testing.T) {
builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 4).GameBuilder() builder := test.NewAlphabetClaimBuilder(t, big.NewInt(10), 4).GameBuilder()
builder.Seq(). // Defender winning builder.Seq(). // Defender winning
......
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