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
34101091
Unverified
Commit
34101091
authored
Sep 05, 2024
by
Adrian Sutton
Committed by
GitHub
Sep 04, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
challenger: Introduce StateConverter to abstract loading VM states (#11715)
parent
31f408bf
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
233 additions
and
208 deletions
+233
-208
register_task.go
op-challenger/game/fault/register_task.go
+4
-4
provider.go
op-challenger/game/fault/trace/asterisc/provider.go
+10
-24
provider_test.go
op-challenger/game/fault/trace/asterisc/provider_test.go
+6
-5
state_converter.go
op-challenger/game/fault/trace/asterisc/state_converter.go
+25
-0
prestate.go
op-challenger/game/fault/trace/cannon/prestate.go
+0
-47
prestate_test.go
op-challenger/game/fault/trace/cannon/prestate_test.go
+0
-89
provider.go
op-challenger/game/fault/trace/cannon/provider.go
+12
-31
provider_test.go
op-challenger/game/fault/trace/cannon/provider_test.go
+6
-5
state_converter.go
op-challenger/game/fault/trace/cannon/state_converter.go
+53
-0
iface.go
op-challenger/game/fault/trace/vm/iface.go
+9
-0
prestate.go
op-challenger/game/fault/trace/vm/prestate.go
+42
-0
prestate_test.go
op-challenger/game/fault/trace/vm/prestate_test.go
+63
-0
factory.go
op-challenger/runner/factory.go
+3
-3
No files found.
op-challenger/game/fault/register_task.go
View file @
34101091
...
...
@@ -57,7 +57,7 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c
cfg
.
CannonAbsolutePreState
,
filepath
.
Join
(
cfg
.
Datadir
,
"cannon-prestates"
),
func
(
path
string
)
faultTypes
.
PrestateProvider
{
return
cannon
.
NewPrestateProvider
(
path
)
return
vm
.
NewPrestateProvider
(
path
,
cannon
.
NewStateConverter
()
)
}),
newTraceAccessor
:
func
(
logger
log
.
Logger
,
...
...
@@ -71,7 +71,7 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c
splitDepth
faultTypes
.
Depth
,
prestateBlock
uint64
,
poststateBlock
uint64
)
(
*
trace
.
Accessor
,
error
)
{
provider
:=
vmPrestateProvider
.
(
*
cannon
.
Cannon
PrestateProvider
)
provider
:=
vmPrestateProvider
.
(
*
vm
.
PrestateProvider
)
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
cfg
.
AsteriscAbsolutePreState
,
filepath
.
Join
(
cfg
.
Datadir
,
"asterisc-prestates"
),
func
(
path
string
)
faultTypes
.
PrestateProvider
{
return
asterisc
.
NewPrestateProvider
(
path
)
return
vm
.
NewPrestateProvider
(
path
,
asterisc
.
NewStateConverter
()
)
}),
newTraceAccessor
:
func
(
logger
log
.
Logger
,
...
...
@@ -101,7 +101,7 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m
splitDepth
faultTypes
.
Depth
,
prestateBlock
uint64
,
poststateBlock
uint64
)
(
*
trace
.
Accessor
,
error
)
{
provider
:=
vmPrestateProvider
.
(
*
asterisc
.
AsteriscPreS
tateProvider
)
provider
:=
vmPrestateProvider
.
(
*
vm
.
Pres
tateProvider
)
return
outputs
.
NewOutputAsteriscTraceAccessor
(
logger
,
m
,
cfg
.
Asterisc
,
serverExecutor
,
l2Client
,
prestateProvider
,
provider
.
PrestatePath
(),
rollupClient
,
dir
,
l1Head
,
splitDepth
,
prestateBlock
,
poststateBlock
)
},
}
...
...
op-challenger/game/fault/trace/asterisc/provider.go
View file @
34101091
...
...
@@ -27,6 +27,7 @@ type AsteriscTraceProvider struct {
generator
utils
.
ProofGenerator
gameDepth
types
.
Depth
preimageLoader
*
utils
.
PreimageLoader
stateConverter
vm
.
StateConverter
types
.
PrestateProvider
...
...
@@ -46,6 +47,7 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm.
return
kvstore
.
NewFileKV
(
vm
.
PreimageDir
(
dir
))
}),
PrestateProvider
:
prestateProvider
,
stateConverter
:
NewStateConverter
(),
}
}
...
...
@@ -120,31 +122,23 @@ func (p *AsteriscTraceProvider) loadProof(ctx context.Context, i uint64) (*utils
file
,
err
=
ioutil
.
OpenDecompressed
(
path
)
if
errors
.
Is
(
err
,
os
.
ErrNotExist
)
{
// Expected proof wasn't generated, check if we reached the end of execution
state
,
err
:=
p
.
finalState
(
)
proof
,
step
,
exited
,
err
:=
p
.
stateConverter
.
ConvertStateToProof
(
filepath
.
Join
(
p
.
dir
,
vm
.
FinalState
)
)
if
err
!=
nil
{
return
nil
,
err
}
if
state
.
Exited
&&
state
.
S
tep
<=
i
{
p
.
logger
.
Warn
(
"Requested proof was after the program exited"
,
"proof"
,
i
,
"last"
,
st
ate
.
St
ep
)
if
exited
&&
s
tep
<=
i
{
p
.
logger
.
Warn
(
"Requested proof was after the program exited"
,
"proof"
,
i
,
"last"
,
step
)
// The final instruction has already been applied to this state, so the last step we can execute
// is one before its Step value.
p
.
lastStep
=
st
ate
.
St
ep
-
1
p
.
lastStep
=
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.
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
{
p
.
logger
.
Warn
(
"Failed to write last step to disk cache"
,
"step"
,
p
.
lastStep
)
}
return
proof
,
nil
}
else
{
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
)
return
nil
,
fmt
.
Errorf
(
"expected proof not generated but final state was not exited, requested step %v, final state at step %v"
,
i
,
step
)
}
}
}
...
...
@@ -160,14 +154,6 @@ func (p *AsteriscTraceProvider) loadProof(ctx context.Context, i uint64) (*utils
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
// Only to be used for testing
type
AsteriscTraceProviderForTest
struct
{
...
...
@@ -194,14 +180,14 @@ func (p *AsteriscTraceProviderForTest) FindStep(ctx context.Context, start uint6
return
0
,
fmt
.
Errorf
(
"generate asterisc trace (until preimage read): %w"
,
err
)
}
// Load the step from the state asterisc finished with
state
,
err
:=
p
.
finalState
(
)
_
,
step
,
exited
,
err
:=
p
.
stateConverter
.
ConvertStateToProof
(
filepath
.
Join
(
p
.
dir
,
vm
.
FinalState
)
)
if
err
!=
nil
{
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
if
state
.
E
xited
{
if
e
xited
{
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.
return
st
ate
.
St
ep
-
1
,
nil
return
step
-
1
,
nil
}
op-challenger/game/fault/trace/asterisc/provider_test.go
View file @
34101091
...
...
@@ -226,6 +226,7 @@ func setupWithTestData(t *testing.T, dataDir string, prestate string) (*Asterisc
generator
:
generator
,
prestate
:
filepath
.
Join
(
dataDir
,
prestate
),
gameDepth
:
63
,
stateConverter
:
&
StateConverter
{},
},
generator
}
...
...
op-challenger/game/fault/trace/asterisc/state.go
→
op-challenger/game/fault/trace/asterisc/state
_converter
.go
View file @
34101091
...
...
@@ -8,6 +8,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"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"
)
...
...
@@ -74,3 +75,27 @@ func parseStateFromReader(in io.ReadCloser) (*VMState, error) {
}
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
deleted
100644 → 0
View file @
31f408bf
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
deleted
100644 → 0
View file @
31f408bf
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 @
34101091
...
...
@@ -11,10 +11,8 @@ import (
"path/filepath"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"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/game/fault/trace/utils"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm"
...
...
@@ -30,6 +28,7 @@ type CannonTraceProvider struct {
generator
utils
.
ProofGenerator
gameDepth
types
.
Depth
preimageLoader
*
utils
.
PreimageLoader
stateConverter
vm
.
StateConverter
types
.
PrestateProvider
...
...
@@ -49,6 +48,7 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm.
return
kvstore
.
NewFileKV
(
vm
.
PreimageDir
(
dir
))
}),
PrestateProvider
:
prestateProvider
,
stateConverter
:
&
StateConverter
{},
}
}
...
...
@@ -122,33 +122,22 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*utils.P
// Try opening the file again now and it should exist.
file
,
err
=
ioutil
.
OpenDecompressed
(
path
)
if
errors
.
Is
(
err
,
os
.
ErrNotExist
)
{
// Expected proof wasn't generated, check if we reached the end of execution
state
,
err
:=
p
.
finalState
()
proof
,
stateStep
,
exited
,
err
:=
p
.
stateConverter
.
ConvertStateToProof
(
filepath
.
Join
(
p
.
dir
,
vm
.
FinalState
))
if
err
!=
nil
{
return
nil
,
err
return
nil
,
fmt
.
Errorf
(
"cannot create proof from final state: %w"
,
err
)
}
if
state
.
Exited
&&
state
.
Step
<=
i
{
p
.
logger
.
Warn
(
"Requested proof was after the program exited"
,
"proof"
,
i
,
"last"
,
state
.
Step
)
if
exited
&&
stateStep
<=
i
{
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
// is one before its Step value.
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
,
}
p
.
lastStep
=
stateStep
-
1
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
)
}
return
proof
,
nil
}
else
{
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
)
return
nil
,
fmt
.
Errorf
(
"expected proof not generated but final state was not exited, requested step %v, final state at step %v"
,
i
,
stateStep
)
}
}
}
...
...
@@ -164,14 +153,6 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*utils.P
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
// Only to be used for testing
type
CannonTraceProviderForTest
struct
{
...
...
@@ -198,14 +179,14 @@ func (p *CannonTraceProviderForTest) FindStep(ctx context.Context, start uint64,
return
0
,
fmt
.
Errorf
(
"generate cannon trace (until preimage read): %w"
,
err
)
}
// Load the step from the state cannon finished with
state
,
err
:=
p
.
finalState
(
)
_
,
step
,
exited
,
err
:=
p
.
stateConverter
.
ConvertStateToProof
(
filepath
.
Join
(
p
.
dir
,
vm
.
FinalState
)
)
if
err
!=
nil
{
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
if
state
.
E
xited
{
if
e
xited
{
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.
return
st
ate
.
St
ep
-
1
,
nil
return
step
-
1
,
nil
}
op-challenger/game/fault/trace/cannon/provider_test.go
View file @
34101091
...
...
@@ -244,6 +244,7 @@ func setupWithTestData(t *testing.T, dataDir string, prestate string) (*CannonTr
generator
:
generator
,
prestate
:
filepath
.
Join
(
dataDir
,
prestate
),
gameDepth
:
63
,
stateConverter
:
&
StateConverter
{},
},
generator
}
...
...
op-challenger/game/fault/trace/cannon/state.go
→
op-challenger/game/fault/trace/cannon/state
_converter
.go
View file @
34101091
...
...
@@ -6,9 +6,35 @@ import (
"io"
"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"
)
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
)
{
file
,
err
:=
ioutil
.
OpenDecompressed
(
path
)
if
err
!=
nil
{
...
...
op-challenger/game/fault/trace/vm/iface.go
0 → 100644
View file @
34101091
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/game/fault/trace/
asterisc
/prestate.go
→
op-challenger/game/fault/trace/
vm
/prestate.go
View file @
34101091
package
asterisc
package
vm
import
(
"context"
"fmt"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
)
var
_
types
.
PrestateProvider
=
(
*
AsteriscPreS
tateProvider
)(
nil
)
var
_
types
.
PrestateProvider
=
(
*
Pres
tateProvider
)(
nil
)
type
AsteriscPreS
tateProvider
struct
{
type
Pres
tateProvider
struct
{
prestate
string
stateConverter
StateConverter
prestateCommitment
common
.
Hash
}
func
NewPrestateProvider
(
prestate
string
)
*
AsteriscPreStateProvider
{
return
&
AsteriscPreStateProvider
{
prestate
:
prestate
}
}
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
)
func
NewPrestateProvider
(
prestate
string
,
converter
StateConverter
)
*
PrestateProvider
{
return
&
PrestateProvider
{
prestate
:
prestate
,
stateConverter
:
converter
,
}
return
state
,
nil
}
func
(
p
*
AsteriscPreS
tateProvider
)
AbsolutePreStateCommitment
(
_
context
.
Context
)
(
common
.
Hash
,
error
)
{
func
(
p
*
Pres
tateProvider
)
AbsolutePreStateCommitment
(
_
context
.
Context
)
(
common
.
Hash
,
error
)
{
if
p
.
prestateCommitment
!=
(
common
.
Hash
{})
{
return
p
.
prestateCommitment
,
nil
}
state
,
err
:=
p
.
absolutePreState
(
)
proof
,
_
,
_
,
err
:=
p
.
stateConverter
.
ConvertStateToProof
(
p
.
prestate
)
if
err
!=
nil
{
return
common
.
Hash
{},
fmt
.
Errorf
(
"cannot load absolute pre-state: %w"
,
err
)
}
p
.
prestateCommitment
=
state
.
StateHash
return
state
.
StateHash
,
nil
p
.
prestateCommitment
=
proof
.
ClaimValue
return
proof
.
ClaimValue
,
nil
}
func
(
p
*
AsteriscPreS
tateProvider
)
PrestatePath
()
string
{
func
(
p
*
Pres
tateProvider
)
PrestatePath
()
string
{
return
p
.
prestate
}
op-challenger/game/fault/trace/
asterisc
/prestate_test.go
→
op-challenger/game/fault/trace/
vm
/prestate_test.go
View file @
34101091
package
asterisc
package
vm
import
(
"context"
"
o
s"
"
error
s"
"path/filepath"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
func
newAsteriscPrestateProvider
(
dataDir
string
,
prestate
string
)
*
AsteriscPreStateProvider
{
return
&
AsteriscPreStateProvider
{
prestate
:
filepath
.
Join
(
dataDir
,
prestate
),
type
stubConverter
struct
{
err
error
hash
common
.
Hash
}
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
TestAbsolutePreStateCommitment
(
t
*
testing
.
T
)
{
dataDir
:=
t
.
TempDir
()
func
newPrestateProvider
(
prestate
common
.
Hash
)
*
PrestateProvider
{
return
NewPrestateProvider
(
"state.json"
,
&
stubConverter
{
hash
:
prestate
})
}
prestate
:=
"state.json"
func
TestAbsolutePreStateCommitment
(
t
*
testing
.
T
)
{
prestate
:=
common
.
Hash
{
0xaa
,
0xbb
}
t
.
Run
(
"StateUnavailable"
,
func
(
t
*
testing
.
T
)
{
provider
:=
newAsteriscPrestateProvider
(
"/dir/does/not/exist"
,
prestate
)
expectedErr
:=
errors
.
New
(
"kaboom"
)
provider
:=
NewPrestateProvider
(
"foo"
,
&
stubConverter
{
err
:
expectedErr
})
_
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
())
require
.
ErrorIs
(
t
,
err
,
os
.
ErrNotExist
)
require
.
ErrorIs
(
t
,
err
,
expectedErr
)
})
t
.
Run
(
"
InvalidStateFil
e"
,
func
(
t
*
testing
.
T
)
{
setupPreState
(
t
,
dataDir
,
"invalid.json"
)
provider
:=
newAsteriscPrestateProvider
(
dataDir
,
prestate
)
_
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
()
)
require
.
E
rrorContains
(
t
,
err
,
"invalid asterisc VM state"
)
t
.
Run
(
"
ExpectedAbsolutePreStat
e"
,
func
(
t
*
testing
.
T
)
{
provider
:=
newPrestateProvider
(
prestate
)
actual
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
()
)
require
.
NoError
(
t
,
err
)
require
.
E
qual
(
t
,
prestate
,
actual
)
})
t
.
Run
(
"CacheAbsolutePreState"
,
func
(
t
*
testing
.
T
)
{
setupPreState
(
t
,
dataDir
,
prestate
)
provider
:=
newAsteriscPrestateProvider
(
dataDir
,
prestate
)
converter
:=
&
stubConverter
{
hash
:
prestate
}
provider
:=
NewPrestateProvider
(
filepath
.
Join
(
"state.json"
),
converter
)
first
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
())
require
.
NoError
(
t
,
err
)
// Remove the prestate from disk
require
.
NoError
(
t
,
os
.
Remove
(
provider
.
prestate
)
)
converter
.
err
=
errors
.
New
(
"no soup for you"
)
// Value should still be available from cache
cached
,
err
:=
provider
.
AbsolutePreStateCommitment
(
context
.
Background
())
...
...
@@ -48,12 +61,3 @@ func TestAbsolutePreStateCommitment(t *testing.T) {
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/runner/factory.go
View file @
34101091
...
...
@@ -33,7 +33,7 @@ func createTraceProvider(
if
err
!=
nil
{
return
nil
,
err
}
prestateProvider
:=
cannon
.
NewPrestateProvider
(
prestate
)
prestateProvider
:=
vm
.
NewPrestateProvider
(
prestate
,
cannon
.
NewStateConverter
()
)
return
cannon
.
NewTraceProvider
(
logger
,
m
,
cfg
.
Cannon
,
vmConfig
,
prestateProvider
,
prestate
,
localInputs
,
dir
,
42
),
nil
case
types
.
TraceTypeAsterisc
:
vmConfig
:=
vm
.
NewOpProgramServerExecutor
()
...
...
@@ -41,7 +41,7 @@ func createTraceProvider(
if
err
!=
nil
{
return
nil
,
err
}
prestateProvider
:=
asterisc
.
NewPrestateProvider
(
prestate
)
prestateProvider
:=
vm
.
NewPrestateProvider
(
prestate
,
asterisc
.
NewStateConverter
()
)
return
asterisc
.
NewTraceProvider
(
logger
,
m
,
cfg
.
Asterisc
,
vmConfig
,
prestateProvider
,
prestate
,
localInputs
,
dir
,
42
),
nil
case
types
.
TraceTypeAsteriscKona
:
vmConfig
:=
vm
.
NewKonaServerExecutor
()
...
...
@@ -49,7 +49,7 @@ func createTraceProvider(
if
err
!=
nil
{
return
nil
,
err
}
prestateProvider
:=
asterisc
.
NewPrestateProvider
(
prestate
)
prestateProvider
:=
vm
.
NewPrestateProvider
(
prestate
,
asterisc
.
NewStateConverter
()
)
return
asterisc
.
NewTraceProvider
(
logger
,
m
,
cfg
.
Asterisc
,
vmConfig
,
prestateProvider
,
prestate
,
localInputs
,
dir
,
42
),
nil
}
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