Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
a6cd52cc
Unverified
Commit
a6cd52cc
authored
Jun 26, 2023
by
OptimismBot
Committed by
GitHub
Jun 26, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #6149 from ethereum-optimism/jg/updates_types
op-challenger: Update Claim types
parents
e3300c42
1f35cabc
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
110 additions
and
88 deletions
+110
-88
solver.go
op-challenger/fault/cmd/examples/solver.go
+40
-44
position.go
op-challenger/fault/position.go
+4
-0
solver.go
op-challenger/fault/solver.go
+20
-16
solver_test.go
op-challenger/fault/solver_test.go
+25
-22
types.go
op-challenger/fault/types.go
+21
-6
No files found.
op-challenger/fault/cmd/examples/solver.go
View file @
a6cd52cc
...
...
@@ -8,76 +8,72 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/fault"
)
func
PrettyPrintAlphabetClaim
(
name
string
,
claim
fault
.
Claim
)
{
value
:=
claim
.
Value
idx
:=
value
[
30
]
letter
:=
value
[
31
]
if
claim
.
IsRoot
()
{
fmt
.
Printf
(
"%s
\t
trace %v letter %c
\n
"
,
name
,
idx
,
letter
)
}
else
{
fmt
.
Printf
(
"%s
\t
trace %v letter %c is attack %v
\n
"
,
name
,
idx
,
letter
,
!
claim
.
DefendsParent
())
}
}
// SolverExampleOne uses the [fault.Solver] with a [fault.AlphabetProvider]
// to print out fault game traces for the "abcdexyz" counter-state.
func
SolverExampleOne
()
{
fmt
.
Println
()
fmt
.
Println
(
"Solver: Example 1"
)
fmt
.
Println
()
// Construct the fault position.
canonical
:=
"abcdefgh"
disputed
:=
"abcdexyz"
maxDepth
:=
3
parent
:=
fault
.
Claim
{
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000768"
),
Position
:
fault
.
NewPosition
(
0
,
0
),
// Root claim is z at trace index 7 from the disputed provider
root
:=
fault
.
Claim
{
ClaimData
:
fault
.
ClaimData
{
Value
:
common
.
HexToHash
(
"0x000000000000000000000000000000000000000000000000000000000000077a"
),
Position
:
fault
.
NewPosition
(
0
,
0
),
},
}
// Note: We have to create the first counter claim seperately because next move does not know how to counter
// the root claim at this time.
// Counter claim is d at trace index 3 from the canonical provider
counter
:=
fault
.
Claim
{
ClaimData
:
fault
.
ClaimData
{
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000364"
),
Position
:
fault
.
NewPosition
(
1
,
0
),
},
Parent
:
root
.
ClaimData
,
}
canonicalProvider
:=
fault
.
NewAlphabetProvider
(
canonical
,
uint64
(
maxDepth
))
disputedProvider
:=
fault
.
NewAlphabetProvider
(
disputed
,
uint64
(
maxDepth
))
// Create a solver with the canonical provider.
solver
:=
fault
.
NewSolver
(
maxDepth
,
canonicalProvider
)
cannonicalSolver
:=
fault
.
NewSolver
(
maxDepth
,
canonicalProvider
)
disputedSolver
:=
fault
.
NewSolver
(
maxDepth
,
disputedProvider
)
// Print the initial state.
fmt
.
Println
(
"Canonical state: "
,
canonical
)
fmt
.
Println
(
"Disputed state: "
,
disputed
)
fmt
.
Println
(
"Disputed state:
"
,
disputed
)
fmt
.
Println
()
fmt
.
Println
(
"Proceeding with the following moves:"
)
fmt
.
Println
(
"go left to d, then right to
f
, then left to e"
)
fmt
.
Println
(
"go left to d, then right to
x (cannonical is f)
, then left to e"
)
fmt
.
Println
()
PrettyPrintAlphabetClaim
(
"Root claim"
,
root
)
PrettyPrintAlphabetClaim
(
"Counter claim"
,
counter
)
// Get the claim from the disputed provider.
claim
,
err
:=
disputedProvider
.
Get
(
3
)
claim1
,
err
:=
disputedSolver
.
NextMove
(
counter
)
if
err
!=
nil
{
fmt
.
Printf
(
"error getting claim from disputed provider: %v"
,
err
)
}
firstDisputedClaim
:=
fault
.
Claim
{
Value
:
claim
,
Position
:
fault
.
NewPosition
(
1
,
0
),
}
res
,
err
:=
solver
.
NextMove
(
firstDisputedClaim
,
parent
)
if
err
!=
nil
{
fmt
.
Printf
(
"error getting next move: %v"
,
err
)
}
fmt
.
Printf
(
"Disputed claim: %s
\n
"
,
claim
)
fmt
.
Printf
(
"Expected claim: %s
\n
"
,
parent
.
Value
)
fmt
.
Printf
(
"Response: [Attack: %v, Value: %s]
\n
"
,
res
.
Attack
,
res
.
Value
)
fmt
.
Println
()
PrettyPrintAlphabetClaim
(
"Disputed moved"
,
*
claim1
)
// Get the next claim from the disputed provider.
claim
,
err
=
disputedProvider
.
Get
(
5
)
claim2
,
err
:=
cannonicalSolver
.
NextMove
(
*
claim1
)
if
err
!=
nil
{
fmt
.
Printf
(
"error getting claim from disputed provider: %v"
,
err
)
}
firstDisputedClaim
=
fault
.
Claim
{
Value
:
claim
,
Position
:
fault
.
NewPosition
(
2
,
2
),
}
res
,
err
=
solver
.
NextMove
(
firstDisputedClaim
,
parent
)
if
err
!=
nil
{
fmt
.
Printf
(
"error getting next move: %v"
,
err
)
}
fmt
.
Printf
(
"Disputed claim: %s
\n
"
,
claim
)
fmt
.
Printf
(
"Expected claim: %s
\n
"
,
parent
.
Value
)
fmt
.
Printf
(
"Response: [Attack: %v, Value: %s]
\n
"
,
res
.
Attack
,
res
.
Value
)
fmt
.
Println
()
// This marks the end of the game!
if
res
.
Attack
{
fmt
.
Println
(
"Game successfully completed!"
)
}
else
{
fmt
.
Println
(
"Game failed!"
)
}
fmt
.
Println
()
PrettyPrintAlphabetClaim
(
"Cannonical move"
,
*
claim2
)
}
op-challenger/fault/position.go
View file @
a6cd52cc
...
...
@@ -26,6 +26,10 @@ func (p *Position) IndexAtDepth() int {
return
p
.
indexAtDepth
}
func
(
p
*
Position
)
IsRootPosition
()
bool
{
return
p
.
depth
==
0
&&
p
.
indexAtDepth
==
0
}
// TraceIndex calculates the what the index of the claim value would be inside the trace.
// It is equivalent to going right until the final depth has been reached.
func
(
p
*
Position
)
TraceIndex
(
maxDepth
int
)
uint64
{
...
...
op-challenger/fault/solver.go
View file @
a6cd52cc
...
...
@@ -22,12 +22,12 @@ func NewSolver(gameDepth int, traceProvider TraceProvider) *Solver {
}
// NextMove returns the next move to make given the current state of the game.
func
(
s
*
Solver
)
NextMove
(
claim
Claim
,
parent
Claim
)
(
*
Response
,
error
)
{
parentCorrect
,
err
:=
s
.
agreeWithClaim
(
p
arent
)
func
(
s
*
Solver
)
NextMove
(
claim
Claim
)
(
*
Claim
,
error
)
{
parentCorrect
,
err
:=
s
.
agreeWithClaim
(
claim
.
P
arent
)
if
err
!=
nil
{
return
nil
,
err
}
claimCorrect
,
err
:=
s
.
agreeWithClaim
(
claim
)
claimCorrect
,
err
:=
s
.
agreeWithClaim
(
claim
.
ClaimData
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -41,7 +41,7 @@ func (s *Solver) NextMove(claim Claim, parent Claim) (*Response, error) {
return
s
.
attack
(
claim
)
}
else
if
!
parentCorrect
&&
claimCorrect
{
// Do nothing, we disagree with the parent, but this claim has correctly countered it
return
s
.
doNothing
()
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
...
...
@@ -52,30 +52,34 @@ func (s *Solver) NextMove(claim Claim, parent Claim) (*Response, error) {
return
nil
,
errors
.
New
(
"no next move"
)
}
func
(
s
*
Solver
)
doNothing
()
(
*
Response
,
error
)
{
return
nil
,
nil
}
// attack returns a response that attacks the claim.
func
(
s
*
Solver
)
attack
(
claim
Claim
)
(
*
Response
,
error
)
{
value
,
err
:=
s
.
traceAtPosition
(
claim
.
Attack
())
func
(
s
*
Solver
)
attack
(
claim
Claim
)
(
*
Claim
,
error
)
{
position
:=
claim
.
Attack
()
value
,
err
:=
s
.
traceAtPosition
(
position
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
Response
{
Attack
:
true
,
Value
:
value
},
nil
return
&
Claim
{
ClaimData
:
ClaimData
{
Value
:
value
,
Position
:
position
},
Parent
:
claim
.
ClaimData
,
},
nil
}
// defend returns a response that defends the claim.
func
(
s
*
Solver
)
defend
(
claim
Claim
)
(
*
Response
,
error
)
{
value
,
err
:=
s
.
traceAtPosition
(
claim
.
Defend
())
func
(
s
*
Solver
)
defend
(
claim
Claim
)
(
*
Claim
,
error
)
{
position
:=
claim
.
Defend
()
value
,
err
:=
s
.
traceAtPosition
(
position
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
Response
{
Attack
:
false
,
Value
:
value
},
nil
return
&
Claim
{
ClaimData
:
ClaimData
{
Value
:
value
,
Position
:
position
},
Parent
:
claim
.
ClaimData
,
},
nil
}
// agreeWithClaim returns true if the
[Claim]
is correct according to the internal [TraceProvider].
func
(
s
*
Solver
)
agreeWithClaim
(
claim
Claim
)
(
bool
,
error
)
{
// agreeWithClaim returns true if the
claim
is correct according to the internal [TraceProvider].
func
(
s
*
Solver
)
agreeWithClaim
(
claim
Claim
Data
)
(
bool
,
error
)
{
ourValue
,
err
:=
s
.
traceAtPosition
(
claim
.
Position
)
return
ourValue
==
claim
.
Value
,
err
}
...
...
op-challenger/fault/solver_test.go
View file @
a6cd52cc
...
...
@@ -20,44 +20,47 @@ func TestSolver_NextMove_Opponent(t *testing.T) {
indices
:=
[]
struct
{
traceIndex
int
claim
Claim
parent
Claim
response
*
Response
response
ClaimData
}{
{
3
,
Claim
{
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000364"
),
Position
:
NewPosition
(
1
,
0
),
ClaimData
:
ClaimData
{
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000364"
),
Position
:
NewPosition
(
1
,
0
),
},
Parent
:
ClaimData
{
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000768"
),
Position
:
NewPosition
(
0
,
0
),
},
},
Claim
{
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000768"
),
Position
:
NewPosition
(
0
,
0
),
},
&
Response
{
Attack
:
false
,
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000566"
),
ClaimData
{
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000566"
),
Position
:
NewPosition
(
2
,
2
),
},
},
{
5
,
Claim
{
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000578"
),
Position
:
NewPosition
(
2
,
2
),
},
Claim
{
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000768"
),
Position
:
NewPosition
(
1
,
1
),
ClaimData
:
ClaimData
{
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000578"
),
Position
:
NewPosition
(
2
,
2
),
},
Parent
:
ClaimData
{
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000768"
),
Position
:
NewPosition
(
1
,
1
),
},
},
&
Response
{
Attack
:
true
,
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000465"
),
ClaimData
{
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000465"
)
,
Position
:
NewPosition
(
3
,
4
),
},
},
}
for
_
,
test
:=
range
indices
{
res
,
err
:=
solver
.
NextMove
(
test
.
claim
,
test
.
parent
)
res
,
err
:=
solver
.
NextMove
(
test
.
claim
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
test
.
response
,
res
)
require
.
Equal
(
t
,
test
.
response
,
res
.
ClaimData
)
}
}
op-challenger/fault/types.go
View file @
a6cd52cc
...
...
@@ -19,19 +19,34 @@ type TraceProvider interface {
Get
(
i
uint64
)
(
common
.
Hash
,
error
)
}
type
Claim
struct
{
// ClaimData is the core of a claim. It must be unique inside a specific game.
type
ClaimData
struct
{
Value
common
.
Hash
Position
}
type
Response
struct
{
Attack
bool
// note: can we flip this to true == going right / defending??
Value
common
.
Hash
Parent
Claim
// Claim extends ClaimData with information about the relationship between two claims.
// It uses ClaimData to break cyclicity without using pointers.
// If the position of the game is Depth 0, IndexAtDepth 0 it is the root claim
// and the Parent field is empty & meaningless.
type
Claim
struct
{
ClaimData
Parent
ClaimData
}
// IsRoot returns true if this claim is the root claim.
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
.
IndexAtDepth
()
>>
1
)
!=
c
.
Parent
.
IndexAtDepth
()
}
// Responder takes a response action & executes.
// For full op-challenger this means executing the transaction on chain.
type
Responder
interface
{
Respond
(
ctx
context
.
Context
,
response
Response
)
error
Respond
(
ctx
context
.
Context
,
response
Claim
)
error
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment