Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

op-challenger: Skip prestate verifications for the permissioned game. #12140

Merged
merged 1 commit into from
Sep 26, 2024
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
16 changes: 12 additions & 4 deletions op-challenger/game/fault/register_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ import (
)

type RegisterTask struct {
gameType faultTypes.GameType
gameType faultTypes.GameType
skipPrestateValidation bool

getPrestateProvider func(prestateHash common.Hash) (faultTypes.PrestateProvider, error)
newTraceAccessor func(
Expand All @@ -51,6 +52,10 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c
stateConverter := cannon.NewStateConverter()
return &RegisterTask{
gameType: gameType,
// Don't validate the absolute prestate or genesis output root for permissioned games
// Only trusted actors participate in these games so they aren't expected to reach the step() call and
// are often configured without valid prestates but the challenger should still resolve the games.
skipPrestateValidation: gameType == faultTypes.PermissionedGameType,
getPrestateProvider: cachePrestates(
gameType,
stateConverter,
Expand Down Expand Up @@ -244,9 +249,12 @@ func (e *RegisterTask) Register(
}
return accessor, nil
}
prestateValidator := NewPrestateValidator(e.gameType.String(), contract.GetAbsolutePrestateHash, vmPrestateProvider)
startingValidator := NewPrestateValidator("output root", contract.GetStartingRootHash, prestateProvider)
return NewGamePlayer(ctx, systemClock, l1Clock, logger, m, dir, game.Proxy, txSender, contract, syncValidator, []Validator{prestateValidator, startingValidator}, creator, l1HeaderSource, selective, claimants)
var validators []Validator
if !e.skipPrestateValidation {
validators = append(validators, NewPrestateValidator(e.gameType.String(), contract.GetAbsolutePrestateHash, vmPrestateProvider))
validators = append(validators, NewPrestateValidator("output root", contract.GetStartingRootHash, prestateProvider))
}
return NewGamePlayer(ctx, systemClock, l1Clock, logger, m, dir, game.Proxy, txSender, contract, syncValidator, validators, creator, l1HeaderSource, selective, claimants)
}
err := registerOracle(ctx, m, oracles, gameFactory, caller, e.gameType)
if err != nil {
Expand Down
21 changes: 20 additions & 1 deletion op-e2e/e2eutils/challenger/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func NewHelper(log log.Logger, t *testing.T, require *require.Assertions, dir st
}
}

type Option func(config2 *config.Config)
type Option func(c *config.Config)

func WithFactoryAddress(addr common.Address) Option {
return func(c *config.Config) {
Expand All @@ -84,6 +84,18 @@ func WithPollInterval(pollInterval time.Duration) Option {
}
}

func WithValidPrestateRequired() Option {
return func(c *config.Config) {
c.AllowInvalidPrestate = false
}
}

func WithInvalidCannonPrestate() Option {
return func(c *config.Config) {
c.CannonAbsolutePreState = "/tmp/not-a-real-prestate.foo"
}
}

// FindMonorepoRoot finds the relative path to the monorepo root
// Different tests might be nested in subdirectories of the op-e2e dir.
func FindMonorepoRoot(t *testing.T) string {
Expand Down Expand Up @@ -136,6 +148,13 @@ func WithCannon(t *testing.T, rollupCfg *rollup.Config, l2Genesis *core.Genesis)
}
}

func WithPermissioned(t *testing.T, rollupCfg *rollup.Config, l2Genesis *core.Genesis) Option {
return func(c *config.Config) {
c.TraceTypes = append(c.TraceTypes, types.TraceTypePermissioned)
applyCannonConfig(c, t, rollupCfg, l2Genesis)
}
}

func WithAlphabet() Option {
return func(c *config.Config) {
c.TraceTypes = append(c.TraceTypes, types.TraceTypeAlphabet)
Expand Down
40 changes: 32 additions & 8 deletions op-e2e/e2eutils/disputegame/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ var (
)

const (
cannonGameType uint32 = 0
alphabetGameType uint32 = 255
cannonGameType uint32 = 0
permissionedGameType uint32 = 1
alphabetGameType uint32 = 255
)

type GameCfg struct {
Expand Down Expand Up @@ -95,13 +96,28 @@ type FactoryHelper struct {
Factory *bindings.DisputeGameFactory
}

func NewFactoryHelper(t *testing.T, ctx context.Context, system DisputeSystem) *FactoryHelper {
type FactoryCfg struct {
PrivKey *ecdsa.PrivateKey
}

type FactoryOption func(c *FactoryCfg)

func WithFactoryPrivKey(privKey *ecdsa.PrivateKey) FactoryOption {
return func(c *FactoryCfg) {
c.PrivKey = privKey
}
}

func NewFactoryHelper(t *testing.T, ctx context.Context, system DisputeSystem, opts ...FactoryOption) *FactoryHelper {
require := require.New(t)
client := system.NodeClient("l1")
chainID, err := client.ChainID(ctx)
require.NoError(err)
privKey := TestKey
opts, err := bind.NewKeyedTransactorWithChainID(privKey, chainID)
factoryCfg := &FactoryCfg{PrivKey: TestKey}
for _, opt := range opts {
opt(factoryCfg)
}
txOpts, err := bind.NewKeyedTransactorWithChainID(factoryCfg.PrivKey, chainID)
require.NoError(err)

l1Deployments := system.L1Deployments()
Expand All @@ -114,8 +130,8 @@ func NewFactoryHelper(t *testing.T, ctx context.Context, system DisputeSystem) *
Require: require,
System: system,
Client: client,
Opts: opts,
PrivKey: privKey,
Opts: txOpts,
PrivKey: factoryCfg.PrivKey,
Factory: factory,
FactoryAddr: factoryAddr,
}
Expand Down Expand Up @@ -152,6 +168,14 @@ func (h *FactoryHelper) StartOutputCannonGameWithCorrectRoot(ctx context.Context
}

func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string, l2BlockNumber uint64, rootClaim common.Hash, opts ...GameOpt) *OutputCannonGameHelper {
return h.startOutputCannonGameOfType(ctx, l2Node, l2BlockNumber, rootClaim, cannonGameType, opts...)
}

func (h *FactoryHelper) StartPermissionedGame(ctx context.Context, l2Node string, l2BlockNumber uint64, rootClaim common.Hash, opts ...GameOpt) *OutputCannonGameHelper {
return h.startOutputCannonGameOfType(ctx, l2Node, l2BlockNumber, rootClaim, permissionedGameType, opts...)
}

func (h *FactoryHelper) startOutputCannonGameOfType(ctx context.Context, l2Node string, l2BlockNumber uint64, rootClaim common.Hash, gameType uint32, opts ...GameOpt) *OutputCannonGameHelper {
cfg := NewGameCfg(opts...)
logger := testlog.Logger(h.T, log.LevelInfo).New("role", "OutputCannonGameHelper")
rollupClient := h.System.RollupClient(l2Node)
Expand All @@ -163,7 +187,7 @@ func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string
defer cancel()

tx, err := transactions.PadGasEstimate(h.Opts, 2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return h.Factory.Create(opts, cannonGameType, rootClaim, extraData)
return h.Factory.Create(opts, gameType, rootClaim, extraData)
})
h.Require.NoError(err, "create fault dispute game")
rcpt, err := wait.ForReceiptOK(ctx, h.Client, tx.Hash())
Expand Down
35 changes: 35 additions & 0 deletions op-e2e/faultproofs/permissioned_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package faultproofs

import (
"context"
"testing"

op_e2e "github.com/ethereum-optimism/optimism/op-e2e"

"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame"
"github.com/ethereum/go-ethereum/common"
)

func TestPermissionedGameType(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UsesCannon)

ctx := context.Background()
sys, _ := StartFaultDisputeSystem(t)
t.Cleanup(sys.Close)

gameFactory := disputegame.NewFactoryHelper(t, ctx, sys, disputegame.WithFactoryPrivKey(sys.Cfg.Secrets.Proposer))

game := gameFactory.StartPermissionedGame(ctx, "sequencer", 1, common.Hash{0x01, 0xaa})

// Start a challenger with both cannon and alphabet support
gameFactory.StartChallenger(ctx, "TowerDefense",
challenger.WithValidPrestateRequired(),
challenger.WithInvalidCannonPrestate(),
challenger.WithPermissioned(t, sys.RollupConfig, sys.L2GenesisCfg),
challenger.WithPrivKey(sys.Cfg.Secrets.Alice),
)

// Wait for the challenger to respond
game.RootClaim(ctx).WaitForCounterClaim(ctx)
}