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
3f7a8ad1
Unverified
Commit
3f7a8ad1
authored
Sep 04, 2024
by
clabby
Committed by
GitHub
Sep 04, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "challenger: Introduce StateConverter to abstract loading VM states (#…" (#11747)
This reverts commit
34101091
.
parent
2272a5de
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
339 additions
and
75 deletions
+339
-75
register_task.go
op-challenger/game/fault/register_task.go
+4
-4
prestate.go
op-challenger/game/fault/trace/asterisc/prestate.go
+45
-0
prestate_test.go
op-challenger/game/fault/trace/asterisc/prestate_test.go
+59
-0
provider.go
op-challenger/game/fault/trace/asterisc/provider.go
+24
-10
provider_test.go
op-challenger/game/fault/trace/asterisc/provider_test.go
+5
-6
state.go
op-challenger/game/fault/trace/asterisc/state.go
+0
-25
prestate.go
op-challenger/game/fault/trace/cannon/prestate.go
+47
-0
prestate_test.go
op-challenger/game/fault/trace/cannon/prestate_test.go
+89
-0
provider.go
op-challenger/game/fault/trace/cannon/provider.go
+31
-12
provider_test.go
op-challenger/game/fault/trace/cannon/provider_test.go
+5
-6
state.go
op-challenger/game/fault/trace/cannon/state.go
+27
-0
iface.go
op-challenger/game/fault/trace/vm/iface.go
+0
-9
factory.go
op-challenger/runner/factory.go
+3
-3
No files found.
op-challenger/game/fault/register_task.go
View file @
3f7a8ad1
...
@@ -57,7 +57,7 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c
...
@@ -57,7 +57,7 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c
cfg
.
CannonAbsolutePreState
,
cfg
.
CannonAbsolutePreState
,
filepath
.
Join
(
cfg
.
Datadir
,
"cannon-prestates"
),
filepath
.
Join
(
cfg
.
Datadir
,
"cannon-prestates"
),
func
(
path
string
)
faultTypes
.
PrestateProvider
{
func
(
path
string
)
faultTypes
.
PrestateProvider
{
return
vm
.
NewPrestateProvider
(
path
,
cannon
.
NewStateConverter
()
)
return
cannon
.
NewPrestateProvider
(
path
)
}),
}),
newTraceAccessor
:
func
(
newTraceAccessor
:
func
(
logger
log
.
Logger
,
logger
log
.
Logger
,
...
@@ -71,7 +71,7 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c
...
@@ -71,7 +71,7 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c
splitDepth
faultTypes
.
Depth
,
splitDepth
faultTypes
.
Depth
,
prestateBlock
uint64
,
prestateBlock
uint64
,
poststateBlock
uint64
)
(
*
trace
.
Accessor
,
error
)
{
poststateBlock
uint64
)
(
*
trace
.
Accessor
,
error
)
{
provider
:=
vmPrestateProvider
.
(
*
vm
.
PrestateProvider
)
provider
:=
vmPrestateProvider
.
(
*
cannon
.
Cannon
PrestateProvider
)
return
outputs
.
NewOutputCannonTraceAccessor
(
logger
,
m
,
cfg
.
Cannon
,
serverExecutor
,
l2Client
,
prestateProvider
,
provider
.
PrestatePath
(),
rollupClient
,
dir
,
l1Head
,
splitDepth
,
prestateBlock
,
poststateBlock
)
return
outputs
.
NewOutputCannonTraceAccessor
(
logger
,
m
,
cfg
.
Cannon
,
serverExecutor
,
l2Client
,
prestateProvider
,
provider
.
PrestatePath
(),
rollupClient
,
dir
,
l1Head
,
splitDepth
,
prestateBlock
,
poststateBlock
)
},
},
}
}
...
@@ -87,7 +87,7 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m
...
@@ -87,7 +87,7 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m
cfg
.
AsteriscAbsolutePreState
,
cfg
.
AsteriscAbsolutePreState
,
filepath
.
Join
(
cfg
.
Datadir
,
"asterisc-prestates"
),
filepath
.
Join
(
cfg
.
Datadir
,
"asterisc-prestates"
),
func
(
path
string
)
faultTypes
.
PrestateProvider
{
func
(
path
string
)
faultTypes
.
PrestateProvider
{
return
vm
.
NewPrestateProvider
(
path
,
asterisc
.
NewStateConverter
()
)
return
asterisc
.
NewPrestateProvider
(
path
)
}),
}),
newTraceAccessor
:
func
(
newTraceAccessor
:
func
(
logger
log
.
Logger
,
logger
log
.
Logger
,
...
@@ -101,7 +101,7 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m
...
@@ -101,7 +101,7 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m
splitDepth
faultTypes
.
Depth
,
splitDepth
faultTypes
.
Depth
,
prestateBlock
uint64
,
prestateBlock
uint64
,
poststateBlock
uint64
)
(
*
trace
.
Accessor
,
error
)
{
poststateBlock
uint64
)
(
*
trace
.
Accessor
,
error
)
{
provider
:=
vmPrestateProvider
.
(
*
vm
.
Pres
tateProvider
)
provider
:=
vmPrestateProvider
.
(
*
asterisc
.
AsteriscPreS
tateProvider
)
return
outputs
.
NewOutputAsteriscTraceAccessor
(
logger
,
m
,
cfg
.
Asterisc
,
serverExecutor
,
l2Client
,
prestateProvider
,
provider
.
PrestatePath
(),
rollupClient
,
dir
,
l1Head
,
splitDepth
,
prestateBlock
,
poststateBlock
)
return
outputs
.
NewOutputAsteriscTraceAccessor
(
logger
,
m
,
cfg
.
Asterisc
,
serverExecutor
,
l2Client
,
prestateProvider
,
provider
.
PrestatePath
(),
rollupClient
,
dir
,
l1Head
,
splitDepth
,
prestateBlock
,
poststateBlock
)
},
},
}
}
...
...
op-challenger/game/fault/trace/
vm
/prestate.go
→
op-challenger/game/fault/trace/
asterisc
/prestate.go
View file @
3f7a8ad1
package
vm
package
asterisc
import
(
import
(
"context"
"context"
"fmt"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum/go-ethereum/common"
)
)
var
_
types
.
PrestateProvider
=
(
*
Pres
tateProvider
)(
nil
)
var
_
types
.
PrestateProvider
=
(
*
AsteriscPreS
tateProvider
)(
nil
)
type
PrestateProvider
struct
{
type
AsteriscPreStateProvider
struct
{
prestate
string
prestate
string
stateConverter
StateConverter
prestateCommitment
common
.
Hash
prestateCommitment
common
.
Hash
}
}
func
NewPrestateProvider
(
prestate
string
,
converter
StateConverter
)
*
PrestateProvider
{
func
NewPrestateProvider
(
prestate
string
)
*
AsteriscPreStateProvider
{
return
&
PrestateProvider
{
return
&
AsteriscPreStateProvider
{
prestate
:
prestate
}
prestate
:
prestate
,
}
stateConverter
:
converter
,
func
(
p
*
AsteriscPreStateProvider
)
absolutePreState
()
(
*
VMState
,
error
)
{
state
,
err
:=
parseState
(
p
.
prestate
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"cannot load absolute pre-state: %w"
,
err
)
}
}
return
state
,
nil
}
}
func
(
p
*
Pres
tateProvider
)
AbsolutePreStateCommitment
(
_
context
.
Context
)
(
common
.
Hash
,
error
)
{
func
(
p
*
AsteriscPreS
tateProvider
)
AbsolutePreStateCommitment
(
_
context
.
Context
)
(
common
.
Hash
,
error
)
{
if
p
.
prestateCommitment
!=
(
common
.
Hash
{})
{
if
p
.
prestateCommitment
!=
(
common
.
Hash
{})
{
return
p
.
prestateCommitment
,
nil
return
p
.
prestateCommitment
,
nil
}
}
proof
,
_
,
_
,
err
:=
p
.
stateConverter
.
ConvertStateToProof
(
p
.
prestate
)
state
,
err
:=
p
.
absolutePreState
(
)
if
err
!=
nil
{
if
err
!=
nil
{
return
common
.
Hash
{},
fmt
.
Errorf
(
"cannot load absolute pre-state: %w"
,
err
)
return
common
.
Hash
{},
fmt
.
Errorf
(
"cannot load absolute pre-state: %w"
,
err
)
}
}
p
.
prestateCommitment
=
proof
.
ClaimValue
p
.
prestateCommitment
=
state
.
StateHash
return
proof
.
ClaimValue
,
nil
return
state
.
StateHash
,
nil
}
}
func
(
p
*
Pres
tateProvider
)
PrestatePath
()
string
{
func
(
p
*
AsteriscPreS
tateProvider
)
PrestatePath
()
string
{
return
p
.
prestate
return
p
.
prestate
}
}
op-challenger/game/fault/trace/
vm
/prestate_test.go
→
op-challenger/game/fault/trace/
asterisc
/prestate_test.go
View file @
3f7a8ad1
package
vm
package
asterisc
import
(
import
(
"context"
"context"
"
error
s"
"
o
s"
"path/filepath"
"path/filepath"
"testing"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/require"
)
)
type
stubConverter
struct
{
func
newAsteriscPrestateProvider
(
dataDir
string
,
prestate
string
)
*
AsteriscPreStateProvider
{
err
error
return
&
AsteriscPreStateProvider
{
hash
common
.
Hash
prestate
:
filepath
.
Join
(
dataDir
,
prestate
),
}
func
(
s
*
stubConverter
)
ConvertStateToProof
(
statePath
string
)
(
*
utils
.
ProofData
,
uint64
,
bool
,
error
)
{
if
s
.
err
!=
nil
{
return
nil
,
0
,
false
,
s
.
err
}
}
return
&
utils
.
ProofData
{
ClaimValue
:
s
.
hash
,
},
0
,
false
,
nil
}
func
newPrestateProvider
(
prestate
common
.
Hash
)
*
PrestateProvider
{
return
NewPrestateProvider
(
"state.json"
,
&
stubConverter
{
hash
:
prestate
})
}
}
func
TestAbsolutePreStateCommitment
(
t
*
testing
.
T
)
{
func
TestAbsolutePreStateCommitment
(
t
*
testing
.
T
)
{
prestate
:=
common
.
Hash
{
0xaa
,
0xbb
}
dataDir
:=
t
.
TempDir
()
prestate
:=
"state.json"
t
.
Run
(
"StateUnavailable"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"StateUnavailable"
,
func
(
t
*
testing
.
T
)
{
expectedErr
:=
errors
.
New
(
"kaboom"
)
provider
:=
newAsteriscPrestateProvider
(
"/dir/does/not/exist"
,
prestate
)
provider
:=
NewPrestateProvider
(
"foo"
,
&
stubConverter
{
err
:
expectedErr
})
_
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
())
_
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
())
require
.
ErrorIs
(
t
,
err
,
expectedErr
)
require
.
ErrorIs
(
t
,
err
,
os
.
ErrNotExist
)
})
})
t
.
Run
(
"
ExpectedAbsolutePreStat
e"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"
InvalidStateFil
e"
,
func
(
t
*
testing
.
T
)
{
provider
:=
newPrestateProvider
(
prestate
)
setupPreState
(
t
,
dataDir
,
"invalid.json"
)
actual
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
()
)
provider
:=
newAsteriscPrestateProvider
(
dataDir
,
prestate
)
require
.
NoError
(
t
,
err
)
_
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
()
)
require
.
E
qual
(
t
,
prestate
,
actual
)
require
.
E
rrorContains
(
t
,
err
,
"invalid asterisc VM state"
)
})
})
t
.
Run
(
"CacheAbsolutePreState"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"CacheAbsolutePreState"
,
func
(
t
*
testing
.
T
)
{
converter
:=
&
stubConverter
{
hash
:
prestate
}
setupPreState
(
t
,
dataDir
,
prestate
)
provider
:=
NewPrestateProvider
(
filepath
.
Join
(
"state.json"
),
converter
)
provider
:=
newAsteriscPrestateProvider
(
dataDir
,
prestate
)
first
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
())
first
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
())
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
// Remove the prestate from disk
// Remove the prestate from disk
converter
.
err
=
errors
.
New
(
"no soup for you"
)
require
.
NoError
(
t
,
os
.
Remove
(
provider
.
prestate
)
)
// Value should still be available from cache
// Value should still be available from cache
cached
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
())
cached
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
())
...
@@ -61,3 +48,12 @@ func TestAbsolutePreStateCommitment(t *testing.T) {
...
@@ -61,3 +48,12 @@ func TestAbsolutePreStateCommitment(t *testing.T) {
require
.
Equal
(
t
,
first
,
cached
)
require
.
Equal
(
t
,
first
,
cached
)
})
})
}
}
func
setupPreState
(
t
*
testing
.
T
,
dataDir
string
,
filename
string
)
{
srcDir
:=
filepath
.
Join
(
"test_data"
)
path
:=
filepath
.
Join
(
srcDir
,
filename
)
file
,
err
:=
testData
.
ReadFile
(
path
)
require
.
NoErrorf
(
t
,
err
,
"reading %v"
,
path
)
err
=
os
.
WriteFile
(
filepath
.
Join
(
dataDir
,
"state.json"
),
file
,
0
o644
)
require
.
NoErrorf
(
t
,
err
,
"writing %v"
,
path
)
}
op-challenger/game/fault/trace/asterisc/provider.go
View file @
3f7a8ad1
...
@@ -27,7 +27,6 @@ type AsteriscTraceProvider struct {
...
@@ -27,7 +27,6 @@ type AsteriscTraceProvider struct {
generator
utils
.
ProofGenerator
generator
utils
.
ProofGenerator
gameDepth
types
.
Depth
gameDepth
types
.
Depth
preimageLoader
*
utils
.
PreimageLoader
preimageLoader
*
utils
.
PreimageLoader
stateConverter
vm
.
StateConverter
types
.
PrestateProvider
types
.
PrestateProvider
...
@@ -47,7 +46,6 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm.
...
@@ -47,7 +46,6 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm.
return
kvstore
.
NewFileKV
(
vm
.
PreimageDir
(
dir
))
return
kvstore
.
NewFileKV
(
vm
.
PreimageDir
(
dir
))
}),
}),
PrestateProvider
:
prestateProvider
,
PrestateProvider
:
prestateProvider
,
stateConverter
:
NewStateConverter
(),
}
}
}
}
...
@@ -122,23 +120,31 @@ func (p *AsteriscTraceProvider) loadProof(ctx context.Context, i uint64) (*utils
...
@@ -122,23 +120,31 @@ func (p *AsteriscTraceProvider) loadProof(ctx context.Context, i uint64) (*utils
file
,
err
=
ioutil
.
OpenDecompressed
(
path
)
file
,
err
=
ioutil
.
OpenDecompressed
(
path
)
if
errors
.
Is
(
err
,
os
.
ErrNotExist
)
{
if
errors
.
Is
(
err
,
os
.
ErrNotExist
)
{
// Expected proof wasn't generated, check if we reached the end of execution
// Expected proof wasn't generated, check if we reached the end of execution
proof
,
step
,
exited
,
err
:=
p
.
stateConverter
.
ConvertStateToProof
(
filepath
.
Join
(
p
.
dir
,
vm
.
FinalState
)
)
state
,
err
:=
p
.
finalState
(
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
if
exited
&&
s
tep
<=
i
{
if
state
.
Exited
&&
state
.
S
tep
<=
i
{
p
.
logger
.
Warn
(
"Requested proof was after the program exited"
,
"proof"
,
i
,
"last"
,
step
)
p
.
logger
.
Warn
(
"Requested proof was after the program exited"
,
"proof"
,
i
,
"last"
,
st
ate
.
St
ep
)
// The final instruction has already been applied to this state, so the last step we can execute
// The final instruction has already been applied to this state, so the last step we can execute
// is one before its Step value.
// is one before its Step value.
p
.
lastStep
=
step
-
1
p
.
lastStep
=
st
ate
.
St
ep
-
1
// Extend the trace out to the full length using a no-op instruction that doesn't change any state
// Extend the trace out to the full length using a no-op instruction that doesn't change any state
// No execution is done, so no proof-data or oracle values are required.
// No execution is done, so no proof-data or oracle values are required.
proof
:=
&
utils
.
ProofData
{
ClaimValue
:
state
.
StateHash
,
StateData
:
state
.
Witness
,
ProofData
:
[]
byte
{},
OracleKey
:
nil
,
OracleValue
:
nil
,
OracleOffset
:
0
,
}
if
err
:=
utils
.
WriteLastStep
(
p
.
dir
,
proof
,
p
.
lastStep
);
err
!=
nil
{
if
err
:=
utils
.
WriteLastStep
(
p
.
dir
,
proof
,
p
.
lastStep
);
err
!=
nil
{
p
.
logger
.
Warn
(
"Failed to write last step to disk cache"
,
"step"
,
p
.
lastStep
)
p
.
logger
.
Warn
(
"Failed to write last step to disk cache"
,
"step"
,
p
.
lastStep
)
}
}
return
proof
,
nil
return
proof
,
nil
}
else
{
}
else
{
return
nil
,
fmt
.
Errorf
(
"expected proof not generated but final state was not exited, requested step %v, final state at step %v"
,
i
,
step
)
return
nil
,
fmt
.
Errorf
(
"expected proof not generated but final state was not exited, requested step %v, final state at step %v"
,
i
,
st
ate
.
St
ep
)
}
}
}
}
}
}
...
@@ -154,6 +160,14 @@ func (p *AsteriscTraceProvider) loadProof(ctx context.Context, i uint64) (*utils
...
@@ -154,6 +160,14 @@ func (p *AsteriscTraceProvider) loadProof(ctx context.Context, i uint64) (*utils
return
&
proof
,
nil
return
&
proof
,
nil
}
}
func
(
c
*
AsteriscTraceProvider
)
finalState
()
(
*
VMState
,
error
)
{
state
,
err
:=
parseState
(
filepath
.
Join
(
c
.
dir
,
vm
.
FinalState
))
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"cannot read final state: %w"
,
err
)
}
return
state
,
nil
}
// AsteriscTraceProviderForTest is a AsteriscTraceProvider that can find the step referencing the preimage read
// AsteriscTraceProviderForTest is a AsteriscTraceProvider that can find the step referencing the preimage read
// Only to be used for testing
// Only to be used for testing
type
AsteriscTraceProviderForTest
struct
{
type
AsteriscTraceProviderForTest
struct
{
...
@@ -180,14 +194,14 @@ func (p *AsteriscTraceProviderForTest) FindStep(ctx context.Context, start uint6
...
@@ -180,14 +194,14 @@ func (p *AsteriscTraceProviderForTest) FindStep(ctx context.Context, start uint6
return
0
,
fmt
.
Errorf
(
"generate asterisc trace (until preimage read): %w"
,
err
)
return
0
,
fmt
.
Errorf
(
"generate asterisc trace (until preimage read): %w"
,
err
)
}
}
// Load the step from the state asterisc finished with
// Load the step from the state asterisc finished with
_
,
step
,
exited
,
err
:=
p
.
stateConverter
.
ConvertStateToProof
(
filepath
.
Join
(
p
.
dir
,
vm
.
FinalState
)
)
state
,
err
:=
p
.
finalState
(
)
if
err
!=
nil
{
if
err
!=
nil
{
return
0
,
fmt
.
Errorf
(
"failed to load final state: %w"
,
err
)
return
0
,
fmt
.
Errorf
(
"failed to load final state: %w"
,
err
)
}
}
// Check we didn't get to the end of the trace without finding the preimage read we were looking for
// Check we didn't get to the end of the trace without finding the preimage read we were looking for
if
e
xited
{
if
state
.
E
xited
{
return
0
,
fmt
.
Errorf
(
"preimage read not found: %w"
,
io
.
EOF
)
return
0
,
fmt
.
Errorf
(
"preimage read not found: %w"
,
io
.
EOF
)
}
}
// The state is the post-state so the step we want to execute to read the preimage is step - 1.
// The state is the post-state so the step we want to execute to read the preimage is step - 1.
return
step
-
1
,
nil
return
st
ate
.
St
ep
-
1
,
nil
}
}
op-challenger/game/fault/trace/asterisc/provider_test.go
View file @
3f7a8ad1
...
@@ -221,12 +221,11 @@ func setupTestData(t *testing.T) (string, string) {
...
@@ -221,12 +221,11 @@ func setupTestData(t *testing.T) (string, string) {
func
setupWithTestData
(
t
*
testing
.
T
,
dataDir
string
,
prestate
string
)
(
*
AsteriscTraceProvider
,
*
stubGenerator
)
{
func
setupWithTestData
(
t
*
testing
.
T
,
dataDir
string
,
prestate
string
)
(
*
AsteriscTraceProvider
,
*
stubGenerator
)
{
generator
:=
&
stubGenerator
{}
generator
:=
&
stubGenerator
{}
return
&
AsteriscTraceProvider
{
return
&
AsteriscTraceProvider
{
logger
:
testlog
.
Logger
(
t
,
log
.
LevelInfo
),
logger
:
testlog
.
Logger
(
t
,
log
.
LevelInfo
),
dir
:
dataDir
,
dir
:
dataDir
,
generator
:
generator
,
generator
:
generator
,
prestate
:
filepath
.
Join
(
dataDir
,
prestate
),
prestate
:
filepath
.
Join
(
dataDir
,
prestate
),
gameDepth
:
63
,
gameDepth
:
63
,
stateConverter
:
&
StateConverter
{},
},
generator
},
generator
}
}
...
...
op-challenger/game/fault/trace/asterisc/state
_converter
.go
→
op-challenger/game/fault/trace/asterisc/state.go
View file @
3f7a8ad1
...
@@ -8,7 +8,6 @@ import (
...
@@ -8,7 +8,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum-optimism/optimism/cannon/mipsevm"
"github.com/ethereum-optimism/optimism/cannon/mipsevm"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum-optimism/optimism/op-service/ioutil"
"github.com/ethereum-optimism/optimism/op-service/ioutil"
)
)
...
@@ -75,27 +74,3 @@ func parseStateFromReader(in io.ReadCloser) (*VMState, error) {
...
@@ -75,27 +74,3 @@ func parseStateFromReader(in io.ReadCloser) (*VMState, error) {
}
}
return
&
state
,
nil
return
&
state
,
nil
}
}
type
StateConverter
struct
{
}
func
NewStateConverter
()
*
StateConverter
{
return
&
StateConverter
{}
}
func
(
c
*
StateConverter
)
ConvertStateToProof
(
statePath
string
)
(
*
utils
.
ProofData
,
uint64
,
bool
,
error
)
{
state
,
err
:=
parseState
(
statePath
)
if
err
!=
nil
{
return
nil
,
0
,
false
,
fmt
.
Errorf
(
"cannot read final state: %w"
,
err
)
}
// Extend the trace out to the full length using a no-op instruction that doesn't change any state
// No execution is done, so no proof-data or oracle values are required.
return
&
utils
.
ProofData
{
ClaimValue
:
state
.
StateHash
,
StateData
:
state
.
Witness
,
ProofData
:
[]
byte
{},
OracleKey
:
nil
,
OracleValue
:
nil
,
OracleOffset
:
0
,
},
state
.
Step
,
state
.
Exited
,
nil
}
op-challenger/game/fault/trace/cannon/prestate.go
0 → 100644
View file @
3f7a8ad1
package
cannon
import
(
"context"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
)
var
_
types
.
PrestateProvider
=
(
*
CannonPrestateProvider
)(
nil
)
type
CannonPrestateProvider
struct
{
prestate
string
prestateCommitment
common
.
Hash
}
func
NewPrestateProvider
(
prestate
string
)
*
CannonPrestateProvider
{
return
&
CannonPrestateProvider
{
prestate
:
prestate
}
}
func
(
p
*
CannonPrestateProvider
)
absolutePreState
()
([]
byte
,
common
.
Hash
,
error
)
{
state
,
err
:=
parseState
(
p
.
prestate
)
if
err
!=
nil
{
return
nil
,
common
.
Hash
{},
fmt
.
Errorf
(
"cannot load absolute pre-state: %w"
,
err
)
}
witness
,
hash
:=
state
.
EncodeWitness
()
return
witness
,
hash
,
nil
}
func
(
p
*
CannonPrestateProvider
)
AbsolutePreStateCommitment
(
_
context
.
Context
)
(
common
.
Hash
,
error
)
{
if
p
.
prestateCommitment
!=
(
common
.
Hash
{})
{
return
p
.
prestateCommitment
,
nil
}
_
,
hash
,
err
:=
p
.
absolutePreState
()
if
err
!=
nil
{
return
common
.
Hash
{},
fmt
.
Errorf
(
"cannot load absolute pre-state: %w"
,
err
)
}
p
.
prestateCommitment
=
hash
return
hash
,
nil
}
func
(
p
*
CannonPrestateProvider
)
PrestatePath
()
string
{
return
p
.
prestate
}
op-challenger/game/fault/trace/cannon/prestate_test.go
0 → 100644
View file @
3f7a8ad1
package
cannon
import
(
"context"
"os"
"path/filepath"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/cannon/mipsevm"
"github.com/ethereum-optimism/optimism/cannon/mipsevm/memory"
"github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded"
)
func
newCannonPrestateProvider
(
dataDir
string
,
prestate
string
)
*
CannonPrestateProvider
{
return
&
CannonPrestateProvider
{
prestate
:
filepath
.
Join
(
dataDir
,
prestate
),
}
}
func
TestAbsolutePreStateCommitment
(
t
*
testing
.
T
)
{
dataDir
:=
t
.
TempDir
()
prestate
:=
"state.json"
t
.
Run
(
"StateUnavailable"
,
func
(
t
*
testing
.
T
)
{
provider
:=
newCannonPrestateProvider
(
"/dir/does/not/exist"
,
prestate
)
_
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
())
require
.
ErrorIs
(
t
,
err
,
os
.
ErrNotExist
)
})
t
.
Run
(
"InvalidStateFile"
,
func
(
t
*
testing
.
T
)
{
setupPreState
(
t
,
dataDir
,
"invalid.json"
)
provider
:=
newCannonPrestateProvider
(
dataDir
,
prestate
)
_
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
())
require
.
ErrorContains
(
t
,
err
,
"invalid mipsevm state"
)
})
t
.
Run
(
"ExpectedAbsolutePreState"
,
func
(
t
*
testing
.
T
)
{
setupPreState
(
t
,
dataDir
,
"state.json"
)
provider
:=
newCannonPrestateProvider
(
dataDir
,
prestate
)
actual
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
())
require
.
NoError
(
t
,
err
)
state
:=
singlethreaded
.
State
{
Memory
:
memory
.
NewMemory
(),
PreimageKey
:
common
.
HexToHash
(
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
),
PreimageOffset
:
0
,
Cpu
:
mipsevm
.
CpuScalars
{
PC
:
0
,
NextPC
:
1
,
LO
:
0
,
HI
:
0
,
},
Heap
:
0
,
ExitCode
:
0
,
Exited
:
false
,
Step
:
0
,
Registers
:
[
32
]
uint32
{},
}
_
,
expected
:=
state
.
EncodeWitness
()
require
.
Equal
(
t
,
expected
,
actual
)
})
t
.
Run
(
"CacheAbsolutePreState"
,
func
(
t
*
testing
.
T
)
{
setupPreState
(
t
,
dataDir
,
prestate
)
provider
:=
newCannonPrestateProvider
(
dataDir
,
prestate
)
first
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
())
require
.
NoError
(
t
,
err
)
// Remove the prestate from disk
require
.
NoError
(
t
,
os
.
Remove
(
provider
.
prestate
))
// Value should still be available from cache
cached
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
())
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
first
,
cached
)
})
}
func
setupPreState
(
t
*
testing
.
T
,
dataDir
string
,
filename
string
)
{
srcDir
:=
filepath
.
Join
(
"test_data"
)
path
:=
filepath
.
Join
(
srcDir
,
filename
)
file
,
err
:=
testData
.
ReadFile
(
path
)
require
.
NoErrorf
(
t
,
err
,
"reading %v"
,
path
)
err
=
os
.
WriteFile
(
filepath
.
Join
(
dataDir
,
"state.json"
),
file
,
0
o644
)
require
.
NoErrorf
(
t
,
err
,
"writing %v"
,
path
)
}
op-challenger/game/fault/trace/cannon/provider.go
View file @
3f7a8ad1
...
@@ -11,8 +11,10 @@ import (
...
@@ -11,8 +11,10 @@ import (
"path/filepath"
"path/filepath"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm"
...
@@ -28,7 +30,6 @@ type CannonTraceProvider struct {
...
@@ -28,7 +30,6 @@ type CannonTraceProvider struct {
generator
utils
.
ProofGenerator
generator
utils
.
ProofGenerator
gameDepth
types
.
Depth
gameDepth
types
.
Depth
preimageLoader
*
utils
.
PreimageLoader
preimageLoader
*
utils
.
PreimageLoader
stateConverter
vm
.
StateConverter
types
.
PrestateProvider
types
.
PrestateProvider
...
@@ -48,7 +49,6 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm.
...
@@ -48,7 +49,6 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm.
return
kvstore
.
NewFileKV
(
vm
.
PreimageDir
(
dir
))
return
kvstore
.
NewFileKV
(
vm
.
PreimageDir
(
dir
))
}),
}),
PrestateProvider
:
prestateProvider
,
PrestateProvider
:
prestateProvider
,
stateConverter
:
&
StateConverter
{},
}
}
}
}
...
@@ -122,22 +122,33 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*utils.P
...
@@ -122,22 +122,33 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*utils.P
// Try opening the file again now and it should exist.
// Try opening the file again now and it should exist.
file
,
err
=
ioutil
.
OpenDecompressed
(
path
)
file
,
err
=
ioutil
.
OpenDecompressed
(
path
)
if
errors
.
Is
(
err
,
os
.
ErrNotExist
)
{
if
errors
.
Is
(
err
,
os
.
ErrNotExist
)
{
proof
,
stateStep
,
exited
,
err
:=
p
.
stateConverter
.
ConvertStateToProof
(
filepath
.
Join
(
p
.
dir
,
vm
.
FinalState
))
// Expected proof wasn't generated, check if we reached the end of execution
state
,
err
:=
p
.
finalState
()
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"cannot create proof from final state: %w"
,
err
)
return
nil
,
err
}
}
if
state
.
Exited
&&
state
.
Step
<=
i
{
if
exited
&&
stateStep
<=
i
{
p
.
logger
.
Warn
(
"Requested proof was after the program exited"
,
"proof"
,
i
,
"last"
,
state
.
Step
)
p
.
logger
.
Warn
(
"Requested proof was after the program exited"
,
"proof"
,
i
,
"last"
,
stateStep
)
// The final instruction has already been applied to this state, so the last step we can execute
// The final instruction has already been applied to this state, so the last step we can execute
// is one before its Step value.
// is one before its Step value.
p
.
lastStep
=
stateStep
-
1
p
.
lastStep
=
state
.
Step
-
1
// Extend the trace out to the full length using a no-op instruction that doesn't change any state
// No execution is done, so no proof-data or oracle values are required.
witness
,
witnessHash
:=
state
.
EncodeWitness
()
proof
:=
&
utils
.
ProofData
{
ClaimValue
:
witnessHash
,
StateData
:
hexutil
.
Bytes
(
witness
),
ProofData
:
[]
byte
{},
OracleKey
:
nil
,
OracleValue
:
nil
,
OracleOffset
:
0
,
}
if
err
:=
utils
.
WriteLastStep
(
p
.
dir
,
proof
,
p
.
lastStep
);
err
!=
nil
{
if
err
:=
utils
.
WriteLastStep
(
p
.
dir
,
proof
,
p
.
lastStep
);
err
!=
nil
{
p
.
logger
.
Warn
(
"Failed to write last step to disk cache"
,
"step"
,
p
.
lastStep
)
p
.
logger
.
Warn
(
"Failed to write last step to disk cache"
,
"step"
,
p
.
lastStep
)
}
}
return
proof
,
nil
return
proof
,
nil
}
else
{
}
else
{
return
nil
,
fmt
.
Errorf
(
"expected proof not generated but final state was not exited, requested step %v, final state at step %v"
,
i
,
stateStep
)
return
nil
,
fmt
.
Errorf
(
"expected proof not generated but final state was not exited, requested step %v, final state at step %v"
,
i
,
state
.
Step
)
}
}
}
}
}
}
...
@@ -153,6 +164,14 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*utils.P
...
@@ -153,6 +164,14 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*utils.P
return
&
proof
,
nil
return
&
proof
,
nil
}
}
func
(
c
*
CannonTraceProvider
)
finalState
()
(
*
singlethreaded
.
State
,
error
)
{
state
,
err
:=
parseState
(
filepath
.
Join
(
c
.
dir
,
vm
.
FinalState
))
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"cannot read final state: %w"
,
err
)
}
return
state
,
nil
}
// CannonTraceProviderForTest is a CannonTraceProvider that can find the step referencing the preimage read
// CannonTraceProviderForTest is a CannonTraceProvider that can find the step referencing the preimage read
// Only to be used for testing
// Only to be used for testing
type
CannonTraceProviderForTest
struct
{
type
CannonTraceProviderForTest
struct
{
...
@@ -179,14 +198,14 @@ func (p *CannonTraceProviderForTest) FindStep(ctx context.Context, start uint64,
...
@@ -179,14 +198,14 @@ func (p *CannonTraceProviderForTest) FindStep(ctx context.Context, start uint64,
return
0
,
fmt
.
Errorf
(
"generate cannon trace (until preimage read): %w"
,
err
)
return
0
,
fmt
.
Errorf
(
"generate cannon trace (until preimage read): %w"
,
err
)
}
}
// Load the step from the state cannon finished with
// Load the step from the state cannon finished with
_
,
step
,
exited
,
err
:=
p
.
stateConverter
.
ConvertStateToProof
(
filepath
.
Join
(
p
.
dir
,
vm
.
FinalState
)
)
state
,
err
:=
p
.
finalState
(
)
if
err
!=
nil
{
if
err
!=
nil
{
return
0
,
fmt
.
Errorf
(
"failed to load final state: %w"
,
err
)
return
0
,
fmt
.
Errorf
(
"failed to load final state: %w"
,
err
)
}
}
// Check we didn't get to the end of the trace without finding the preimage read we were looking for
// Check we didn't get to the end of the trace without finding the preimage read we were looking for
if
e
xited
{
if
state
.
E
xited
{
return
0
,
fmt
.
Errorf
(
"preimage read not found: %w"
,
io
.
EOF
)
return
0
,
fmt
.
Errorf
(
"preimage read not found: %w"
,
io
.
EOF
)
}
}
// The state is the post-state so the step we want to execute to read the preimage is step - 1.
// The state is the post-state so the step we want to execute to read the preimage is step - 1.
return
step
-
1
,
nil
return
st
ate
.
St
ep
-
1
,
nil
}
}
op-challenger/game/fault/trace/cannon/provider_test.go
View file @
3f7a8ad1
...
@@ -239,12 +239,11 @@ func setupTestData(t *testing.T) (string, string) {
...
@@ -239,12 +239,11 @@ func setupTestData(t *testing.T) (string, string) {
func
setupWithTestData
(
t
*
testing
.
T
,
dataDir
string
,
prestate
string
)
(
*
CannonTraceProvider
,
*
stubGenerator
)
{
func
setupWithTestData
(
t
*
testing
.
T
,
dataDir
string
,
prestate
string
)
(
*
CannonTraceProvider
,
*
stubGenerator
)
{
generator
:=
&
stubGenerator
{}
generator
:=
&
stubGenerator
{}
return
&
CannonTraceProvider
{
return
&
CannonTraceProvider
{
logger
:
testlog
.
Logger
(
t
,
log
.
LevelInfo
),
logger
:
testlog
.
Logger
(
t
,
log
.
LevelInfo
),
dir
:
dataDir
,
dir
:
dataDir
,
generator
:
generator
,
generator
:
generator
,
prestate
:
filepath
.
Join
(
dataDir
,
prestate
),
prestate
:
filepath
.
Join
(
dataDir
,
prestate
),
gameDepth
:
63
,
gameDepth
:
63
,
stateConverter
:
&
StateConverter
{},
},
generator
},
generator
}
}
...
...
op-challenger/game/fault/trace/cannon/state
_converter
.go
→
op-challenger/game/fault/trace/cannon/state.go
View file @
3f7a8ad1
...
@@ -6,35 +6,9 @@ import (
...
@@ -6,35 +6,9 @@ import (
"io"
"io"
"github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded"
"github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum-optimism/optimism/op-service/ioutil"
"github.com/ethereum-optimism/optimism/op-service/ioutil"
)
)
type
StateConverter
struct
{
}
func
NewStateConverter
()
*
StateConverter
{
return
&
StateConverter
{}
}
func
(
c
*
StateConverter
)
ConvertStateToProof
(
statePath
string
)
(
*
utils
.
ProofData
,
uint64
,
bool
,
error
)
{
state
,
err
:=
parseState
(
statePath
)
if
err
!=
nil
{
return
nil
,
0
,
false
,
fmt
.
Errorf
(
"cannot read final state: %w"
,
err
)
}
// Extend the trace out to the full length using a no-op instruction that doesn't change any state
// No execution is done, so no proof-data or oracle values are required.
witness
,
witnessHash
:=
state
.
EncodeWitness
()
return
&
utils
.
ProofData
{
ClaimValue
:
witnessHash
,
StateData
:
witness
,
ProofData
:
[]
byte
{},
OracleKey
:
nil
,
OracleValue
:
nil
,
OracleOffset
:
0
,
},
state
.
Step
,
state
.
Exited
,
nil
}
func
parseState
(
path
string
)
(
*
singlethreaded
.
State
,
error
)
{
func
parseState
(
path
string
)
(
*
singlethreaded
.
State
,
error
)
{
file
,
err
:=
ioutil
.
OpenDecompressed
(
path
)
file
,
err
:=
ioutil
.
OpenDecompressed
(
path
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
op-challenger/game/fault/trace/vm/iface.go
deleted
100644 → 0
View file @
2272a5de
package
vm
import
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
type
StateConverter
interface
{
// ConvertStateToProof reads the state snapshot at the specified path and converts it to ProofData.
// Returns the proof data, the VM step the state is from and whether or not the VM had exited.
ConvertStateToProof
(
statePath
string
)
(
*
utils
.
ProofData
,
uint64
,
bool
,
error
)
}
op-challenger/runner/factory.go
View file @
3f7a8ad1
...
@@ -33,7 +33,7 @@ func createTraceProvider(
...
@@ -33,7 +33,7 @@ func createTraceProvider(
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
prestateProvider
:=
vm
.
NewPrestateProvider
(
prestate
,
cannon
.
NewStateConverter
()
)
prestateProvider
:=
cannon
.
NewPrestateProvider
(
prestate
)
return
cannon
.
NewTraceProvider
(
logger
,
m
,
cfg
.
Cannon
,
vmConfig
,
prestateProvider
,
prestate
,
localInputs
,
dir
,
42
),
nil
return
cannon
.
NewTraceProvider
(
logger
,
m
,
cfg
.
Cannon
,
vmConfig
,
prestateProvider
,
prestate
,
localInputs
,
dir
,
42
),
nil
case
types
.
TraceTypeAsterisc
:
case
types
.
TraceTypeAsterisc
:
vmConfig
:=
vm
.
NewOpProgramServerExecutor
()
vmConfig
:=
vm
.
NewOpProgramServerExecutor
()
...
@@ -41,7 +41,7 @@ func createTraceProvider(
...
@@ -41,7 +41,7 @@ func createTraceProvider(
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
prestateProvider
:=
vm
.
NewPrestateProvider
(
prestate
,
asterisc
.
NewStateConverter
()
)
prestateProvider
:=
asterisc
.
NewPrestateProvider
(
prestate
)
return
asterisc
.
NewTraceProvider
(
logger
,
m
,
cfg
.
Asterisc
,
vmConfig
,
prestateProvider
,
prestate
,
localInputs
,
dir
,
42
),
nil
return
asterisc
.
NewTraceProvider
(
logger
,
m
,
cfg
.
Asterisc
,
vmConfig
,
prestateProvider
,
prestate
,
localInputs
,
dir
,
42
),
nil
case
types
.
TraceTypeAsteriscKona
:
case
types
.
TraceTypeAsteriscKona
:
vmConfig
:=
vm
.
NewKonaServerExecutor
()
vmConfig
:=
vm
.
NewKonaServerExecutor
()
...
@@ -49,7 +49,7 @@ func createTraceProvider(
...
@@ -49,7 +49,7 @@ func createTraceProvider(
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
prestateProvider
:=
vm
.
NewPrestateProvider
(
prestate
,
asterisc
.
NewStateConverter
()
)
prestateProvider
:=
asterisc
.
NewPrestateProvider
(
prestate
)
return
asterisc
.
NewTraceProvider
(
logger
,
m
,
cfg
.
Asterisc
,
vmConfig
,
prestateProvider
,
prestate
,
localInputs
,
dir
,
42
),
nil
return
asterisc
.
NewTraceProvider
(
logger
,
m
,
cfg
.
Asterisc
,
vmConfig
,
prestateProvider
,
prestate
,
localInputs
,
dir
,
42
),
nil
}
}
return
nil
,
errors
.
New
(
"invalid trace type"
)
return
nil
,
errors
.
New
(
"invalid trace type"
)
...
...
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