Commit 204d3602 authored by refcell.eth's avatar refcell.eth Committed by GitHub

Merge pull request #8496 from ethereum-optimism/refcell/game-player-validation

feat(op-challenger): Game Player Prestate Validation
parents e4fd1317 e13c0bb8
package fault
import (
"bytes"
"context"
"fmt"
......@@ -22,10 +21,11 @@ type GameInfo interface {
}
type GamePlayer struct {
act actor
loader GameInfo
logger log.Logger
status gameTypes.GameStatus
act actor
loader GameInfo
logger log.Logger
prestateValidators []Validator
status gameTypes.GameStatus
}
type GameContract interface {
......@@ -46,6 +46,7 @@ func NewGamePlayer(
addr common.Address,
txMgr txmgr.TxManager,
loader GameContract,
validators []Validator,
creator resourceCreator,
) (*GamePlayer, error) {
logger = logger.New("game", addr)
......@@ -58,9 +59,10 @@ func NewGamePlayer(
logger.Info("Game already resolved", "status", status)
// Game is already complete so skip creating the trace provider, loading game inputs etc.
return &GamePlayer{
logger: logger,
loader: loader,
status: status,
logger: logger,
loader: loader,
prestateValidators: validators,
status: status,
// Act function does nothing because the game is already complete
act: func(ctx context.Context) error {
return nil
......@@ -92,6 +94,15 @@ func NewGamePlayer(
}, nil
}
func (g *GamePlayer) ValidatePrestate(ctx context.Context) error {
for _, validator := range g.prestateValidators {
if err := validator.Validate(ctx); err != nil {
return fmt.Errorf("failed to validate prestate: %w", err)
}
}
return nil
}
func (g *GamePlayer) Status() gameTypes.GameStatus {
return g.status
}
......@@ -128,23 +139,3 @@ func (g *GamePlayer) logGameStatus(ctx context.Context, status gameTypes.GameSta
}
g.logger.Info("Game resolved", "status", status)
}
type PrestateLoader interface {
GetAbsolutePrestateHash(ctx context.Context) (common.Hash, error)
}
// ValidateAbsolutePrestate validates the absolute prestate of the fault game.
func ValidateAbsolutePrestate(ctx context.Context, trace types.TraceProvider, loader PrestateLoader) error {
providerPrestateHash, err := trace.AbsolutePreStateCommitment(ctx)
if err != nil {
return fmt.Errorf("failed to get the trace provider's absolute prestate: %w", err)
}
onchainPrestate, err := loader.GetAbsolutePrestateHash(ctx)
if err != nil {
return fmt.Errorf("failed to get the onchain absolute prestate: %w", err)
}
if !bytes.Equal(providerPrestateHash[:], onchainPrestate[:]) {
return fmt.Errorf("trace provider's absolute prestate does not match onchain absolute prestate: Provider: %s | Chain %s", providerPrestateHash.Hex(), onchainPrestate.Hex())
}
return nil
}
......@@ -6,26 +6,22 @@ import (
"fmt"
"testing"
"github.com/ethereum-optimism/optimism/cannon/mipsevm"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
)
var (
mockTraceProviderError = fmt.Errorf("mock trace provider error")
mockLoaderError = fmt.Errorf("mock loader error")
mockValidatorError = fmt.Errorf("mock validator error")
)
func TestProgressGame_LogErrorFromAct(t *testing.T) {
handler, game, actor := setupProgressGameTest(t)
actor.actErr = errors.New("boom")
status := game.ProgressGame(context.Background())
require.Equal(t, gameTypes.GameStatusInProgress, status)
require.Equal(t, types.GameStatusInProgress, status)
require.Equal(t, 1, actor.callCount, "should perform next actions")
errLog := handler.FindLog(log.LvlError, "Error when acting on game")
require.NotNil(t, errLog, "should log error")
......@@ -40,22 +36,22 @@ func TestProgressGame_LogErrorFromAct(t *testing.T) {
func TestProgressGame_LogGameStatus(t *testing.T) {
tests := []struct {
name string
status gameTypes.GameStatus
status types.GameStatus
logMsg string
}{
{
name: "ChallengerWon",
status: gameTypes.GameStatusChallengerWon,
status: types.GameStatusChallengerWon,
logMsg: "Game resolved",
},
{
name: "DefenderWon",
status: gameTypes.GameStatusDefenderWon,
status: types.GameStatusDefenderWon,
logMsg: "Game resolved",
},
{
name: "GameInProgress",
status: gameTypes.GameStatusInProgress,
status: types.GameStatusInProgress,
logMsg: "Game info",
},
}
......@@ -76,7 +72,7 @@ func TestProgressGame_LogGameStatus(t *testing.T) {
}
func TestDoNotActOnCompleteGame(t *testing.T) {
for _, status := range []gameTypes.GameStatus{gameTypes.GameStatusChallengerWon, gameTypes.GameStatusDefenderWon} {
for _, status := range []types.GameStatus{types.GameStatusChallengerWon, types.GameStatusDefenderWon} {
t.Run(status.String(), func(t *testing.T) {
_, game, gameState := setupProgressGameTest(t)
gameState.status = status
......@@ -93,41 +89,60 @@ func TestDoNotActOnCompleteGame(t *testing.T) {
}
}
// TestValidateAbsolutePrestate tests that the absolute prestate is validated
// correctly by the service component.
func TestValidateAbsolutePrestate(t *testing.T) {
t.Run("ValidPrestates", func(t *testing.T) {
prestate := []byte{0x00, 0x01, 0x02, 0x03}
prestateHash := crypto.Keccak256(prestate)
prestateHash[0] = mipsevm.VMStatusUnfinished
mockTraceProvider := newMockTraceProvider(false, prestate)
mockLoader := newMockPrestateLoader(false, common.BytesToHash(prestateHash))
err := ValidateAbsolutePrestate(context.Background(), mockTraceProvider, mockLoader)
require.NoError(t, err)
})
t.Run("TraceProviderErrors", func(t *testing.T) {
prestate := []byte{0x00, 0x01, 0x02, 0x03}
mockTraceProvider := newMockTraceProvider(true, prestate)
mockLoader := newMockPrestateLoader(false, common.BytesToHash(prestate))
err := ValidateAbsolutePrestate(context.Background(), mockTraceProvider, mockLoader)
require.ErrorIs(t, err, mockTraceProviderError)
})
t.Run("LoaderErrors", func(t *testing.T) {
prestate := []byte{0x00, 0x01, 0x02, 0x03}
mockTraceProvider := newMockTraceProvider(false, prestate)
mockLoader := newMockPrestateLoader(true, common.BytesToHash(prestate))
err := ValidateAbsolutePrestate(context.Background(), mockTraceProvider, mockLoader)
require.ErrorIs(t, err, mockLoaderError)
})
t.Run("PrestateMismatch", func(t *testing.T) {
mockTraceProvider := newMockTraceProvider(false, []byte{0x00, 0x01, 0x02, 0x03})
mockLoader := newMockPrestateLoader(false, common.BytesToHash([]byte{0x00}))
err := ValidateAbsolutePrestate(context.Background(), mockTraceProvider, mockLoader)
require.Error(t, err)
})
func TestValidatePrestate(t *testing.T) {
tests := []struct {
name string
validators []Validator
errors bool
}{
{
name: "SingleValidator",
validators: []Validator{&mockValidator{}},
errors: false,
},
{
name: "MultipleValidators",
validators: []Validator{&mockValidator{}, &mockValidator{}},
errors: false,
},
{
name: "SingleValidator_Errors",
validators: []Validator{&mockValidator{true}},
errors: true,
},
{
name: "MultipleValidators_Errors",
validators: []Validator{&mockValidator{}, &mockValidator{true}},
errors: true,
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
player := &GamePlayer{
prestateValidators: test.validators,
}
err := player.ValidatePrestate(context.Background())
if test.errors {
require.ErrorIs(t, err, mockValidatorError)
} else {
require.NoError(t, err)
}
})
}
}
var _ Validator = (*mockValidator)(nil)
type mockValidator struct {
err bool
}
func (m *mockValidator) Validate(ctx context.Context) error {
if m.err {
return mockValidatorError
}
return nil
}
func setupProgressGameTest(t *testing.T) (*testlog.CapturingHandler, *GamePlayer, *stubGameState) {
......@@ -146,7 +161,7 @@ func setupProgressGameTest(t *testing.T) (*testlog.CapturingHandler, *GamePlayer
}
type stubGameState struct {
status gameTypes.GameStatus
status types.GameStatus
claimCount uint64
callCount int
actErr error
......@@ -158,7 +173,7 @@ func (s *stubGameState) Act(ctx context.Context) error {
return s.actErr
}
func (s *stubGameState) GetStatus(ctx context.Context) (gameTypes.GameStatus, error) {
func (s *stubGameState) GetStatus(ctx context.Context) (types.GameStatus, error) {
return s.status, nil
}
......@@ -166,54 +181,6 @@ func (s *stubGameState) GetClaimCount(ctx context.Context) (uint64, error) {
return s.claimCount, nil
}
type mockTraceProvider struct {
prestateErrors bool
prestate []byte
}
func newMockTraceProvider(prestateErrors bool, prestate []byte) *mockTraceProvider {
return &mockTraceProvider{
prestateErrors: prestateErrors,
prestate: prestate,
}
}
func (m *mockTraceProvider) Get(ctx context.Context, i types.Position) (common.Hash, error) {
panic("not implemented")
}
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) {
if m.prestateErrors {
return nil, mockTraceProviderError
}
return m.prestate, nil
}
func (m *mockTraceProvider) AbsolutePreStateCommitment(ctx context.Context) (common.Hash, error) {
prestate, err := m.AbsolutePreState(ctx)
if err != nil {
return common.Hash{}, err
}
hash := common.BytesToHash(crypto.Keccak256(prestate))
hash[0] = mipsevm.VMStatusUnfinished
return hash, nil
}
type mockLoader struct {
prestateError bool
prestate common.Hash
}
func newMockPrestateLoader(prestateError bool, prestate common.Hash) *mockLoader {
return &mockLoader{
prestateError: prestateError,
prestate: prestate,
}
}
func (m *mockLoader) GetAbsolutePrestateHash(ctx context.Context) (common.Hash, error) {
if m.prestateError {
return common.Hash{}, mockLoaderError
}
return m.prestate, nil
func (s *stubGameState) GetAbsolutePrestateHash(ctx context.Context) (common.Hash, error) {
return common.Hash{}, s.Err
}
......@@ -14,6 +14,7 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/game/scheduler"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-service/dial"
"github.com/ethereum-optimism/optimism/op-service/sources/batching"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/ethclient"
......@@ -80,23 +81,29 @@ func registerOutputAlphabet(
if err != nil {
return nil, err
}
prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx)
if err != nil {
return nil, err
}
rollupClient, err := dial.DialRollupClientWithTimeout(ctx, dial.DefaultDialTimeout, logger, cfg.RollupRpc)
if err != nil {
return nil, err
}
prestateProvider := outputs.NewPrestateProvider(ctx, logger, rollupClient, prestateBlock)
creator := func(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (faultTypes.TraceAccessor, error) {
// TODO(client-pod#44): Validate absolute pre-state for split games
prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx)
if err != nil {
return nil, err
}
splitDepth, err := contract.GetSplitDepth(ctx)
if err != nil {
return nil, err
}
accessor, err := outputs.NewOutputAlphabetTraceAccessor(ctx, logger, m, cfg, gameDepth, splitDepth, prestateBlock, poststateBlock)
accessor, err := outputs.NewOutputAlphabetTraceAccessor(ctx, logger, m, cfg, prestateProvider, rollupClient, gameDepth, splitDepth, prestateBlock, poststateBlock)
if err != nil {
return nil, err
}
return accessor, nil
}
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, creator)
prestateValidator := NewPrestateValidator(contract.GetAbsolutePrestateHash, prestateProvider)
genesisValidator := NewPrestateValidator(contract.GetGenesisOutputRoot, prestateProvider)
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, []Validator{prestateValidator, genesisValidator}, creator)
}
registry.RegisterGameType(outputAlphabetGameType, playerCreator)
}
......@@ -115,23 +122,29 @@ func registerOutputCannon(
if err != nil {
return nil, err
}
prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx)
if err != nil {
return nil, err
}
rollupClient, err := dial.DialRollupClientWithTimeout(ctx, dial.DefaultDialTimeout, logger, cfg.RollupRpc)
if err != nil {
return nil, err
}
prestateProvider := outputs.NewPrestateProvider(ctx, logger, rollupClient, prestateBlock)
creator := func(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (faultTypes.TraceAccessor, error) {
// TODO(client-pod#44): Validate absolute pre-state for split games
agreed, disputed, err := contract.GetBlockRange(ctx)
if err != nil {
return nil, err
}
splitDepth, err := contract.GetSplitDepth(ctx)
if err != nil {
return nil, fmt.Errorf("failed to load split depth: %w", err)
}
accessor, err := outputs.NewOutputCannonTraceAccessor(ctx, logger, m, cfg, l2Client, contract, dir, gameDepth, splitDepth, agreed, disputed)
accessor, err := outputs.NewOutputCannonTraceAccessor(ctx, logger, m, cfg, l2Client, contract, prestateProvider, rollupClient, dir, gameDepth, splitDepth, prestateBlock, poststateBlock)
if err != nil {
return nil, err
}
return accessor, nil
}
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, creator)
prestateValidator := NewPrestateValidator(contract.GetAbsolutePrestateHash, prestateProvider)
genesisValidator := NewPrestateValidator(contract.GetGenesisOutputRoot, prestateProvider)
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, []Validator{prestateValidator, genesisValidator}, creator)
}
registry.RegisterGameType(outputCannonGameType, playerCreator)
}
......@@ -150,18 +163,17 @@ func registerCannon(
if err != nil {
return nil, err
}
prestateProvider := cannon.NewPrestateProvider(cfg)
creator := func(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (faultTypes.TraceAccessor, error) {
localInputs, err := cannon.FetchLocalInputs(ctx, contract, l2Client)
if err != nil {
return nil, fmt.Errorf("failed to fetch cannon local inputs: %w", err)
}
provider := cannon.NewTraceProvider(logger, m, cfg, faultTypes.NoLocalContext, localInputs, dir, gameDepth)
if err := ValidateAbsolutePrestate(ctx, provider, contract); err != nil {
return nil, err
}
return trace.NewSimpleTraceAccessor(provider), nil
}
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, creator)
validator := NewPrestateValidator(contract.GetAbsolutePrestateHash, prestateProvider)
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, []Validator{validator}, creator)
}
registry.RegisterGameType(cannonGameType, playerCreator)
}
......@@ -179,14 +191,13 @@ func registerAlphabet(
if err != nil {
return nil, err
}
prestateProvider := &alphabet.AlphabetPrestateProvider{}
creator := func(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (faultTypes.TraceAccessor, error) {
provider := alphabet.NewTraceProvider(cfg.AlphabetTrace, gameDepth)
if err := ValidateAbsolutePrestate(ctx, provider, contract); err != nil {
return nil, err
}
return trace.NewSimpleTraceAccessor(provider), nil
traceProvider := alphabet.NewTraceProvider(cfg.AlphabetTrace, gameDepth)
return trace.NewSimpleTraceAccessor(traceProvider), nil
}
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, creator)
validator := NewPrestateValidator(contract.GetAbsolutePrestateHash, prestateProvider)
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, []Validator{validator}, creator)
}
registry.RegisterGameType(alphabetGameType, playerCreator)
}
......@@ -19,22 +19,19 @@ func NewOutputAlphabetTraceAccessor(
logger log.Logger,
m metrics.Metricer,
cfg *config.Config,
prestateProvider types.PrestateProvider,
rollupClient OutputRollupClient,
gameDepth uint64,
splitDepth uint64,
prestateBlock uint64,
poststateBlock uint64,
) (*trace.Accessor, error) {
bottomDepth := gameDepth - splitDepth
outputProvider, err := NewTraceProvider(ctx, logger, cfg.RollupRpc, splitDepth, prestateBlock, poststateBlock)
if err != nil {
return nil, err
}
outputProvider := NewTraceProviderFromInputs(logger, prestateProvider, rollupClient, splitDepth, prestateBlock, poststateBlock)
alphabetCreator := func(ctx context.Context, localContext common.Hash, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
provider := alphabet.NewTraceProvider(localContext.Hex(), bottomDepth)
return provider, nil
}
cache := NewProviderCache(m, "output_alphabet_provider", alphabetCreator)
selector := split.NewSplitProviderSelector(outputProvider, int(splitDepth), OutputRootSplitAdapter(outputProvider, cache.GetOrCreate))
return trace.NewAccessor(selector), nil
......
......@@ -23,6 +23,8 @@ func NewOutputCannonTraceAccessor(
cfg *config.Config,
l2Client cannon.L2HeaderSource,
contract cannon.L1HeadSource,
prestateProvider types.PrestateProvider,
rollupClient OutputRollupClient,
dir string,
gameDepth uint64,
splitDepth uint64,
......@@ -30,11 +32,7 @@ func NewOutputCannonTraceAccessor(
poststateBlock uint64,
) (*trace.Accessor, error) {
bottomDepth := gameDepth - splitDepth
outputProvider, err := NewTraceProvider(ctx, logger, cfg.RollupRpc, splitDepth, prestateBlock, poststateBlock)
if err != nil {
return nil, err
}
outputProvider := NewTraceProviderFromInputs(logger, prestateProvider, rollupClient, splitDepth, prestateBlock, poststateBlock)
cannonCreator := func(ctx context.Context, localContext common.Hash, agreed contracts.Proposal, claimed contracts.Proposal) (types.TraceProvider, error) {
logger := logger.New("pre", agreed.OutputRoot, "post", claimed.OutputRoot, "localContext", localContext)
subdir := filepath.Join(dir, localContext.Hex())
......
package fault
import (
"bytes"
"context"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
)
type PrestateLoader = func(ctx context.Context) (common.Hash, error)
type Validator interface {
Validate(ctx context.Context) error
}
var _ Validator = (*PrestateValidator)(nil)
type PrestateValidator struct {
load PrestateLoader
provider types.PrestateProvider
}
func NewPrestateValidator(loader PrestateLoader, provider types.PrestateProvider) *PrestateValidator {
return &PrestateValidator{
load: loader,
provider: provider,
}
}
func (v *PrestateValidator) Validate(ctx context.Context) error {
prestateHash, err := v.load(ctx)
if err != nil {
return fmt.Errorf("failed to get prestate hash from loader: %w", err)
}
prestateCommitment, err := v.provider.AbsolutePreStateCommitment(ctx)
if err != nil {
return fmt.Errorf("failed to fetch provider's prestate hash: %w", err)
}
if !bytes.Equal(prestateCommitment[:], prestateHash[:]) {
return fmt.Errorf("provider's absolute prestate does not match contract's absolute prestate: Provider: %s | Contract: %s", prestateCommitment.Hex(), prestateHash.Hex())
}
return nil
}
package fault
import (
"context"
"fmt"
"testing"
"github.com/ethereum-optimism/optimism/cannon/mipsevm"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/stretchr/testify/require"
)
var (
prestate = []byte{0x00, 0x01, 0x02, 0x03}
mockProviderError = fmt.Errorf("mock provider error")
mockLoaderError = fmt.Errorf("mock loader error")
)
func TestValidate(t *testing.T) {
t.Run("ValidPrestates", func(t *testing.T) {
prestateHash := crypto.Keccak256(prestate)
prestateHash[0] = mipsevm.VMStatusUnfinished
player := &PrestateValidator{
load: newMockPrestateLoader(false, common.BytesToHash(prestateHash)),
provider: newMockPrestateProvider(false, prestate),
}
err := player.Validate(context.Background())
require.NoError(t, err)
})
t.Run("ProviderErrors", func(t *testing.T) {
player := &PrestateValidator{
load: newMockPrestateLoader(false, common.BytesToHash(prestate)),
provider: newMockPrestateProvider(true, prestate),
}
err := player.Validate(context.Background())
require.ErrorIs(t, err, mockProviderError)
})
t.Run("LoaderErrors", func(t *testing.T) {
player := &PrestateValidator{
load: newMockPrestateLoader(true, common.BytesToHash(prestate)),
provider: newMockPrestateProvider(false, prestate),
}
err := player.Validate(context.Background())
require.ErrorIs(t, err, mockLoaderError)
})
t.Run("PrestateMismatch", func(t *testing.T) {
player := &PrestateValidator{
load: newMockPrestateLoader(false, common.BytesToHash([]byte{0x00})),
provider: newMockPrestateProvider(false, prestate),
}
err := player.Validate(context.Background())
require.Error(t, err)
})
}
var _ types.PrestateProvider = (*mockPrestateProvider)(nil)
type mockPrestateProvider struct {
prestateErrors bool
prestate []byte
}
func newMockPrestateProvider(prestateErrors bool, prestate []byte) *mockPrestateProvider {
return &mockPrestateProvider{
prestateErrors: prestateErrors,
prestate: prestate,
}
}
func (m *mockPrestateProvider) AbsolutePreStateCommitment(ctx context.Context) (common.Hash, error) {
if m.prestateErrors {
return common.Hash{}, mockProviderError
}
hash := common.BytesToHash(crypto.Keccak256(m.prestate))
hash[0] = mipsevm.VMStatusUnfinished
return hash, nil
}
func newMockPrestateLoader(prestateError bool, prestate common.Hash) PrestateLoader {
return func(ctx context.Context) (common.Hash, error) {
if prestateError {
return common.Hash{}, mockLoaderError
}
return prestate, nil
}
}
......@@ -112,6 +112,7 @@ func (c *coordinator) createJob(game types.GameMetadata) (*job, error) {
if err != nil {
return nil, fmt.Errorf("failed to create game player: %w", err)
}
// TODO(client-pod#325): Update coordinator to call the game player's ValidatePrestate method
state.player = player
state.status = player.Status()
}
......
......@@ -58,8 +58,10 @@ func (g *OutputCannonGameHelper) CreateHonestActor(ctx context.Context, l2Node s
dir := filepath.Join(cfg.Datadir, "honest")
maxDepth := uint64(g.MaxDepth(ctx))
splitDepth := uint64(g.SplitDepth(ctx))
rollupClient := g.system.RollupClient(l2Node)
prestateProvider := outputs.NewPrestateProvider(ctx, logger, rollupClient, prestateBlock)
accessor, err := outputs.NewOutputCannonTraceAccessor(
ctx, logger, metrics.NoopMetrics, cfg, l2Client, contract, dir, maxDepth, splitDepth, prestateBlock, poststateBlock)
ctx, logger, metrics.NoopMetrics, cfg, l2Client, contract, prestateProvider, rollupClient, dir, maxDepth, splitDepth, prestateBlock, poststateBlock)
g.require.NoError(err, "Failed to create output cannon trace accessor")
return &OutputHonestHelper{
t: g.t,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment