Commit 16190071 authored by OptimismBot's avatar OptimismBot Committed by GitHub

Merge pull request #6289 from ethereum-optimism/jg/only_respond_to_levels_we_disagree_with

op-challenger: Only respond to claims at levels we disagree with
parents 051aa24d 139acfbf
...@@ -14,4 +14,4 @@ MALLORY_KEY="28d7045146193f5f4eeb151c4843544b1b0d30a7ac1680c845a416fac65a7715" ...@@ -14,4 +14,4 @@ MALLORY_KEY="28d7045146193f5f4eeb151c4843544b1b0d30a7ac1680c845a416fac65a7715"
FAULT_GAME_ADDRESS="0x8daf17a20c9dba35f005b6324f493785d239719d" FAULT_GAME_ADDRESS="0x8daf17a20c9dba35f005b6324f493785d239719d"
./bin/op-challenger --l1-eth-rpc http://localhost:8545 --alphabet "abcdefgh" --game-address $FAULT_GAME_ADDRESS --private-key $CHARLIE_KEY --num-confirmations 1 ./bin/op-challenger --l1-eth-rpc http://localhost:8545 --alphabet "abcdefgh" --game-address $FAULT_GAME_ADDRESS --private-key $CHARLIE_KEY --num-confirmations 1 --agree-with-proposed-output=true
...@@ -70,7 +70,7 @@ func (a *Agent) newGameFromContracts(ctx context.Context) (Game, error) { ...@@ -70,7 +70,7 @@ func (a *Agent) newGameFromContracts(ctx context.Context) (Game, error) {
// move determines & executes the next move given a claim // move determines & executes the next move given a claim
func (a *Agent) move(claim Claim, game Game) error { func (a *Agent) move(claim Claim, game Game) error {
nextMove, err := a.solver.NextMove(claim) nextMove, err := a.solver.NextMove(claim, game.AgreeWithClaimLevel(claim))
if err != nil { if err != nil {
a.log.Warn("Failed to execute the next move", "err", err) a.log.Warn("Failed to execute the next move", "err", err)
return err return err
......
...@@ -53,19 +53,19 @@ func SolverExampleOne() { ...@@ -53,19 +53,19 @@ func SolverExampleOne() {
fmt.Println() fmt.Println()
PrettyPrintAlphabetClaim("Root claim", root) PrettyPrintAlphabetClaim("Root claim", root)
claim1, err := cannonicalSolver.NextMove(root) claim1, err := cannonicalSolver.NextMove(root, false)
if err != nil { if err != nil {
fmt.Printf("error getting claim from provider: %v", err) fmt.Printf("error getting claim from provider: %v", err)
} }
PrettyPrintAlphabetClaim("Cannonical move", *claim1) PrettyPrintAlphabetClaim("Cannonical move", *claim1)
claim2, err := disputedSolver.NextMove(*claim1) claim2, err := disputedSolver.NextMove(*claim1, false)
if err != nil { if err != nil {
fmt.Printf("error getting claim from provider: %v", err) fmt.Printf("error getting claim from provider: %v", err)
} }
PrettyPrintAlphabetClaim("Disputed moved", *claim2) PrettyPrintAlphabetClaim("Disputed moved", *claim2)
claim3, err := cannonicalSolver.NextMove(*claim2) claim3, err := cannonicalSolver.NextMove(*claim2, false)
if err != nil { if err != nil {
fmt.Printf("error getting claim from provider: %v", err) fmt.Printf("error getting claim from provider: %v", err)
} }
......
...@@ -33,6 +33,9 @@ type Game interface { ...@@ -33,6 +33,9 @@ type Game interface {
// PostStateClaim gets the claim which commits to the post-state of this specific claim. // PostStateClaim gets the claim which commits to the post-state of this specific claim.
// This will return an error if it is called with a non-leaf claim. // This will return an error if it is called with a non-leaf claim.
PostStateClaim(claim Claim) (Claim, error) PostStateClaim(claim Claim) (Claim, error)
// AgreeWithLevel returns if the game state agrees with the provided claim level.
AgreeWithClaimLevel(claim Claim) bool
} }
type extendedClaim struct { type extendedClaim struct {
......
...@@ -21,7 +21,11 @@ func NewSolver(gameDepth int, traceProvider TraceProvider) *Solver { ...@@ -21,7 +21,11 @@ func NewSolver(gameDepth int, traceProvider TraceProvider) *Solver {
} }
// NextMove returns the next move to make given the current state of the game. // NextMove returns the next move to make given the current state of the game.
func (s *Solver) NextMove(claim Claim) (*Claim, error) { func (s *Solver) NextMove(claim Claim, agreeWithClaimLevel bool) (*Claim, error) {
if agreeWithClaimLevel {
return nil, nil
}
// Special case of the root claim // Special case of the root claim
if claim.IsRoot() { if claim.IsRoot() {
return s.handleRoot(claim) return s.handleRoot(claim)
...@@ -29,6 +33,36 @@ func (s *Solver) NextMove(claim Claim) (*Claim, error) { ...@@ -29,6 +33,36 @@ func (s *Solver) NextMove(claim Claim) (*Claim, error) {
return s.handleMiddle(claim) return s.handleMiddle(claim)
} }
func (s *Solver) handleRoot(claim Claim) (*Claim, error) {
agree, err := s.agreeWithClaim(claim.ClaimData)
if err != nil {
return nil, err
}
// Attack the root claim if we do not agree with it
// Note: We always disagree with the claim level at this point,
// so if we agree with claim maybe we should also attack?
if !agree {
return s.attack(claim)
} else {
return nil, nil
}
}
func (s *Solver) handleMiddle(claim Claim) (*Claim, error) {
claimCorrect, err := s.agreeWithClaim(claim.ClaimData)
if err != nil {
return nil, err
}
if claim.Depth() == s.gameDepth {
return nil, errors.New("game depth reached")
}
if claimCorrect {
return s.defend(claim)
} else {
return s.attack(claim)
}
}
type StepData struct { type StepData struct {
LeafClaim Claim LeafClaim Claim
IsAttack bool IsAttack bool
...@@ -57,52 +91,6 @@ func (s *Solver) AttemptStep(claim Claim) (StepData, error) { ...@@ -57,52 +91,6 @@ func (s *Solver) AttemptStep(claim Claim) (StepData, error) {
}, nil }, nil
} }
func (s *Solver) handleRoot(claim Claim) (*Claim, error) {
agree, err := s.agreeWithClaim(claim.ClaimData)
if err != nil {
return nil, err
}
// Attack the root claim if we do not agree with it
if !agree {
return s.attack(claim)
} else {
return nil, nil
}
}
func (s *Solver) handleMiddle(claim Claim) (*Claim, error) {
parentCorrect, err := s.agreeWithClaim(claim.Parent)
if err != nil {
return nil, err
}
claimCorrect, err := s.agreeWithClaim(claim.ClaimData)
if err != nil {
return nil, err
}
if claim.Depth() == s.gameDepth {
return nil, errors.New("game depth reached")
}
if parentCorrect && claimCorrect {
// We agree with the parent, but the claim is disagreeing with it.
// Since we agree with the claim, the difference must be to the right of the claim
return s.defend(claim)
} else if parentCorrect && !claimCorrect {
// We agree with the parent, but the claim disagrees with it.
// Since we disagree with the claim, the difference must be to the left of the claim
return s.attack(claim)
} else if !parentCorrect && claimCorrect {
// Do nothing, we disagree with the parent, but this claim has correctly countered it
return nil, nil
} else if !parentCorrect && !claimCorrect {
// We disagree with the parent so want to counter it (which the claim is doing)
// but we also disagree with the claim so there must be a difference to the left of claim
// Note that we will create the correct counter-claim for parent when it is evaluated, no need to do it here
return s.attack(claim)
}
// This should not be reached
return nil, errors.New("no next move")
}
// attack returns a response that attacks the claim. // attack returns a response that attacks the claim.
func (s *Solver) attack(claim Claim) (*Claim, error) { func (s *Solver) attack(claim Claim) (*Claim, error) {
position := claim.Attack() position := claim.Attack()
......
...@@ -74,12 +74,30 @@ func TestSolver_NextMove_Opponent(t *testing.T) { ...@@ -74,12 +74,30 @@ func TestSolver_NextMove_Opponent(t *testing.T) {
} }
for _, test := range indices { for _, test := range indices {
res, err := solver.NextMove(test.claim) res, err := solver.NextMove(test.claim, false)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, test.response, res.ClaimData) require.Equal(t, test.response, res.ClaimData)
} }
} }
func TestNoMoveAgainstOwnLevel(t *testing.T) {
maxDepth := 3
mallory := NewAlphabetProvider("abcdepqr", uint64(maxDepth))
solver := NewSolver(maxDepth, mallory)
claim := Claim{
ClaimData: ClaimData{
Value: alphabetClaim(7, "z"),
Position: NewPosition(0, 0),
},
// Root claim has no parent
}
move, err := solver.NextMove(claim, true)
require.Nil(t, move)
require.Nil(t, err)
}
func TestAttemptStep(t *testing.T) { func TestAttemptStep(t *testing.T) {
maxDepth := 3 maxDepth := 3
canonicalProvider := NewAlphabetProvider("abcdefgh", uint64(maxDepth)) canonicalProvider := NewAlphabetProvider("abcdefgh", uint64(maxDepth))
......
...@@ -15,4 +15,4 @@ MALLORY_KEY="28d7045146193f5f4eeb151c4843544b1b0d30a7ac1680c845a416fac65a7715" ...@@ -15,4 +15,4 @@ MALLORY_KEY="28d7045146193f5f4eeb151c4843544b1b0d30a7ac1680c845a416fac65a7715"
FAULT_GAME_ADDRESS="0x8daf17a20c9dba35f005b6324f493785d239719d" FAULT_GAME_ADDRESS="0x8daf17a20c9dba35f005b6324f493785d239719d"
./bin/op-challenger --l1-eth-rpc http://localhost:8545 --alphabet "abcdexyz" --game-address $FAULT_GAME_ADDRESS --private-key $MALLORY_KEY --num-confirmations 1 ./bin/op-challenger --l1-eth-rpc http://localhost:8545 --alphabet "abcdexyz" --game-address $FAULT_GAME_ADDRESS --private-key $MALLORY_KEY --num-confirmations 1 --agree-with-proposed-output=false
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