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
6eb98a75
Unverified
Commit
6eb98a75
authored
Sep 27, 2023
by
OptimismBot
Committed by
GitHub
Sep 27, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #7185 from ethereum-optimism/refcell/position-tp-port
feat(op-challenger): Trace Provider Position Type Port
parents
9223f920
63d34acb
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
151 additions
and
97 deletions
+151
-97
player.go
op-challenger/game/fault/player.go
+1
-1
player_test.go
op-challenger/game/fault/player_test.go
+2
-2
solver.go
op-challenger/game/fault/solver/solver.go
+5
-9
alphabet.go
op-challenger/game/fault/test/alphabet.go
+6
-3
claim_builder.go
op-challenger/game/fault/test/claim_builder.go
+17
-21
provider.go
op-challenger/game/fault/trace/alphabet/provider.go
+13
-9
provider_test.go
op-challenger/game/fault/trace/alphabet/provider_test.go
+27
-15
provider.go
op-challenger/game/fault/trace/cannon/provider.go
+13
-7
provider_test.go
op-challenger/game/fault/trace/cannon/provider_test.go
+16
-11
position.go
op-challenger/game/fault/types/position.go
+7
-0
types.go
op-challenger/game/fault/types/types.go
+2
-2
cannon_helper.go
op-e2e/e2eutils/disputegame/cannon_helper.go
+2
-1
game_helper.go
op-e2e/e2eutils/disputegame/game_helper.go
+5
-0
helper.go
op-e2e/e2eutils/disputegame/helper.go
+27
-4
honest_helper.go
op-e2e/e2eutils/disputegame/honest_helper.go
+8
-12
No files found.
op-challenger/game/fault/player.go
View file @
6eb98a75
...
...
@@ -80,7 +80,7 @@ func NewGamePlayer(
var
updater
types
.
OracleUpdater
switch
cfg
.
TraceType
{
case
config
.
TraceTypeCannon
:
cannonProvider
,
err
:=
cannon
.
NewTraceProvider
(
ctx
,
logger
,
m
,
cfg
,
client
,
dir
,
addr
)
cannonProvider
,
err
:=
cannon
.
NewTraceProvider
(
ctx
,
logger
,
m
,
cfg
,
client
,
dir
,
addr
,
gameDepth
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"create cannon trace provider: %w"
,
err
)
}
...
...
op-challenger/game/fault/player_test.go
View file @
6eb98a75
...
...
@@ -200,10 +200,10 @@ func newMockTraceProvider(prestateErrors bool, prestate []byte) *mockTraceProvid
prestate
:
prestate
,
}
}
func
(
m
*
mockTraceProvider
)
Get
(
ctx
context
.
Context
,
i
uint64
)
(
common
.
Hash
,
error
)
{
func
(
m
*
mockTraceProvider
)
Get
(
ctx
context
.
Context
,
i
types
.
Position
)
(
common
.
Hash
,
error
)
{
panic
(
"not implemented"
)
}
func
(
m
*
mockTraceProvider
)
GetStepData
(
ctx
context
.
Context
,
i
uint64
)
(
prestate
[]
byte
,
proofData
[]
byte
,
preimageData
*
types
.
PreimageOracleData
,
err
error
)
{
func
(
m
*
mockTraceProvider
)
GetStepData
(
ctx
context
.
Context
,
i
types
.
Position
)
(
prestate
[]
byte
,
proofData
[]
byte
,
preimageData
*
types
.
PreimageOracleData
,
err
error
)
{
panic
(
"not implemented"
)
}
func
(
m
*
mockTraceProvider
)
AbsolutePreState
(
ctx
context
.
Context
)
([]
byte
,
error
)
{
...
...
op-challenger/game/fault/solver/solver.go
View file @
6eb98a75
...
...
@@ -97,22 +97,20 @@ func (s *claimSolver) AttemptStep(ctx context.Context, game types.Game, claim ty
if
err
!=
nil
{
return
StepData
{},
err
}
index
:=
claim
.
TraceIndex
(
s
.
gameDepth
)
var
preState
[]
byte
var
proofData
[]
byte
var
oracleData
*
types
.
PreimageOracleData
if
!
claimCorrect
{
// Attack the claim by executing step index, so we need to get the pre-state of that index
preState
,
proofData
,
oracleData
,
err
=
s
.
trace
.
GetStepData
(
ctx
,
index
)
preState
,
proofData
,
oracleData
,
err
=
s
.
trace
.
GetStepData
(
ctx
,
claim
.
Position
)
if
err
!=
nil
{
return
StepData
{},
err
}
}
else
{
// We agree with the claim so Defend and use this claim as the starting point to execute the step after
// Thus we need the pre-state of the next step
// Note: This makes our maximum depth 63 because we need to add 1 without overflowing.
preState
,
proofData
,
oracleData
,
err
=
s
.
trace
.
GetStepData
(
ctx
,
index
+
1
)
// We agree with the claim so Defend and use this claim as the starting point to
// execute the step after. Thus we need the pre-state of the next step.
preState
,
proofData
,
oracleData
,
err
=
s
.
trace
.
GetStepData
(
ctx
,
claim
.
MoveRight
())
if
err
!=
nil
{
return
StepData
{},
err
}
...
...
@@ -166,9 +164,7 @@ func (s *claimSolver) agreeWithClaim(ctx context.Context, claim types.ClaimData)
// traceAtPosition returns the [common.Hash] from internal [TraceProvider] at the given [Position].
func
(
s
*
claimSolver
)
traceAtPosition
(
ctx
context
.
Context
,
p
types
.
Position
)
(
common
.
Hash
,
error
)
{
index
:=
p
.
TraceIndex
(
s
.
gameDepth
)
hash
,
err
:=
s
.
trace
.
Get
(
ctx
,
index
)
return
hash
,
err
return
s
.
trace
.
Get
(
ctx
,
p
)
}
// agreeWithClaimPath returns true if the every other claim in the path to root is correct according to the internal [TraceProvider].
...
...
op-challenger/game/fault/test/alphabet.go
View file @
6eb98a75
...
...
@@ -11,6 +11,7 @@ import (
func
NewAlphabetWithProofProvider
(
t
*
testing
.
T
,
maxDepth
int
,
oracleError
error
)
*
alphabetWithProofProvider
{
return
&
alphabetWithProofProvider
{
alphabet
.
NewTraceProvider
(
"abcdefghijklmnopqrstuvwxyz"
,
uint64
(
maxDepth
)),
uint64
(
maxDepth
),
oracleError
,
}
}
...
...
@@ -22,14 +23,16 @@ func NewAlphabetClaimBuilder(t *testing.T, maxDepth int) *ClaimBuilder {
type
alphabetWithProofProvider
struct
{
*
alphabet
.
AlphabetTraceProvider
depth
uint64
OracleError
error
}
func
(
a
*
alphabetWithProofProvider
)
GetStepData
(
ctx
context
.
Context
,
i
uint64
)
([]
byte
,
[]
byte
,
*
types
.
PreimageOracleData
,
error
)
{
func
(
a
*
alphabetWithProofProvider
)
GetStepData
(
ctx
context
.
Context
,
i
types
.
Position
)
([]
byte
,
[]
byte
,
*
types
.
PreimageOracleData
,
error
)
{
preimage
,
_
,
_
,
err
:=
a
.
AlphabetTraceProvider
.
GetStepData
(
ctx
,
i
)
if
err
!=
nil
{
return
nil
,
nil
,
nil
,
err
}
data
:=
types
.
NewPreimageOracleData
([]
byte
{
byte
(
i
)},
[]
byte
{
byte
(
i
-
1
)},
uint32
(
i
-
1
))
return
preimage
,
[]
byte
{
byte
(
i
-
1
)},
data
,
nil
traceIndex
:=
i
.
TraceIndex
(
int
(
a
.
depth
))
data
:=
types
.
NewPreimageOracleData
([]
byte
{
byte
(
traceIndex
)},
[]
byte
{
byte
(
traceIndex
-
1
)},
uint32
(
traceIndex
-
1
))
return
preimage
,
[]
byte
{
byte
(
traceIndex
-
1
)},
data
,
nil
}
op-challenger/game/fault/test/claim_builder.go
View file @
6eb98a75
...
...
@@ -31,54 +31,50 @@ func (c *ClaimBuilder) CorrectTraceProvider() types.TraceProvider {
return
c
.
correct
}
// CorrectClaim returns the canonical claim at a specified trace index
func
(
c
*
ClaimBuilder
)
CorrectClaim
(
idx
uint64
)
common
.
Hash
{
value
,
err
:=
c
.
correct
.
Get
(
context
.
Background
(),
idx
)
c
.
require
.
NoError
(
err
)
return
value
}
// CorrectClaimAtPosition returns the canonical claim at a specified position
func
(
c
*
ClaimBuilder
)
CorrectClaimAtPosition
(
pos
types
.
Position
)
common
.
Hash
{
value
,
err
:=
c
.
correct
.
Get
(
context
.
Background
(),
pos
.
TraceIndex
(
c
.
maxDepth
)
)
value
,
err
:=
c
.
correct
.
Get
(
context
.
Background
(),
pos
)
c
.
require
.
NoError
(
err
)
return
value
}
// CorrectPreState returns the pre-state (not hashed) required to execute the valid step at the specified trace index
func
(
c
*
ClaimBuilder
)
CorrectPreState
(
idx
uint64
)
[]
byte
{
preimage
,
_
,
_
,
err
:=
c
.
correct
.
GetStepData
(
context
.
Background
(),
idx
)
pos
:=
types
.
NewPosition
(
c
.
maxDepth
,
int
(
idx
))
preimage
,
_
,
_
,
err
:=
c
.
correct
.
GetStepData
(
context
.
Background
(),
pos
)
c
.
require
.
NoError
(
err
)
return
preimage
}
// CorrectProofData returns the proof-data required to execute the valid step at the specified trace index
func
(
c
*
ClaimBuilder
)
CorrectProofData
(
idx
uint64
)
[]
byte
{
_
,
proof
,
_
,
err
:=
c
.
correct
.
GetStepData
(
context
.
Background
(),
idx
)
pos
:=
types
.
NewPosition
(
c
.
maxDepth
,
int
(
idx
))
_
,
proof
,
_
,
err
:=
c
.
correct
.
GetStepData
(
context
.
Background
(),
pos
)
c
.
require
.
NoError
(
err
)
return
proof
}
func
(
c
*
ClaimBuilder
)
CorrectOracleData
(
idx
uint64
)
*
types
.
PreimageOracleData
{
_
,
_
,
data
,
err
:=
c
.
correct
.
GetStepData
(
context
.
Background
(),
idx
)
pos
:=
types
.
NewPosition
(
c
.
maxDepth
,
int
(
idx
))
_
,
_
,
data
,
err
:=
c
.
correct
.
GetStepData
(
context
.
Background
(),
pos
)
c
.
require
.
NoError
(
err
)
return
data
}
func
(
c
*
ClaimBuilder
)
incorrectClaim
(
idx
uint64
)
common
.
Hash
{
return
common
.
BigToHash
(
new
(
big
.
Int
)
.
SetUint64
(
idx
))
func
(
c
*
ClaimBuilder
)
incorrectClaim
(
pos
types
.
Position
)
common
.
Hash
{
return
common
.
BigToHash
(
new
(
big
.
Int
)
.
SetUint64
(
pos
.
TraceIndex
(
c
.
maxDepth
)
))
}
func
(
c
*
ClaimBuilder
)
claim
(
idx
uint64
,
correct
bool
)
common
.
Hash
{
func
(
c
*
ClaimBuilder
)
claim
(
pos
types
.
Position
,
correct
bool
)
common
.
Hash
{
if
correct
{
return
c
.
CorrectClaim
(
idx
)
return
c
.
CorrectClaim
AtPosition
(
pos
)
}
else
{
return
c
.
incorrectClaim
(
idx
)
return
c
.
incorrectClaim
(
pos
)
}
}
func
(
c
*
ClaimBuilder
)
CreateRootClaim
(
correct
bool
)
types
.
Claim
{
value
:=
c
.
claim
(
(
1
<<
c
.
maxDepth
)
-
1
,
correct
)
value
:=
c
.
claim
(
types
.
NewPositionFromGIndex
(
1
)
,
correct
)
claim
:=
types
.
Claim
{
ClaimData
:
types
.
ClaimData
{
Value
:
value
,
...
...
@@ -93,11 +89,11 @@ func (c *ClaimBuilder) CreateLeafClaim(traceIndex uint64, correct bool) types.Cl
pos
:=
types
.
NewPosition
(
c
.
maxDepth
,
int
(
traceIndex
))
return
types
.
Claim
{
ClaimData
:
types
.
ClaimData
{
Value
:
c
.
claim
(
pos
.
TraceIndex
(
c
.
maxDepth
)
,
correct
),
Value
:
c
.
claim
(
pos
,
correct
),
Position
:
pos
,
},
Parent
:
types
.
ClaimData
{
Value
:
c
.
claim
(
parentPos
.
TraceIndex
(
c
.
maxDepth
)
,
!
correct
),
Value
:
c
.
claim
(
parentPos
,
!
correct
),
Position
:
parentPos
,
},
}
...
...
@@ -107,7 +103,7 @@ 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
.
TraceIndex
(
c
.
maxDepth
)
,
correct
),
Value
:
c
.
claim
(
pos
,
correct
),
Position
:
pos
,
},
Parent
:
claim
.
ClaimData
,
...
...
@@ -131,7 +127,7 @@ func (c *ClaimBuilder) DefendClaim(claim types.Claim, correct bool) types.Claim
pos
:=
claim
.
Position
.
Defend
()
return
types
.
Claim
{
ClaimData
:
types
.
ClaimData
{
Value
:
c
.
claim
(
pos
.
TraceIndex
(
c
.
maxDepth
)
,
correct
),
Value
:
c
.
claim
(
pos
,
correct
),
Position
:
pos
,
},
Parent
:
claim
.
ClaimData
,
...
...
op-challenger/game/fault/trace/alphabet/provider.go
View file @
6eb98a75
...
...
@@ -20,6 +20,7 @@ var (
// indices in the given trace.
type
AlphabetTraceProvider
struct
{
state
[]
string
depth
uint64
maxLen
uint64
}
...
...
@@ -27,12 +28,14 @@ type AlphabetTraceProvider struct {
func
NewTraceProvider
(
state
string
,
depth
uint64
)
*
AlphabetTraceProvider
{
return
&
AlphabetTraceProvider
{
state
:
strings
.
Split
(
state
,
""
),
depth
:
depth
,
maxLen
:
uint64
(
1
<<
depth
),
}
}
func
(
ap
*
AlphabetTraceProvider
)
GetStepData
(
ctx
context
.
Context
,
i
uint64
)
([]
byte
,
[]
byte
,
*
types
.
PreimageOracleData
,
error
)
{
if
i
==
0
{
func
(
ap
*
AlphabetTraceProvider
)
GetStepData
(
ctx
context
.
Context
,
i
types
.
Position
)
([]
byte
,
[]
byte
,
*
types
.
PreimageOracleData
,
error
)
{
traceIndex
:=
i
.
TraceIndex
(
int
(
ap
.
depth
))
if
traceIndex
==
0
{
prestate
,
err
:=
ap
.
AbsolutePreState
(
ctx
)
if
err
!=
nil
{
return
nil
,
nil
,
nil
,
err
...
...
@@ -40,22 +43,23 @@ func (ap *AlphabetTraceProvider) GetStepData(ctx context.Context, i uint64) ([]b
return
prestate
,
[]
byte
{},
nil
,
nil
}
// We want the pre-state which is the value prior to the one requested
i
--
traceIndex
--
// The index cannot be larger than the maximum index as computed by the depth.
if
i
>=
ap
.
maxLen
{
if
traceIndex
>=
ap
.
maxLen
{
return
nil
,
nil
,
nil
,
ErrIndexTooLarge
}
// We extend the deepest hash to the maximum depth if the trace is not expansive.
if
i
>=
uint64
(
len
(
ap
.
state
))
{
return
ap
.
GetStepData
(
ctx
,
uint64
(
len
(
ap
.
state
)))
if
traceIndex
>=
uint64
(
len
(
ap
.
state
))
{
return
ap
.
GetStepData
(
ctx
,
types
.
NewPosition
(
int
(
ap
.
depth
),
len
(
ap
.
state
)))
}
return
BuildAlphabetPreimage
(
i
,
ap
.
state
[
i
]),
[]
byte
{},
nil
,
nil
return
BuildAlphabetPreimage
(
traceIndex
,
ap
.
state
[
traceIndex
]),
[]
byte
{},
nil
,
nil
}
// Get returns the claim value at the given index in the trace.
func
(
ap
*
AlphabetTraceProvider
)
Get
(
ctx
context
.
Context
,
i
uint64
)
(
common
.
Hash
,
error
)
{
func
(
ap
*
AlphabetTraceProvider
)
Get
(
ctx
context
.
Context
,
i
types
.
Position
)
(
common
.
Hash
,
error
)
{
// Step data returns the pre-state, so add 1 to get the state for index i
claimBytes
,
_
,
_
,
err
:=
ap
.
GetStepData
(
ctx
,
i
+
1
)
postPosition
:=
types
.
NewPosition
(
int
(
ap
.
depth
),
int
(
i
.
TraceIndex
(
int
(
ap
.
depth
)))
+
1
)
claimBytes
,
_
,
_
,
err
:=
ap
.
GetStepData
(
ctx
,
postPosition
)
if
err
!=
nil
{
return
common
.
Hash
{},
err
}
...
...
op-challenger/game/fault/trace/alphabet/provider_test.go
View file @
6eb98a75
...
...
@@ -5,6 +5,7 @@ import (
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
...
...
@@ -16,23 +17,24 @@ func alphabetClaim(index uint64, letter string) common.Hash {
// TestAlphabetProvider_Get_ClaimsByTraceIndex tests the [fault.AlphabetProvider] Get function.
func
TestAlphabetProvider_Get_ClaimsByTraceIndex
(
t
*
testing
.
T
)
{
// Create a new alphabet provider.
canonicalProvider
:=
NewTraceProvider
(
"abcdefgh"
,
uint64
(
3
))
depth
:=
3
canonicalProvider
:=
NewTraceProvider
(
"abcdefgh"
,
uint64
(
depth
))
// Build a list of traces.
traces
:=
[]
struct
{
traceIndex
uint64
traceIndex
types
.
Position
expectedHash
common
.
Hash
}{
{
7
,
types
.
NewPosition
(
depth
,
7
)
,
alphabetClaim
(
7
,
"h"
),
},
{
3
,
types
.
NewPosition
(
depth
,
3
)
,
alphabetClaim
(
3
,
"d"
),
},
{
5
,
types
.
NewPosition
(
depth
,
5
)
,
alphabetClaim
(
5
,
"f"
),
},
}
...
...
@@ -58,9 +60,11 @@ func FuzzIndexToBytes(f *testing.F) {
// TestGetPreimage_Succeeds tests the GetPreimage function
// returns the correct pre-image for a index.
func
TestGetStepData_Succeeds
(
t
*
testing
.
T
)
{
ap
:=
NewTraceProvider
(
"abc"
,
2
)
depth
:=
2
ap
:=
NewTraceProvider
(
"abc"
,
uint64
(
depth
))
expected
:=
BuildAlphabetPreimage
(
0
,
"a"
)
retrieved
,
proof
,
data
,
err
:=
ap
.
GetStepData
(
context
.
Background
(),
uint64
(
1
))
pos
:=
types
.
NewPosition
(
depth
,
1
)
retrieved
,
proof
,
data
,
err
:=
ap
.
GetStepData
(
context
.
Background
(),
pos
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
expected
,
retrieved
)
require
.
Empty
(
t
,
proof
)
...
...
@@ -70,15 +74,19 @@ func TestGetStepData_Succeeds(t *testing.T) {
// TestGetPreimage_TooLargeIndex_Fails tests the GetPreimage
// function errors if the index is too large.
func
TestGetStepData_TooLargeIndex_Fails
(
t
*
testing
.
T
)
{
ap
:=
NewTraceProvider
(
"abc"
,
2
)
_
,
_
,
_
,
err
:=
ap
.
GetStepData
(
context
.
Background
(),
5
)
depth
:=
2
ap
:=
NewTraceProvider
(
"abc"
,
uint64
(
depth
))
pos
:=
types
.
NewPosition
(
depth
,
5
)
_
,
_
,
_
,
err
:=
ap
.
GetStepData
(
context
.
Background
(),
pos
)
require
.
ErrorIs
(
t
,
err
,
ErrIndexTooLarge
)
}
// TestGet_Succeeds tests the Get function.
func
TestGet_Succeeds
(
t
*
testing
.
T
)
{
ap
:=
NewTraceProvider
(
"abc"
,
2
)
claim
,
err
:=
ap
.
Get
(
context
.
Background
(),
0
)
depth
:=
2
ap
:=
NewTraceProvider
(
"abc"
,
uint64
(
depth
))
pos
:=
types
.
NewPosition
(
depth
,
0
)
claim
,
err
:=
ap
.
Get
(
context
.
Background
(),
pos
)
require
.
NoError
(
t
,
err
)
expected
:=
alphabetClaim
(
0
,
"a"
)
require
.
Equal
(
t
,
expected
,
claim
)
...
...
@@ -87,16 +95,20 @@ func TestGet_Succeeds(t *testing.T) {
// TestGet_IndexTooLarge tests the Get function with an index
// greater than the number of indices: 2^depth - 1.
func
TestGet_IndexTooLarge
(
t
*
testing
.
T
)
{
ap
:=
NewTraceProvider
(
"abc"
,
2
)
_
,
err
:=
ap
.
Get
(
context
.
Background
(),
4
)
depth
:=
2
ap
:=
NewTraceProvider
(
"abc"
,
uint64
(
depth
))
pos
:=
types
.
NewPosition
(
depth
,
4
)
_
,
err
:=
ap
.
Get
(
context
.
Background
(),
pos
)
require
.
ErrorIs
(
t
,
err
,
ErrIndexTooLarge
)
}
// TestGet_Extends tests the Get function with an index that is larger
// than the trace, but smaller than the maximum depth.
func
TestGet_Extends
(
t
*
testing
.
T
)
{
ap
:=
NewTraceProvider
(
"abc"
,
2
)
claim
,
err
:=
ap
.
Get
(
context
.
Background
(),
3
)
depth
:=
2
ap
:=
NewTraceProvider
(
"abc"
,
uint64
(
depth
))
pos
:=
types
.
NewPosition
(
depth
,
3
)
claim
,
err
:=
ap
.
Get
(
context
.
Background
(),
pos
)
require
.
NoError
(
t
,
err
)
expected
:=
alphabetClaim
(
2
,
"c"
)
require
.
Equal
(
t
,
expected
,
claim
)
...
...
op-challenger/game/fault/trace/cannon/provider.go
View file @
6eb98a75
...
...
@@ -49,13 +49,14 @@ type CannonTraceProvider struct {
dir
string
prestate
string
generator
ProofGenerator
gameDepth
uint64
// lastStep stores the last step in the actual trace if known. 0 indicates unknown.
// Cached as an optimisation to avoid repeatedly attempting to execute beyond the end of the trace.
lastStep
uint64
}
func
NewTraceProvider
(
ctx
context
.
Context
,
logger
log
.
Logger
,
m
CannonMetricer
,
cfg
*
config
.
Config
,
l1Client
bind
.
ContractCaller
,
dir
string
,
gameAddr
common
.
Address
)
(
*
CannonTraceProvider
,
error
)
{
func
NewTraceProvider
(
ctx
context
.
Context
,
logger
log
.
Logger
,
m
CannonMetricer
,
cfg
*
config
.
Config
,
l1Client
bind
.
ContractCaller
,
dir
string
,
gameAddr
common
.
Address
,
gameDepth
uint64
)
(
*
CannonTraceProvider
,
error
)
{
l2Client
,
err
:=
ethclient
.
DialContext
(
ctx
,
cfg
.
CannonL2
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"dial l2 client %v: %w"
,
cfg
.
CannonL2
,
err
)
...
...
@@ -69,20 +70,25 @@ func NewTraceProvider(ctx context.Context, logger log.Logger, m CannonMetricer,
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"fetch local game inputs: %w"
,
err
)
}
return
NewTraceProviderFromInputs
(
logger
,
m
,
cfg
,
localInputs
,
dir
),
nil
return
NewTraceProviderFromInputs
(
logger
,
m
,
cfg
,
localInputs
,
dir
,
gameDepth
),
nil
}
func
NewTraceProviderFromInputs
(
logger
log
.
Logger
,
m
CannonMetricer
,
cfg
*
config
.
Config
,
localInputs
LocalGameInputs
,
dir
string
)
*
CannonTraceProvider
{
func
NewTraceProviderFromInputs
(
logger
log
.
Logger
,
m
CannonMetricer
,
cfg
*
config
.
Config
,
localInputs
LocalGameInputs
,
dir
string
,
gameDepth
uint64
)
*
CannonTraceProvider
{
return
&
CannonTraceProvider
{
logger
:
logger
,
dir
:
dir
,
prestate
:
cfg
.
CannonAbsolutePreState
,
generator
:
NewExecutor
(
logger
,
m
,
cfg
,
localInputs
),
gameDepth
:
gameDepth
,
}
}
func
(
p
*
CannonTraceProvider
)
Get
(
ctx
context
.
Context
,
i
uint64
)
(
common
.
Hash
,
error
)
{
proof
,
err
:=
p
.
loadProof
(
ctx
,
i
)
func
(
p
*
CannonTraceProvider
)
SetMaxDepth
(
gameDepth
uint64
)
{
p
.
gameDepth
=
gameDepth
}
func
(
p
*
CannonTraceProvider
)
Get
(
ctx
context
.
Context
,
pos
types
.
Position
)
(
common
.
Hash
,
error
)
{
proof
,
err
:=
p
.
loadProof
(
ctx
,
pos
.
TraceIndex
(
int
(
p
.
gameDepth
)))
if
err
!=
nil
{
return
common
.
Hash
{},
err
}
...
...
@@ -94,8 +100,8 @@ func (p *CannonTraceProvider) Get(ctx context.Context, i uint64) (common.Hash, e
return
value
,
nil
}
func
(
p
*
CannonTraceProvider
)
GetStepData
(
ctx
context
.
Context
,
i
uint64
)
([]
byte
,
[]
byte
,
*
types
.
PreimageOracleData
,
error
)
{
proof
,
err
:=
p
.
loadProof
(
ctx
,
i
)
func
(
p
*
CannonTraceProvider
)
GetStepData
(
ctx
context
.
Context
,
pos
types
.
Position
)
([]
byte
,
[]
byte
,
*
types
.
PreimageOracleData
,
error
)
{
proof
,
err
:=
p
.
loadProof
(
ctx
,
pos
.
TraceIndex
(
int
(
p
.
gameDepth
))
)
if
err
!=
nil
{
return
nil
,
nil
,
nil
,
err
}
...
...
op-challenger/game/fault/trace/cannon/provider_test.go
View file @
6eb98a75
...
...
@@ -22,11 +22,15 @@ import (
//go:embed test_data
var
testData
embed
.
FS
func
PositionFromTraceIndex
(
provider
*
CannonTraceProvider
,
idx
int
)
types
.
Position
{
return
types
.
NewPosition
(
int
(
provider
.
gameDepth
),
idx
)
}
func
TestGet
(
t
*
testing
.
T
)
{
dataDir
,
prestate
:=
setupTestData
(
t
)
t
.
Run
(
"ExistingProof"
,
func
(
t
*
testing
.
T
)
{
provider
,
generator
:=
setupWithTestData
(
t
,
dataDir
,
prestate
)
value
,
err
:=
provider
.
Get
(
context
.
Background
(),
0
)
value
,
err
:=
provider
.
Get
(
context
.
Background
(),
PositionFromTraceIndex
(
provider
,
0
)
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
common
.
HexToHash
(
"0x45fd9aa59768331c726e719e76aa343e73123af888804604785ae19506e65e87"
),
value
)
require
.
Empty
(
t
,
generator
.
generated
)
...
...
@@ -39,7 +43,7 @@ func TestGet(t *testing.T) {
Step
:
10
,
Exited
:
true
,
}
value
,
err
:=
provider
.
Get
(
context
.
Background
(),
7000
)
value
,
err
:=
provider
.
Get
(
context
.
Background
(),
PositionFromTraceIndex
(
provider
,
7000
)
)
require
.
NoError
(
t
,
err
)
require
.
Contains
(
t
,
generator
.
generated
,
7000
,
"should have tried to generate the proof"
)
stateHash
,
err
:=
generator
.
finalState
.
EncodeWitness
()
.
StateHash
()
...
...
@@ -49,14 +53,14 @@ func TestGet(t *testing.T) {
t
.
Run
(
"MissingPostHash"
,
func
(
t
*
testing
.
T
)
{
provider
,
generator
:=
setupWithTestData
(
t
,
dataDir
,
prestate
)
_
,
err
:=
provider
.
Get
(
context
.
Background
(),
1
)
_
,
err
:=
provider
.
Get
(
context
.
Background
(),
PositionFromTraceIndex
(
provider
,
1
)
)
require
.
ErrorContains
(
t
,
err
,
"missing post hash"
)
require
.
Empty
(
t
,
generator
.
generated
)
})
t
.
Run
(
"IgnoreUnknownFields"
,
func
(
t
*
testing
.
T
)
{
provider
,
generator
:=
setupWithTestData
(
t
,
dataDir
,
prestate
)
value
,
err
:=
provider
.
Get
(
context
.
Background
(),
2
)
value
,
err
:=
provider
.
Get
(
context
.
Background
(),
PositionFromTraceIndex
(
provider
,
2
)
)
require
.
NoError
(
t
,
err
)
expected
:=
common
.
HexToHash
(
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
)
require
.
Equal
(
t
,
expected
,
value
)
...
...
@@ -68,7 +72,7 @@ func TestGetStepData(t *testing.T) {
t
.
Run
(
"ExistingProof"
,
func
(
t
*
testing
.
T
)
{
dataDir
,
prestate
:=
setupTestData
(
t
)
provider
,
generator
:=
setupWithTestData
(
t
,
dataDir
,
prestate
)
value
,
proof
,
data
,
err
:=
provider
.
GetStepData
(
context
.
Background
(),
0
)
value
,
proof
,
data
,
err
:=
provider
.
GetStepData
(
context
.
Background
(),
PositionFromTraceIndex
(
provider
,
0
)
)
require
.
NoError
(
t
,
err
)
expected
:=
common
.
Hex2Bytes
(
"b8f068de604c85ea0e2acd437cdb47add074a2d70b81d018390c504b71fe26f400000000000000000000000000000000000000000000000000000000000000000000000000"
)
require
.
Equal
(
t
,
expected
,
value
)
...
...
@@ -95,7 +99,7 @@ func TestGetStepData(t *testing.T) {
OracleValue
:
[]
byte
{
0xdd
},
OracleOffset
:
10
,
}
preimage
,
proof
,
data
,
err
:=
provider
.
GetStepData
(
context
.
Background
(),
4
)
preimage
,
proof
,
data
,
err
:=
provider
.
GetStepData
(
context
.
Background
(),
PositionFromTraceIndex
(
provider
,
4
)
)
require
.
NoError
(
t
,
err
)
require
.
Contains
(
t
,
generator
.
generated
,
4
,
"should have tried to generate the proof"
)
...
...
@@ -121,7 +125,7 @@ func TestGetStepData(t *testing.T) {
OracleValue
:
[]
byte
{
0xdd
},
OracleOffset
:
10
,
}
preimage
,
proof
,
data
,
err
:=
provider
.
GetStepData
(
context
.
Background
(),
7000
)
preimage
,
proof
,
data
,
err
:=
provider
.
GetStepData
(
context
.
Background
(),
PositionFromTraceIndex
(
provider
,
7000
)
)
require
.
NoError
(
t
,
err
)
require
.
Contains
(
t
,
generator
.
generated
,
7000
,
"should have tried to generate the proof"
)
...
...
@@ -147,7 +151,7 @@ func TestGetStepData(t *testing.T) {
OracleValue
:
[]
byte
{
0xdd
},
OracleOffset
:
10
,
}
_
,
_
,
_
,
err
:=
provider
.
GetStepData
(
context
.
Background
(),
7000
)
_
,
_
,
_
,
err
:=
provider
.
GetStepData
(
context
.
Background
(),
PositionFromTraceIndex
(
provider
,
7000
)
)
require
.
NoError
(
t
,
err
)
require
.
Contains
(
t
,
initGenerator
.
generated
,
7000
,
"should have tried to generate the proof"
)
...
...
@@ -162,7 +166,7 @@ func TestGetStepData(t *testing.T) {
StateData
:
[]
byte
{
0xbb
},
ProofData
:
[]
byte
{
0xcc
},
}
preimage
,
proof
,
data
,
err
:=
provider
.
GetStepData
(
context
.
Background
(),
7000
)
preimage
,
proof
,
data
,
err
:=
provider
.
GetStepData
(
context
.
Background
(),
PositionFromTraceIndex
(
provider
,
7000
)
)
require
.
NoError
(
t
,
err
)
require
.
Empty
(
t
,
generator
.
generated
,
"should not have to generate the proof again"
)
...
...
@@ -174,7 +178,7 @@ func TestGetStepData(t *testing.T) {
t
.
Run
(
"MissingStateData"
,
func
(
t
*
testing
.
T
)
{
dataDir
,
prestate
:=
setupTestData
(
t
)
provider
,
generator
:=
setupWithTestData
(
t
,
dataDir
,
prestate
)
_
,
_
,
_
,
err
:=
provider
.
GetStepData
(
context
.
Background
(),
1
)
_
,
_
,
_
,
err
:=
provider
.
GetStepData
(
context
.
Background
(),
PositionFromTraceIndex
(
provider
,
1
)
)
require
.
ErrorContains
(
t
,
err
,
"missing state data"
)
require
.
Empty
(
t
,
generator
.
generated
)
})
...
...
@@ -182,7 +186,7 @@ func TestGetStepData(t *testing.T) {
t
.
Run
(
"IgnoreUnknownFields"
,
func
(
t
*
testing
.
T
)
{
dataDir
,
prestate
:=
setupTestData
(
t
)
provider
,
generator
:=
setupWithTestData
(
t
,
dataDir
,
prestate
)
value
,
proof
,
data
,
err
:=
provider
.
GetStepData
(
context
.
Background
(),
2
)
value
,
proof
,
data
,
err
:=
provider
.
GetStepData
(
context
.
Background
(),
PositionFromTraceIndex
(
provider
,
2
)
)
require
.
NoError
(
t
,
err
)
expected
:=
common
.
Hex2Bytes
(
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
)
require
.
Equal
(
t
,
expected
,
value
)
...
...
@@ -266,6 +270,7 @@ func setupWithTestData(t *testing.T, dataDir string, prestate string) (*CannonTr
dir
:
dataDir
,
generator
:
generator
,
prestate
:
filepath
.
Join
(
dataDir
,
prestate
),
gameDepth
:
63
,
},
generator
}
...
...
op-challenger/game/fault/types/position.go
View file @
6eb98a75
...
...
@@ -18,6 +18,13 @@ func NewPositionFromGIndex(x uint64) Position {
return
NewPosition
(
depth
,
int
(
indexAtDepth
))
}
func
(
p
Position
)
MoveRight
()
Position
{
return
Position
{
depth
:
p
.
depth
,
indexAtDepth
:
int
(
p
.
indexAtDepth
+
1
),
}
}
func
(
p
Position
)
Depth
()
int
{
return
p
.
depth
}
...
...
op-challenger/game/fault/types/types.go
View file @
6eb98a75
...
...
@@ -64,13 +64,13 @@ type OracleUpdater interface {
type
TraceProvider
interface
{
// Get returns the claim value at the requested index.
// Get(i) = Keccak256(GetPreimage(i))
Get
(
ctx
context
.
Context
,
i
uint64
)
(
common
.
Hash
,
error
)
Get
(
ctx
context
.
Context
,
i
Position
)
(
common
.
Hash
,
error
)
// GetStepData returns the data required to execute the step at the specified trace index.
// This includes the pre-state of the step (not hashed), the proof data required during step execution
// and any pre-image data that needs to be loaded into the oracle prior to execution (may be nil)
// The prestate returned from GetStepData for trace 10 should be the pre-image of the claim from trace 9
GetStepData
(
ctx
context
.
Context
,
i
uint64
)
(
prestate
[]
byte
,
proofData
[]
byte
,
preimageData
*
PreimageOracleData
,
err
error
)
GetStepData
(
ctx
context
.
Context
,
i
Position
)
(
prestate
[]
byte
,
proofData
[]
byte
,
preimageData
*
PreimageOracleData
,
err
error
)
// AbsolutePreState is the pre-image value of the trace that transitions to the trace value at index 0
AbsolutePreState
(
ctx
context
.
Context
)
(
preimage
[]
byte
,
err
error
)
...
...
op-e2e/e2eutils/disputegame/cannon_helper.go
View file @
6eb98a75
...
...
@@ -41,7 +41,8 @@ func (g *CannonGameHelper) CreateHonestActor(ctx context.Context, rollupCfg *rol
opts
=
append
(
opts
,
options
...
)
cfg
:=
challenger
.
NewChallengerConfig
(
g
.
t
,
l1Endpoint
,
opts
...
)
logger
:=
testlog
.
Logger
(
g
.
t
,
log
.
LvlInfo
)
.
New
(
"role"
,
"CorrectTrace"
)
provider
,
err
:=
cannon
.
NewTraceProvider
(
ctx
,
logger
,
metrics
.
NoopMetrics
,
cfg
,
l1Client
,
filepath
.
Join
(
cfg
.
Datadir
,
"honest"
),
g
.
addr
)
maxDepth
:=
g
.
MaxDepth
(
ctx
)
provider
,
err
:=
cannon
.
NewTraceProvider
(
ctx
,
logger
,
metrics
.
NoopMetrics
,
cfg
,
l1Client
,
filepath
.
Join
(
cfg
.
Datadir
,
"honest"
),
g
.
addr
,
uint64
(
maxDepth
))
g
.
require
.
NoError
(
err
,
"create cannon trace provider"
)
return
&
HonestHelper
{
...
...
op-e2e/e2eutils/disputegame/game_helper.go
View file @
6eb98a75
...
...
@@ -141,6 +141,11 @@ func (g *FaultGameHelper) getClaim(ctx context.Context, claimIdx int64) Contract
return
claimData
}
// getClaimPosition retrieves the [types.Position] of a claim at a specific index.
func
(
g
*
FaultGameHelper
)
getClaimPosition
(
ctx
context
.
Context
,
claimIdx
int64
)
types
.
Position
{
return
types
.
NewPositionFromGIndex
(
g
.
getClaim
(
ctx
,
claimIdx
)
.
Position
.
Uint64
())
}
func
(
g
*
FaultGameHelper
)
WaitForClaimAtDepth
(
ctx
context
.
Context
,
depth
int
)
{
g
.
waitForClaim
(
ctx
,
...
...
op-e2e/e2eutils/disputegame/helper.go
View file @
6eb98a75
...
...
@@ -4,7 +4,6 @@ import (
"context"
"encoding/binary"
"fmt"
"math"
"math/big"
"testing"
"time"
...
...
@@ -15,6 +14,7 @@ import (
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon"
faultTypes
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/l2oo"
...
...
@@ -36,6 +36,9 @@ const cannonGameType uint8 = 0
const
alphabetGameDepth
=
4
const
lastAlphabetTraceIndex
=
1
<<
alphabetGameDepth
-
1
// rootPosition is the position of the root claim.
var
rootPosition
=
faultTypes
.
NewPositionFromGIndex
(
1
)
type
Status
uint8
const
(
...
...
@@ -104,7 +107,8 @@ func (h *FactoryHelper) StartAlphabetGame(ctx context.Context, claimedAlphabet s
defer
cancel
()
trace
:=
alphabet
.
NewTraceProvider
(
claimedAlphabet
,
alphabetGameDepth
)
rootClaim
,
err
:=
trace
.
Get
(
ctx
,
lastAlphabetTraceIndex
)
pos
:=
faultTypes
.
NewPosition
(
alphabetGameDepth
,
lastAlphabetTraceIndex
)
rootClaim
,
err
:=
trace
.
Get
(
ctx
,
pos
)
h
.
require
.
NoError
(
err
,
"get root claim"
)
extraData
:=
make
([]
byte
,
64
)
binary
.
BigEndian
.
PutUint64
(
extraData
[
24
:
],
l2BlockNumber
)
...
...
@@ -172,14 +176,33 @@ func (h *FactoryHelper) StartCannonGameWithCorrectRoot(ctx context.Context, roll
L2Claim
:
challengedOutput
.
OutputRoot
,
L2BlockNumber
:
challengedOutput
.
L2BlockNumber
,
}
provider
:=
cannon
.
NewTraceProviderFromInputs
(
testlog
.
Logger
(
h
.
t
,
log
.
LvlInfo
)
.
New
(
"role"
,
"CorrectTrace"
),
metrics
.
NoopMetrics
,
cfg
,
inputs
,
cfg
.
Datadir
)
rootClaim
,
err
:=
provider
.
Get
(
ctx
,
math
.
MaxUint64
)
cannonTypeAddr
,
err
:=
h
.
factory
.
GameImpls
(
opts
,
cannonGameType
)
h
.
require
.
NoError
(
err
,
"fetch cannon game type impl"
)
gameImpl
,
err
:=
bindings
.
NewFaultDisputeGameCaller
(
cannonTypeAddr
,
h
.
client
)
h
.
require
.
NoError
(
err
,
"bind fault dispute game caller"
)
maxDepth
,
err
:=
gameImpl
.
MAXGAMEDEPTH
(
opts
)
h
.
require
.
NoError
(
err
,
"fetch max game depth"
)
provider
:=
cannon
.
NewTraceProviderFromInputs
(
testlog
.
Logger
(
h
.
t
,
log
.
LvlInfo
)
.
New
(
"role"
,
"CorrectTrace"
),
metrics
.
NoopMetrics
,
cfg
,
inputs
,
cfg
.
Datadir
,
maxDepth
.
Uint64
(),
)
rootClaim
,
err
:=
provider
.
Get
(
ctx
,
rootPosition
)
h
.
require
.
NoError
(
err
,
"Compute correct root hash"
)
// Override the VM status to claim the root is invalid
// Otherwise creating the game will fail
rootClaim
[
0
]
=
mipsevm
.
VMStatusInvalid
game
:=
h
.
createCannonGame
(
ctx
,
l2BlockNumber
,
l1Head
,
rootClaim
)
correctMaxDepth
:=
game
.
MaxDepth
(
ctx
)
provider
.
SetMaxDepth
(
uint64
(
correctMaxDepth
))
honestHelper
:=
&
HonestHelper
{
t
:
h
.
t
,
require
:
h
.
require
,
...
...
op-e2e/e2eutils/disputegame/honest_helper.go
View file @
6eb98a75
...
...
@@ -22,10 +22,9 @@ func (h *HonestHelper) Attack(ctx context.Context, claimIdx int64) {
claim
:=
h
.
game
.
getClaim
(
ctx
,
claimIdx
)
pos
:=
types
.
NewPositionFromGIndex
(
claim
.
Position
.
Uint64
())
attackPos
:=
pos
.
Attack
()
traceIdx
:=
attackPos
.
TraceIndex
(
int
(
h
.
game
.
MaxDepth
(
ctx
)))
h
.
t
.
Logf
(
"Attacking at position %v using correct trace from index %v"
,
attackPos
.
ToGIndex
(),
traceIdx
)
value
,
err
:=
h
.
correctTrace
.
Get
(
ctx
,
traceIdx
)
h
.
require
.
NoErrorf
(
err
,
"Get correct claim at trace index %v"
,
traceIdx
)
h
.
t
.
Logf
(
"Attacking at position %v with g index %v"
,
attackPos
,
attackPos
.
ToGIndex
())
value
,
err
:=
h
.
correctTrace
.
Get
(
ctx
,
attackPos
)
h
.
require
.
NoErrorf
(
err
,
"Get correct claim at position %v with g index %v"
,
attackPos
,
attackPos
.
ToGIndex
())
h
.
t
.
Log
(
"Performing attack"
)
h
.
game
.
Attack
(
ctx
,
claimIdx
,
value
)
h
.
t
.
Log
(
"Attack complete"
)
...
...
@@ -37,23 +36,20 @@ func (h *HonestHelper) Defend(ctx context.Context, claimIdx int64) {
claim
:=
h
.
game
.
getClaim
(
ctx
,
claimIdx
)
pos
:=
types
.
NewPositionFromGIndex
(
claim
.
Position
.
Uint64
())
defendPos
:=
pos
.
Defend
()
traceIdx
:=
defendPos
.
TraceIndex
(
int
(
h
.
game
.
MaxDepth
(
ctx
)))
value
,
err
:=
h
.
correctTrace
.
Get
(
ctx
,
traceIdx
)
h
.
game
.
require
.
NoErrorf
(
err
,
"Get correct claim at trace index %v"
,
traceIdx
)
value
,
err
:=
h
.
correctTrace
.
Get
(
ctx
,
defendPos
)
h
.
game
.
require
.
NoErrorf
(
err
,
"Get correct claim at position %v with g index %v"
,
defendPos
,
defendPos
.
ToGIndex
())
h
.
game
.
Defend
(
ctx
,
claimIdx
,
value
)
}
func
(
h
*
HonestHelper
)
StepFails
(
ctx
context
.
Context
,
claimIdx
int64
,
isAttack
bool
)
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
2
*
time
.
Minute
)
defer
cancel
()
claim
:=
h
.
game
.
getClaim
(
ctx
,
claimIdx
)
pos
:=
types
.
NewPositionFromGIndex
(
claim
.
Position
.
Uint64
())
traceIdx
:=
pos
.
TraceIndex
(
int
(
h
.
game
.
MaxDepth
(
ctx
)))
pos
:=
h
.
game
.
getClaimPosition
(
ctx
,
claimIdx
)
if
!
isAttack
{
// If we're defending, then the step will be from the trace to the next one
traceIdx
+=
1
pos
=
pos
.
MoveRight
()
}
prestate
,
proofData
,
_
,
err
:=
h
.
correctTrace
.
GetStepData
(
ctx
,
traceIdx
)
prestate
,
proofData
,
_
,
err
:=
h
.
correctTrace
.
GetStepData
(
ctx
,
pos
)
h
.
require
.
NoError
(
err
,
"Get step data"
)
h
.
game
.
StepFails
(
claimIdx
,
isAttack
,
prestate
,
proofData
)
}
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