Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion op-challenger/game/fault/register_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ func newSuperCannonVMRegisterTaskWithConfig(
syncValidator: syncValidator,
skipPrestateValidation: gameType == gameTypes.SuperPermissionedGameType,
getTopPrestateProvider: func(ctx context.Context, prestateTimestamp uint64) (faultTypes.PrestateProvider, error) {
if superNodeProvider != nil {
return super.NewSuperNodePrestateProvider(superNodeProvider, prestateTimestamp), nil
}
return super.NewSuperRootPrestateProvider(rootProvider, prestateTimestamp), nil
},
getBottomPrestateProvider: cachePrestates(
Expand All @@ -102,7 +105,7 @@ func newSuperCannonVMRegisterTaskWithConfig(
poststateBlock uint64) (*trace.Accessor, error) {
provider := vmPrestateProvider.(*vm.PrestateProvider)
preimagePrestateProvider := prestateProvider.(super.PreimagePrestateProvider)
return super.NewSuperCannonTraceAccessor(logger, m, vmCfg, serverExecutor, preimagePrestateProvider, rootProvider, superNodeProvider, provider.PrestatePath(), dir, l1Head, splitDepth, prestateBlock, poststateBlock)
return super.NewSuperCannonTraceAccessor(logger, m, vmCfg, serverExecutor, preimagePrestateProvider, rootProvider, superNodeProvider, superNodeProvider != nil, provider.PrestatePath(), dir, l1Head, splitDepth, prestateBlock, poststateBlock)
},
}
}
Expand Down
42 changes: 42 additions & 0 deletions op-challenger/game/fault/trace/super/prestate_supernode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package super

import (
"context"

"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
)

type SuperNodePrestateProvider struct {
provider SuperNodeRootProvider
timestamp uint64
}

var _ PreimagePrestateProvider = (*SuperNodePrestateProvider)(nil)

func NewSuperNodePrestateProvider(provider SuperNodeRootProvider, prestateTimestamp uint64) *SuperNodePrestateProvider {
return &SuperNodePrestateProvider{
provider: provider,
timestamp: prestateTimestamp,
}
}

func (s *SuperNodePrestateProvider) AbsolutePreStateCommitment(ctx context.Context) (common.Hash, error) {
prestate, err := s.AbsolutePreState(ctx)
if err != nil {
return common.Hash{}, err
}
return common.Hash(eth.SuperRoot(prestate)), nil
}

func (s *SuperNodePrestateProvider) AbsolutePreState(ctx context.Context) (eth.Super, error) {
response, err := s.provider.SuperRootAtTimestamp(ctx, s.timestamp)
if err != nil {
return nil, err
}
if response.Data == nil {
return nil, ethereum.NotFound
}
return response.Data.Super, nil
}
67 changes: 67 additions & 0 deletions op-challenger/game/fault/trace/super/prestate_supernode_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package super

import (
"context"
"testing"

"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)

func TestAbsolutePreState_SuperNode(t *testing.T) {
t.Run("FailedToFetchOutput", func(t *testing.T) {
rootProvider := &stubSuperNodeRootProvider{}
provider := NewSuperNodePrestateProvider(rootProvider, 100)

_, err := provider.AbsolutePreState(context.Background())
require.Error(t, err)
require.NotErrorIs(t, err, ethereum.NotFound, "The API shouldn't return not found, it returns a response with no data instead")

_, err = provider.AbsolutePreStateCommitment(context.Background())
require.Error(t, err)
require.NotErrorIs(t, err, ethereum.NotFound, "The API shouldn't return not found, it returns a response with no data instead")
})

t.Run("NoDataResponse", func(t *testing.T) {
rootProvider := &stubSuperNodeRootProvider{}
rootProvider.AddAtTimestamp(100, eth.SuperRootAtTimestampResponse{
Data: nil,
})
provider := NewSuperNodePrestateProvider(rootProvider, 100)

_, err := provider.AbsolutePreState(context.Background())
require.ErrorIs(t, err, ethereum.NotFound)

_, err = provider.AbsolutePreStateCommitment(context.Background())
require.ErrorIs(t, err, ethereum.NotFound)
})

t.Run("ReturnsSuperRootForTimestamp", func(t *testing.T) {
expectedPreimage := eth.NewSuperV1(100,
eth.ChainIDAndOutput{
ChainID: eth.ChainID{2987},
Output: eth.Bytes32{0x88},
}, eth.ChainIDAndOutput{
ChainID: eth.ChainID{100},
Output: eth.Bytes32{0x10},
})
rootProvider := &stubSuperNodeRootProvider{}
rootProvider.AddAtTimestamp(100, eth.SuperRootAtTimestampResponse{
Data: &eth.SuperRootResponseData{
Super: expectedPreimage,
SuperRoot: eth.SuperRoot(expectedPreimage),
},
})
provider := NewSuperNodePrestateProvider(rootProvider, 100)

preimage, err := provider.AbsolutePreState(context.Background())
require.NoError(t, err)
require.Equal(t, expectedPreimage, preimage)

commitment, err := provider.AbsolutePreStateCommitment(context.Background())
require.NoError(t, err)
require.Equal(t, common.Hash(eth.SuperRoot(expectedPreimage)), commitment)
})
}
11 changes: 0 additions & 11 deletions op-challenger/game/fault/trace/super/provider_supervisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
interopTypes "github.com/ethereum-optimism/optimism/op-program/client/interop/types"
"github.com/ethereum-optimism/optimism/op-service/bigs"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/sources"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
Expand Down Expand Up @@ -54,16 +53,6 @@ type SupervisorSuperTraceProvider struct {
gameDepth types.Depth
}

func NewSuperTraceProvider(logger log.Logger, rollupCfgs *RollupConfigs, prestateProvider PreimagePrestateProvider, rootProvider *sources.SupervisorClient, superNodeProvider *sources.SuperNodeClient, l1Head eth.BlockID, gameDepth types.Depth, prestateTimestamp, poststateTimestamp uint64) SuperTraceProvider {
if rootProvider == nil && superNodeProvider != nil {
return NewSuperNodeTraceProvider(logger, prestateProvider, superNodeProvider, l1Head, gameDepth, prestateTimestamp, poststateTimestamp)
} else if rootProvider != nil && superNodeProvider == nil {
return NewSupervisorSuperTraceProvider(logger, rollupCfgs, prestateProvider, rootProvider, l1Head, gameDepth, prestateTimestamp, poststateTimestamp)
} else {
panic(fmt.Sprintf("Invalid configuration: must provide either a super node provider or a root provider, but not both. Root provider: %v, SuperNodeProvider: %v", rootProvider, superNodeProvider))
}
}

func NewSupervisorSuperTraceProvider(logger log.Logger, rollupCfgs *RollupConfigs, prestateProvider PreimagePrestateProvider, rootProvider RootProvider, l1Head eth.BlockID, gameDepth types.Depth, prestateTimestamp, poststateTimestamp uint64) *SupervisorSuperTraceProvider {
return &SupervisorSuperTraceProvider{
logger: logger,
Expand Down
14 changes: 10 additions & 4 deletions op-challenger/game/fault/trace/super/super_cannon.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/sources"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/log"
Expand All @@ -26,8 +25,10 @@ func NewSuperCannonTraceAccessor(
cfg vm.Config,
serverExecutor vm.OracleServerExecutor,
prestateProvider PreimagePrestateProvider,
rootProvider *sources.SupervisorClient,
superNodeProvider *sources.SuperNodeClient,
rootProvider RootProvider,
superNodeProvider SuperNodeRootProvider,
// Because go interfaces are a pointer and a type, they are not nil if the type is not nil. So we can't just check if the superNodeProvider != nil because it will have a type and be non-nil even though the pointer is nil.
useSuperNode bool,
cannonPrestate string,
dir string,
l1Head eth.BlockID,
Expand All @@ -39,7 +40,12 @@ func NewSuperCannonTraceAccessor(
if err != nil {
return nil, fmt.Errorf("failed to load rollup configs: %w", err)
}
outputProvider := NewSuperTraceProvider(logger, rollupCfgs, prestateProvider, rootProvider, superNodeProvider, l1Head, splitDepth, prestateTimestamp, poststateTimestamp)
var outputProvider SuperTraceProvider
if useSuperNode {
outputProvider = NewSuperNodeTraceProvider(logger, prestateProvider, superNodeProvider, l1Head, splitDepth, prestateTimestamp, poststateTimestamp)
} else {
outputProvider = NewSupervisorSuperTraceProvider(logger, rollupCfgs, prestateProvider, rootProvider, l1Head, splitDepth, prestateTimestamp, poststateTimestamp)
}
cannonCreator := func(ctx context.Context, localContext common.Hash, depth types.Depth, claimInfo ClaimInfo) (types.TraceProvider, error) {
logger := logger.New("agreedPrestate", hexutil.Bytes(claimInfo.AgreedPrestate), "claim", claimInfo.Claim, "localContext", localContext)
subdir := filepath.Join(dir, localContext.Hex())
Expand Down
61 changes: 60 additions & 1 deletion op-devstack/dsl/proofs/dispute_game_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/prestates"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/super"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm"
gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
Expand Down Expand Up @@ -209,7 +210,7 @@ func (f *DisputeGameFactory) startSuperCannonGameOfType(eoa *dsl.EOA, gameType g
}
game, addr := f.createNewGame(eoa, gameType, rootClaim, extraData)

return NewSuperFaultDisputeGame(f.t, f.require, addr, f.getGameHelper, game)
return NewSuperFaultDisputeGame(f.t, f.require, addr, f.getGameHelper, f.honestTraceForGame, game)
}

func (f *DisputeGameFactory) createSuperGameExtraData(timestamp uint64, cfg *GameCfg) []byte {
Expand Down Expand Up @@ -270,6 +271,14 @@ func (f *DisputeGameFactory) honestTraceForGame(game *FaultDisputeGame) challeng
f.challengerCfg.CannonKona,
vm.NewKonaExecutor(),
)
case gameTypes.SuperCannonGameType:
return f.honestSuperCannonTrace(
game,
f.challengerCfg.CannonAbsolutePreStateBaseURL,
f.challengerCfg.CannonAbsolutePreState,
f.challengerCfg.Cannon,
vm.NewOpProgramServerExecutor(f.log),
)
default:
f.require.Truef(false, "Honest trace not supported for game type %v", game.GameType())
return nil
Expand Down Expand Up @@ -320,6 +329,56 @@ func (f *DisputeGameFactory) honestOutputCannonTrace(
return accessor
}

func (f *DisputeGameFactory) honestSuperCannonTrace(
game *FaultDisputeGame,
prestateBaseUrl *url.URL,
prestateFile string,
vmConfig vm.Config,
serverExecutor vm.OracleServerExecutor,
) challengerTypes.TraceAccessor {
logger := f.t.Logger().New("role", "honestSuperTrace")
f.require.NotNil(f.superNode, "SuperNode is required to create honest super trace")

prestateTimestamp := game.StartingL2SequenceNumber()
poststateTimestamp := game.L2SequenceNumber()

l1HeadHash := game.L1Head()
l1Head, err := f.ethClient.BlockRefByHash(f.t.Ctx(), l1HeadHash)
f.require.NoError(err, "Failed to fetch L1 Head")

prestateProvider := super.NewSuperNodePrestateProvider(f.superNode.QueryAPI(), prestateTimestamp)

vmPrestateSource := prestates.NewPrestateSource(
prestateBaseUrl,
prestateFile,
path.Join(f.challengerCfg.Datadir, "test-prestates"),
cannon.NewStateConverter(vmConfig),
)
vmPrestatePath, err := vmPrestateSource.PrestatePath(f.t.Ctx(), game.absolutePrestate())
f.require.NoError(err, "Failed to get prestate path")

accessor, err := super.NewSuperCannonTraceAccessor(
logger,
metrics.NoopMetrics,
vmConfig,
serverExecutor,
prestateProvider,
nil, // supervisor client
f.superNode.QueryAPI(),
true,
vmPrestatePath,
path.Join(f.challengerCfg.Datadir, "test-prestates"),
l1Head.ID(),
game.SplitDepth(),
prestateTimestamp,
poststateTimestamp,
)
f.require.NoError(err, "Failed to create super cannon trace accessor")

f.honestTraces[game.Address] = accessor
return accessor
}

func (f *DisputeGameFactory) startOutputRootGameOfType(
eoa *dsl.EOA,
gameType gameTypes.GameType,
Expand Down
15 changes: 9 additions & 6 deletions op-devstack/dsl/proofs/super_fault_dispute_game.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ type SuperFaultDisputeGame struct {
*FaultDisputeGame
}

func NewSuperFaultDisputeGame(t devtest.T, require *require.Assertions, addr common.Address, helperProvider gameHelperProvider, game *bindings.FaultDisputeGame) *SuperFaultDisputeGame {
honestTraceProvider := func(_ *FaultDisputeGame) types.TraceAccessor {
require.Fail("Honest trace not supported for super games")
return nil
}
fdg := NewFaultDisputeGame(t, require, addr, helperProvider, honestTraceProvider, game)
func NewSuperFaultDisputeGame(
t devtest.T,
require *require.Assertions,
addr common.Address,
helperProvider gameHelperProvider,
honestTrace func(game *FaultDisputeGame) types.TraceAccessor,
game *bindings.FaultDisputeGame,
) *SuperFaultDisputeGame {
fdg := NewFaultDisputeGame(t, require, addr, helperProvider, honestTrace, game)
return &SuperFaultDisputeGame{
FaultDisputeGame: fdg,
}
Expand Down
1 change: 1 addition & 0 deletions op-e2e/e2eutils/disputegame/super_cannon_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ func (g *SuperCannonGameHelper) CreateHonestActor(ctx context.Context, options .
prestateProvider,
supervisorClient,
nil,
false,
cfg.CannonAbsolutePreState,
dir,
l1Head,
Expand Down