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
2e4de94b
Unverified
Commit
2e4de94b
authored
Nov 09, 2023
by
Adrian Sutton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
op-challenger: Add a provider selector function for split output games.
parent
6c4a9ac4
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
373 additions
and
202 deletions
+373
-202
game_builder.go
op-challenger/game/fault/test/game_builder.go
+5
-1
access.go
op-challenger/game/fault/trace/access.go
+3
-3
provider.go
op-challenger/game/fault/trace/alphabet/provider.go
+3
-0
provider_test.go
op-challenger/game/fault/trace/alphabet/provider_test.go
+8
-0
split.go
op-challenger/game/fault/trace/outputs/split.go
+86
-0
split_test.go
op-challenger/game/fault/trace/outputs/split_test.go
+268
-0
provider.go
op-challenger/game/fault/trace/split/provider.go
+0
-67
provider_test.go
op-challenger/game/fault/trace/split/provider_test.go
+0
-131
No files found.
op-challenger/game/fault/test/game_builder.go
View file @
2e4de94b
...
@@ -29,10 +29,14 @@ type GameBuilderSeq struct {
...
@@ -29,10 +29,14 @@ type GameBuilderSeq struct {
}
}
func
(
g
*
GameBuilder
)
Seq
()
*
GameBuilderSeq
{
func
(
g
*
GameBuilder
)
Seq
()
*
GameBuilderSeq
{
return
g
.
SeqFrom
(
g
.
Game
.
Claims
()[
0
])
}
func
(
g
*
GameBuilder
)
SeqFrom
(
claim
types
.
Claim
)
*
GameBuilderSeq
{
return
&
GameBuilderSeq
{
return
&
GameBuilderSeq
{
gameBuilder
:
g
,
gameBuilder
:
g
,
builder
:
g
.
builder
,
builder
:
g
.
builder
,
lastClaim
:
g
.
Game
.
Claims
()[
0
]
,
lastClaim
:
claim
,
}
}
}
}
...
...
op-challenger/game/fault/trace/access.go
View file @
2e4de94b
...
@@ -7,8 +7,6 @@ import (
...
@@ -7,8 +7,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
)
)
type
ProviderCreator
func
(
ctx
context
.
Context
,
pre
types
.
Claim
,
post
types
.
Claim
)
(
types
.
TraceProvider
,
error
)
func
NewSimpleTraceAccessor
(
trace
types
.
TraceProvider
)
*
Accessor
{
func
NewSimpleTraceAccessor
(
trace
types
.
TraceProvider
)
*
Accessor
{
selector
:=
func
(
_
context
.
Context
,
_
types
.
Game
,
_
types
.
Claim
,
_
types
.
Position
)
(
types
.
TraceProvider
,
error
)
{
selector
:=
func
(
_
context
.
Context
,
_
types
.
Game
,
_
types
.
Claim
,
_
types
.
Position
)
(
types
.
TraceProvider
,
error
)
{
return
trace
,
nil
return
trace
,
nil
...
@@ -16,8 +14,10 @@ func NewSimpleTraceAccessor(trace types.TraceProvider) *Accessor {
...
@@ -16,8 +14,10 @@ func NewSimpleTraceAccessor(trace types.TraceProvider) *Accessor {
return
&
Accessor
{
selector
}
return
&
Accessor
{
selector
}
}
}
type
ProviderSelector
func
(
ctx
context
.
Context
,
game
types
.
Game
,
ref
types
.
Claim
,
pos
types
.
Position
)
(
types
.
TraceProvider
,
error
)
type
Accessor
struct
{
type
Accessor
struct
{
selector
func
(
ctx
context
.
Context
,
game
types
.
Game
,
ref
types
.
Claim
,
pos
types
.
Position
)
(
types
.
TraceProvider
,
error
)
selector
ProviderSelector
}
}
func
(
t
*
Accessor
)
Get
(
ctx
context
.
Context
,
game
types
.
Game
,
ref
types
.
Claim
,
pos
types
.
Position
)
(
common
.
Hash
,
error
)
{
func
(
t
*
Accessor
)
Get
(
ctx
context
.
Context
,
game
types
.
Game
,
ref
types
.
Claim
,
pos
types
.
Position
)
(
common
.
Hash
,
error
)
{
...
...
op-challenger/game/fault/trace/alphabet/provider.go
View file @
2e4de94b
...
@@ -54,6 +54,9 @@ func (ap *AlphabetTraceProvider) GetStepData(ctx context.Context, i types.Positi
...
@@ -54,6 +54,9 @@ func (ap *AlphabetTraceProvider) GetStepData(ctx context.Context, i types.Positi
// Get returns the claim value at the given index in the trace.
// Get returns the claim value at the given index in the trace.
func
(
ap
*
AlphabetTraceProvider
)
Get
(
ctx
context
.
Context
,
i
types
.
Position
)
(
common
.
Hash
,
error
)
{
func
(
ap
*
AlphabetTraceProvider
)
Get
(
ctx
context
.
Context
,
i
types
.
Position
)
(
common
.
Hash
,
error
)
{
if
uint64
(
i
.
Depth
())
>
ap
.
depth
{
return
common
.
Hash
{},
ErrIndexTooLarge
}
// Step data returns the pre-state, so add 1 to get the state for index i
// Step data returns the pre-state, so add 1 to get the state for index i
ti
:=
i
.
TraceIndex
(
int
(
ap
.
depth
))
ti
:=
i
.
TraceIndex
(
int
(
ap
.
depth
))
postPosition
:=
types
.
NewPosition
(
int
(
ap
.
depth
),
new
(
big
.
Int
)
.
Add
(
ti
,
big
.
NewInt
(
1
)))
postPosition
:=
types
.
NewPosition
(
int
(
ap
.
depth
),
new
(
big
.
Int
)
.
Add
(
ti
,
big
.
NewInt
(
1
)))
...
...
op-challenger/game/fault/trace/alphabet/provider_test.go
View file @
2e4de94b
...
@@ -92,6 +92,14 @@ func TestGet_IndexTooLarge(t *testing.T) {
...
@@ -92,6 +92,14 @@ func TestGet_IndexTooLarge(t *testing.T) {
require
.
ErrorIs
(
t
,
err
,
ErrIndexTooLarge
)
require
.
ErrorIs
(
t
,
err
,
ErrIndexTooLarge
)
}
}
func
TestGet_DepthTooLarge
(
t
*
testing
.
T
)
{
depth
:=
2
ap
:=
NewTraceProvider
(
"abc"
,
uint64
(
depth
))
pos
:=
types
.
NewPosition
(
depth
+
1
,
big
.
NewInt
(
0
))
_
,
err
:=
ap
.
Get
(
context
.
Background
(),
pos
)
require
.
ErrorIs
(
t
,
err
,
ErrIndexTooLarge
)
}
// TestGet_Extends tests the Get function with an index that is larger
// TestGet_Extends tests the Get function with an index that is larger
// than the trace, but smaller than the maximum depth.
// than the trace, but smaller than the maximum depth.
func
TestGet_Extends
(
t
*
testing
.
T
)
{
func
TestGet_Extends
(
t
*
testing
.
T
)
{
...
...
op-challenger/game/fault/trace/outputs/split.go
0 → 100644
View file @
2e4de94b
package
outputs
import
(
"context"
"errors"
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
)
var
(
errRefClaimNotDeepEnough
=
errors
.
New
(
"reference claim is not deep enough"
)
)
type
ProviderCreator
func
(
ctx
context
.
Context
,
pre
types
.
Claim
,
post
types
.
Claim
)
(
types
.
TraceProvider
,
error
)
func
newSplitProviderSelector
(
topProvider
types
.
TraceProvider
,
topDepth
int
,
bottomProviderCreator
ProviderCreator
)
trace
.
ProviderSelector
{
return
func
(
ctx
context
.
Context
,
game
types
.
Game
,
ref
types
.
Claim
,
pos
types
.
Position
)
(
types
.
TraceProvider
,
error
)
{
if
pos
.
Depth
()
<=
topDepth
{
return
topProvider
,
nil
}
if
ref
.
Position
.
Depth
()
<
topDepth
{
return
nil
,
fmt
.
Errorf
(
"%w, claim depth: %v, depth required: %v"
,
errRefClaimNotDeepEnough
,
ref
.
Position
.
Depth
(),
topDepth
)
}
// Find the ancestor claim at the leaf level for the top game.
topLeaf
,
err
:=
findAncestorAtDepth
(
game
,
ref
,
topDepth
)
if
err
!=
nil
{
return
nil
,
err
}
var
pre
,
post
types
.
Claim
// If pos is to the right of the leaf from the top game, we must be defending that output root
// otherwise, we're attacking it.
if
pos
.
TraceIndex
(
pos
.
Depth
())
.
Cmp
(
topLeaf
.
TraceIndex
(
pos
.
Depth
()))
>
0
{
// Defending the top leaf claim, so use it as the pre-claim and find the post
pre
=
topLeaf
postTraceIdx
:=
new
(
big
.
Int
)
.
Add
(
pre
.
TraceIndex
(
topDepth
),
big
.
NewInt
(
1
))
post
,
err
=
findAncestorWithTraceIndex
(
game
,
topLeaf
,
topDepth
,
postTraceIdx
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to find post claim: %w"
,
err
)
}
}
else
{
// Attacking the top leaf claim, so use it as the post-claim and find the pre
post
=
topLeaf
postTraceIdx
:=
post
.
TraceIndex
(
topDepth
)
if
postTraceIdx
.
Cmp
(
big
.
NewInt
(
0
))
==
0
{
pre
=
types
.
Claim
{}
}
else
{
preTraceIdx
:=
new
(
big
.
Int
)
.
Sub
(
postTraceIdx
,
big
.
NewInt
(
1
))
pre
,
err
=
findAncestorWithTraceIndex
(
game
,
topLeaf
,
topDepth
,
preTraceIdx
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to find pre claim: %w"
,
err
)
}
}
}
provider
,
err
:=
bottomProviderCreator
(
ctx
,
pre
,
post
)
// TODO: Translate the bottom provider
return
provider
,
err
}
}
func
findAncestorAtDepth
(
game
types
.
Game
,
claim
types
.
Claim
,
depth
int
)
(
types
.
Claim
,
error
)
{
for
claim
.
Depth
()
>
depth
{
parent
,
err
:=
game
.
GetParent
(
claim
)
if
err
!=
nil
{
return
types
.
Claim
{},
fmt
.
Errorf
(
"failed to find ancestor at depth %v: %w"
,
depth
,
err
)
}
claim
=
parent
}
return
claim
,
nil
}
func
findAncestorWithTraceIndex
(
game
types
.
Game
,
ref
types
.
Claim
,
depth
int
,
traceIdx
*
big
.
Int
)
(
types
.
Claim
,
error
)
{
candidate
:=
ref
for
candidate
.
TraceIndex
(
depth
)
.
Cmp
(
traceIdx
)
!=
0
{
parent
,
err
:=
game
.
GetParent
(
candidate
)
if
err
!=
nil
{
return
types
.
Claim
{},
fmt
.
Errorf
(
"failed to get parent of claim %v: %w"
,
candidate
.
ContractIndex
,
err
)
}
candidate
=
parent
}
return
candidate
,
nil
}
op-challenger/game/fault/trace/outputs/split_test.go
0 → 100644
View file @
2e4de94b
This diff is collapsed.
Click to expand it.
op-challenger/game/fault/trace/split/provider.go
deleted
100644 → 0
View file @
6c4a9ac4
package
split
import
(
"context"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
)
var
_
types
.
TraceProvider
=
(
*
SplitTraceProvider
)(
nil
)
// SplitTraceProvider is a [types.TraceProvider] implementation that
// routes requests to the correct internal trace provider based on the
// depth of the requested trace.
type
SplitTraceProvider
struct
{
logger
log
.
Logger
topProvider
types
.
TraceProvider
bottomProvider
types
.
TraceProvider
topDepth
uint64
}
// NewTraceProvider creates a new [SplitTraceProvider] instance.
// The [topDepth] parameter specifies the depth at which the internal
// [types.TraceProvider] should be switched.
func
NewTraceProvider
(
logger
log
.
Logger
,
topProvider
types
.
TraceProvider
,
bottomProvider
types
.
TraceProvider
,
topDepth
uint64
)
*
SplitTraceProvider
{
return
&
SplitTraceProvider
{
logger
:
logger
,
topProvider
:
topProvider
,
bottomProvider
:
bottomProvider
,
topDepth
:
topDepth
,
}
}
func
(
s
*
SplitTraceProvider
)
providerForDepth
(
depth
uint64
)
(
uint64
,
types
.
TraceProvider
)
{
if
depth
<=
s
.
topDepth
{
return
0
,
s
.
topProvider
}
return
s
.
topDepth
,
s
.
bottomProvider
}
// Get routes the Get request to the internal [types.TraceProvider] that
// that serves the trace index at the depth.
func
(
s
*
SplitTraceProvider
)
Get
(
ctx
context
.
Context
,
pos
types
.
Position
)
(
common
.
Hash
,
error
)
{
ancestorDepth
,
provider
:=
s
.
providerForDepth
(
uint64
(
pos
.
Depth
()))
relativePosition
,
err
:=
pos
.
RelativeToAncestorAtDepth
(
ancestorDepth
)
if
err
!=
nil
{
return
common
.
Hash
{},
err
}
return
provider
.
Get
(
ctx
,
relativePosition
)
}
// AbsolutePreStateCommitment returns the absolute prestate from the lowest internal [types.TraceProvider]
func
(
s
*
SplitTraceProvider
)
AbsolutePreStateCommitment
(
ctx
context
.
Context
)
(
hash
common
.
Hash
,
err
error
)
{
return
s
.
bottomProvider
.
AbsolutePreStateCommitment
(
ctx
)
}
// GetStepData routes the GetStepData request to the lowest internal [types.TraceProvider].
func
(
s
*
SplitTraceProvider
)
GetStepData
(
ctx
context
.
Context
,
pos
types
.
Position
)
(
prestate
[]
byte
,
proofData
[]
byte
,
preimageData
*
types
.
PreimageOracleData
,
err
error
)
{
ancestorDepth
,
provider
:=
s
.
providerForDepth
(
uint64
(
pos
.
Depth
()))
relativePosition
,
err
:=
pos
.
RelativeToAncestorAtDepth
(
ancestorDepth
)
if
err
!=
nil
{
return
nil
,
nil
,
nil
,
err
}
return
provider
.
GetStepData
(
ctx
,
relativePosition
)
}
op-challenger/game/fault/trace/split/provider_test.go
deleted
100644 → 0
View file @
6c4a9ac4
package
split
import
(
"context"
"errors"
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
)
var
(
mockGetError
=
errors
.
New
(
"mock get error"
)
mockOutput
=
common
.
HexToHash
(
"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
)
mockCommitment
=
common
.
HexToHash
(
"0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
)
)
func
TestGet
(
t
*
testing
.
T
)
{
t
.
Run
(
"ErrorBubblesUp"
,
func
(
t
*
testing
.
T
)
{
mockOutputProvider
:=
mockTraceProvider
{
getError
:
mockGetError
}
splitProvider
:=
newSplitTraceProvider
(
t
,
&
mockOutputProvider
,
nil
,
40
)
_
,
err
:=
splitProvider
.
Get
(
context
.
Background
(),
types
.
NewPosition
(
1
,
common
.
Big0
))
require
.
ErrorIs
(
t
,
err
,
mockGetError
)
})
t
.
Run
(
"ReturnsCorrectOutputFromTopProvider"
,
func
(
t
*
testing
.
T
)
{
mockOutputProvider
:=
mockTraceProvider
{
getOutput
:
mockOutput
}
splitProvider
:=
newSplitTraceProvider
(
t
,
&
mockOutputProvider
,
&
mockTraceProvider
{},
40
)
output
,
err
:=
splitProvider
.
Get
(
context
.
Background
(),
types
.
NewPosition
(
6
,
big
.
NewInt
(
3
)))
require
.
NoError
(
t
,
err
)
expectedGIndex
:=
types
.
NewPosition
(
6
,
big
.
NewInt
(
3
))
.
ToGIndex
()
require
.
Equal
(
t
,
common
.
BigToHash
(
expectedGIndex
),
output
)
})
t
.
Run
(
"ReturnsCorrectOutputWithMultipleProviders"
,
func
(
t
*
testing
.
T
)
{
bottomProvider
:=
mockTraceProvider
{
getOutput
:
mockOutput
}
splitProvider
:=
newSplitTraceProvider
(
t
,
&
mockTraceProvider
{},
&
bottomProvider
,
40
)
output
,
err
:=
splitProvider
.
Get
(
context
.
Background
(),
types
.
NewPosition
(
42
,
big
.
NewInt
(
17
)))
require
.
NoError
(
t
,
err
)
expectedGIndex
:=
types
.
NewPosition
(
2
,
big
.
NewInt
(
1
))
.
ToGIndex
()
require
.
Equal
(
t
,
common
.
BigToHash
(
expectedGIndex
),
output
)
})
}
func
TestAbsolutePreStateCommitment
(
t
*
testing
.
T
)
{
t
.
Run
(
"ErrorBubblesUp"
,
func
(
t
*
testing
.
T
)
{
mockOutputProvider
:=
mockTraceProvider
{
absolutePreStateCommitmentError
:
mockGetError
}
splitProvider
:=
newSplitTraceProvider
(
t
,
nil
,
&
mockOutputProvider
,
40
)
_
,
err
:=
splitProvider
.
AbsolutePreStateCommitment
(
context
.
Background
())
require
.
ErrorIs
(
t
,
err
,
mockGetError
)
})
t
.
Run
(
"ReturnsCorrectOutput"
,
func
(
t
*
testing
.
T
)
{
mockOutputProvider
:=
mockTraceProvider
{
absolutePreStateCommitment
:
mockCommitment
}
splitProvider
:=
newSplitTraceProvider
(
t
,
nil
,
&
mockOutputProvider
,
40
)
output
,
err
:=
splitProvider
.
AbsolutePreStateCommitment
(
context
.
Background
())
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
mockCommitment
,
output
)
})
}
func
TestGetStepData
(
t
*
testing
.
T
)
{
t
.
Run
(
"ErrorBubblesUp"
,
func
(
t
*
testing
.
T
)
{
mockOutputProvider
:=
mockTraceProvider
{
getStepDataError
:
mockGetError
}
splitProvider
:=
newSplitTraceProvider
(
t
,
&
mockOutputProvider
,
nil
,
40
)
_
,
_
,
_
,
err
:=
splitProvider
.
GetStepData
(
context
.
Background
(),
types
.
NewPosition
(
0
,
common
.
Big0
))
require
.
ErrorIs
(
t
,
err
,
mockGetError
)
})
t
.
Run
(
"ReturnsCorrectStepData"
,
func
(
t
*
testing
.
T
)
{
expectedStepData
:=
[]
byte
{
1
,
2
,
3
,
4
}
mockOutputProvider
:=
mockTraceProvider
{
stepPrestateData
:
expectedStepData
}
splitProvider
:=
newSplitTraceProvider
(
t
,
nil
,
&
mockOutputProvider
,
40
)
output
,
_
,
_
,
err
:=
splitProvider
.
GetStepData
(
context
.
Background
(),
types
.
NewPosition
(
41
,
common
.
Big0
))
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
expectedStepData
,
output
)
})
}
type
mockTraceProvider
struct
{
getOutput
common
.
Hash
getError
error
absolutePreStateCommitmentError
error
absolutePreStateCommitment
common
.
Hash
absolutePreStateError
error
preImageData
[]
byte
getStepDataError
error
stepPrestateData
[]
byte
}
func
newSplitTraceProvider
(
t
*
testing
.
T
,
tp
*
mockTraceProvider
,
bp
*
mockTraceProvider
,
topDepth
uint64
)
SplitTraceProvider
{
return
SplitTraceProvider
{
logger
:
testlog
.
Logger
(
t
,
log
.
LvlInfo
),
topProvider
:
tp
,
bottomProvider
:
bp
,
topDepth
:
topDepth
,
}
}
func
(
m
*
mockTraceProvider
)
Get
(
ctx
context
.
Context
,
pos
types
.
Position
)
(
common
.
Hash
,
error
)
{
if
m
.
getError
!=
nil
{
return
common
.
Hash
{},
m
.
getError
}
return
common
.
BigToHash
(
pos
.
ToGIndex
()),
nil
}
func
(
m
*
mockTraceProvider
)
AbsolutePreStateCommitment
(
ctx
context
.
Context
)
(
hash
common
.
Hash
,
err
error
)
{
if
m
.
absolutePreStateCommitmentError
!=
nil
{
return
common
.
Hash
{},
m
.
absolutePreStateCommitmentError
}
return
m
.
absolutePreStateCommitment
,
nil
}
func
(
m
*
mockTraceProvider
)
AbsolutePreState
(
ctx
context
.
Context
)
(
preimage
[]
byte
,
err
error
)
{
if
m
.
absolutePreStateError
!=
nil
{
return
[]
byte
{},
m
.
absolutePreStateError
}
return
m
.
preImageData
,
nil
}
func
(
m
*
mockTraceProvider
)
GetStepData
(
ctx
context
.
Context
,
pos
types
.
Position
)
([]
byte
,
[]
byte
,
*
types
.
PreimageOracleData
,
error
)
{
if
m
.
getStepDataError
!=
nil
{
return
nil
,
nil
,
nil
,
m
.
getStepDataError
}
return
m
.
stepPrestateData
,
nil
,
nil
,
nil
}
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