Commit 3a5fb5e8 authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

op-challenger: Add support for permissioned games. (#9535)

parent 9cca805d
This diff is collapsed.
......@@ -39,23 +39,12 @@ var (
type TraceType string
const (
TraceTypeAlphabet TraceType = "alphabet"
TraceTypeCannon TraceType = "cannon"
// Mainnet games
CannonFaultGameID = 0
// Devnet games
AlphabetFaultGameID = 255
TraceTypeAlphabet TraceType = "alphabet"
TraceTypeCannon TraceType = "cannon"
TraceTypePermissioned TraceType = "permissioned"
)
var TraceTypes = []TraceType{TraceTypeAlphabet, TraceTypeCannon}
// GameIdToString maps game IDs to their string representation.
var GameIdToString = map[uint8]string{
CannonFaultGameID: "Cannon",
AlphabetFaultGameID: "Alphabet",
}
var TraceTypes = []TraceType{TraceTypeAlphabet, TraceTypeCannon, TraceTypePermissioned}
func (t TraceType) String() string {
return string(t)
......@@ -189,7 +178,7 @@ func (c Config) Check() error {
if c.MaxConcurrency == 0 {
return ErrMaxConcurrencyZero
}
if c.TraceTypeEnabled(TraceTypeCannon) {
if c.TraceTypeEnabled(TraceTypeCannon) || c.TraceTypeEnabled(TraceTypePermissioned) {
if c.CannonBin == "" {
return ErrMissingCannonBin
}
......
package config
import (
"fmt"
"runtime"
"testing"
......@@ -23,9 +24,11 @@ var (
validRollupRpc = "http://localhost:8555"
)
var cannonTraceTypes = []TraceType{TraceTypeCannon, TraceTypePermissioned}
func validConfig(traceType TraceType) Config {
cfg := NewConfig(validGameFactoryAddress, validL1EthRpc, validL1BeaconUrl, validDatadir, traceType)
if traceType == TraceTypeCannon {
if traceType == TraceTypeCannon || traceType == TraceTypePermissioned {
cfg.CannonBin = validCannonBin
cfg.CannonServer = validCannonOpProgramBin
cfg.CannonAbsolutePreState = validCannonAbsolutPreState
......@@ -79,22 +82,88 @@ func TestGameAllowlistNotRequired(t *testing.T) {
require.NoError(t, config.Check())
}
func TestCannonBinRequired(t *testing.T) {
config := validConfig(TraceTypeCannon)
config.CannonBin = ""
require.ErrorIs(t, config.Check(), ErrMissingCannonBin)
}
func TestCannonRequiredArgs(t *testing.T) {
for _, traceType := range cannonTraceTypes {
traceType := traceType
func TestCannonServerRequired(t *testing.T) {
config := validConfig(TraceTypeCannon)
config.CannonServer = ""
require.ErrorIs(t, config.Check(), ErrMissingCannonServer)
}
t.Run(fmt.Sprintf("TestCannonBinRequired-%v", traceType), func(t *testing.T) {
config := validConfig(traceType)
config.CannonBin = ""
require.ErrorIs(t, config.Check(), ErrMissingCannonBin)
})
func TestCannonAbsolutePreStateRequired(t *testing.T) {
config := validConfig(TraceTypeCannon)
config.CannonAbsolutePreState = ""
require.ErrorIs(t, config.Check(), ErrMissingCannonAbsolutePreState)
t.Run(fmt.Sprintf("TestCannonServerRequired-%v", traceType), func(t *testing.T) {
config := validConfig(traceType)
config.CannonServer = ""
require.ErrorIs(t, config.Check(), ErrMissingCannonServer)
})
t.Run(fmt.Sprintf("TestCannonAbsolutePreStateRequired-%v", traceType), func(t *testing.T) {
config := validConfig(traceType)
config.CannonAbsolutePreState = ""
require.ErrorIs(t, config.Check(), ErrMissingCannonAbsolutePreState)
})
t.Run(fmt.Sprintf("TestCannonL2Required-%v", traceType), func(t *testing.T) {
config := validConfig(traceType)
config.CannonL2 = ""
require.ErrorIs(t, config.Check(), ErrMissingCannonL2)
})
t.Run(fmt.Sprintf("TestCannonSnapshotFreq-%v", traceType), func(t *testing.T) {
t.Run("MustNotBeZero", func(t *testing.T) {
cfg := validConfig(traceType)
cfg.CannonSnapshotFreq = 0
require.ErrorIs(t, cfg.Check(), ErrMissingCannonSnapshotFreq)
})
})
t.Run(fmt.Sprintf("TestCannonInfoFreq-%v", traceType), func(t *testing.T) {
t.Run("MustNotBeZero", func(t *testing.T) {
cfg := validConfig(traceType)
cfg.CannonInfoFreq = 0
require.ErrorIs(t, cfg.Check(), ErrMissingCannonInfoFreq)
})
})
t.Run(fmt.Sprintf("TestCannonNetworkOrRollupConfigRequired-%v", traceType), func(t *testing.T) {
cfg := validConfig(traceType)
cfg.CannonNetwork = ""
cfg.CannonRollupConfigPath = ""
cfg.CannonL2GenesisPath = "genesis.json"
require.ErrorIs(t, cfg.Check(), ErrMissingCannonRollupConfig)
})
t.Run(fmt.Sprintf("TestCannonNetworkOrL2GenesisRequired-%v", traceType), func(t *testing.T) {
cfg := validConfig(traceType)
cfg.CannonNetwork = ""
cfg.CannonRollupConfigPath = "foo.json"
cfg.CannonL2GenesisPath = ""
require.ErrorIs(t, cfg.Check(), ErrMissingCannonL2Genesis)
})
t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndRollup-%v", traceType), func(t *testing.T) {
cfg := validConfig(traceType)
cfg.CannonNetwork = validCannonNetwork
cfg.CannonRollupConfigPath = "foo.json"
cfg.CannonL2GenesisPath = ""
require.ErrorIs(t, cfg.Check(), ErrCannonNetworkAndRollupConfig)
})
t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndL2Genesis-%v", traceType), func(t *testing.T) {
cfg := validConfig(traceType)
cfg.CannonNetwork = validCannonNetwork
cfg.CannonRollupConfigPath = ""
cfg.CannonL2GenesisPath = "foo.json"
require.ErrorIs(t, cfg.Check(), ErrCannonNetworkAndL2Genesis)
})
t.Run(fmt.Sprintf("TestNetworkMustBeValid-%v", traceType), func(t *testing.T) {
cfg := validConfig(traceType)
cfg.CannonNetwork = "unknown"
require.ErrorIs(t, cfg.Check(), ErrCannonNetworkUnknown)
})
}
}
func TestDatadirRequired(t *testing.T) {
......@@ -123,76 +192,15 @@ func TestHttpPollInterval(t *testing.T) {
})
}
func TestRollupRpcRequired_Cannon(t *testing.T) {
config := validConfig(TraceTypeCannon)
config.RollupRpc = ""
require.ErrorIs(t, config.Check(), ErrMissingRollupRpc)
}
func TestRollupRpcRequired_Alphabet(t *testing.T) {
config := validConfig(TraceTypeAlphabet)
config.RollupRpc = ""
require.ErrorIs(t, config.Check(), ErrMissingRollupRpc)
}
func TestCannonL2Required(t *testing.T) {
config := validConfig(TraceTypeCannon)
config.CannonL2 = ""
require.ErrorIs(t, config.Check(), ErrMissingCannonL2)
}
func TestCannonSnapshotFreq(t *testing.T) {
t.Run("MustNotBeZero", func(t *testing.T) {
cfg := validConfig(TraceTypeCannon)
cfg.CannonSnapshotFreq = 0
require.ErrorIs(t, cfg.Check(), ErrMissingCannonSnapshotFreq)
})
}
func TestCannonInfoFreq(t *testing.T) {
t.Run("MustNotBeZero", func(t *testing.T) {
cfg := validConfig(TraceTypeCannon)
cfg.CannonInfoFreq = 0
require.ErrorIs(t, cfg.Check(), ErrMissingCannonInfoFreq)
})
}
func TestCannonNetworkOrRollupConfigRequired(t *testing.T) {
cfg := validConfig(TraceTypeCannon)
cfg.CannonNetwork = ""
cfg.CannonRollupConfigPath = ""
cfg.CannonL2GenesisPath = "genesis.json"
require.ErrorIs(t, cfg.Check(), ErrMissingCannonRollupConfig)
}
func TestCannonNetworkOrL2GenesisRequired(t *testing.T) {
cfg := validConfig(TraceTypeCannon)
cfg.CannonNetwork = ""
cfg.CannonRollupConfigPath = "foo.json"
cfg.CannonL2GenesisPath = ""
require.ErrorIs(t, cfg.Check(), ErrMissingCannonL2Genesis)
}
func TestMustNotSpecifyNetworkAndRollup(t *testing.T) {
cfg := validConfig(TraceTypeCannon)
cfg.CannonNetwork = validCannonNetwork
cfg.CannonRollupConfigPath = "foo.json"
cfg.CannonL2GenesisPath = ""
require.ErrorIs(t, cfg.Check(), ErrCannonNetworkAndRollupConfig)
}
func TestMustNotSpecifyNetworkAndL2Genesis(t *testing.T) {
cfg := validConfig(TraceTypeCannon)
cfg.CannonNetwork = validCannonNetwork
cfg.CannonRollupConfigPath = ""
cfg.CannonL2GenesisPath = "foo.json"
require.ErrorIs(t, cfg.Check(), ErrCannonNetworkAndL2Genesis)
}
func TestNetworkMustBeValid(t *testing.T) {
cfg := validConfig(TraceTypeCannon)
cfg.CannonNetwork = "unknown"
require.ErrorIs(t, cfg.Check(), ErrCannonNetworkUnknown)
func TestRollupRpcRequired(t *testing.T) {
for _, traceType := range TraceTypes {
traceType := traceType
t.Run(traceType.String(), func(t *testing.T) {
config := validConfig(traceType)
config.RollupRpc = ""
require.ErrorIs(t, config.Check(), ErrMissingRollupRpc)
})
}
}
func TestRequireConfigForMultipleTraceTypes(t *testing.T) {
......
......@@ -223,7 +223,7 @@ func CheckRequired(ctx *cli.Context, traceTypes []config.TraceType) error {
}
for _, traceType := range traceTypes {
switch traceType {
case config.TraceTypeCannon:
case config.TraceTypeCannon, config.TraceTypePermissioned:
if err := CheckCannonFlags(ctx); err != nil {
return err
}
......
......@@ -41,7 +41,7 @@ func RegisterGameTypes(
) (CloseFunc, error) {
var closer CloseFunc
var l2Client *ethclient.Client
if cfg.TraceTypeEnabled(config.TraceTypeCannon) {
if cfg.TraceTypeEnabled(config.TraceTypeCannon) || cfg.TraceTypeEnabled(config.TraceTypePermissioned) {
l2, err := ethclient.DialContext(ctx, cfg.CannonL2)
if err != nil {
return nil, fmt.Errorf("dial l2 client %v: %w", cfg.CannonL2, err)
......@@ -50,10 +50,15 @@ func RegisterGameTypes(
closer = l2Client.Close
}
if cfg.TraceTypeEnabled(config.TraceTypeCannon) {
if err := registerCannon(registry, ctx, cl, logger, m, cfg, rollupClient, txSender, gameFactory, caller, l2Client); err != nil {
if err := registerCannon(faultTypes.CannonGameType, registry, ctx, cl, logger, m, cfg, rollupClient, txSender, gameFactory, caller, l2Client); err != nil {
return nil, fmt.Errorf("failed to register cannon game type: %w", err)
}
}
if cfg.TraceTypeEnabled(config.TraceTypePermissioned) {
if err := registerCannon(faultTypes.PermissionedGameType, registry, ctx, cl, logger, m, cfg, rollupClient, txSender, gameFactory, caller, l2Client); err != nil {
return nil, fmt.Errorf("failed to register permissioned cannon game type: %w", err)
}
}
if cfg.TraceTypeEnabled(config.TraceTypeAlphabet) {
if err := registerAlphabet(registry, ctx, cl, logger, m, rollupClient, txSender, gameFactory, caller); err != nil {
return nil, fmt.Errorf("failed to register alphabet game type: %w", err)
......@@ -128,6 +133,7 @@ func createOracle(ctx context.Context, gameFactory *contracts.DisputeGameFactory
}
func registerCannon(
gameType uint32,
registry Registry,
ctx context.Context,
cl faultTypes.ClockReader,
......@@ -165,15 +171,15 @@ func registerCannon(
genesisValidator := NewPrestateValidator("output root", contract.GetGenesisOutputRoot, prestateProvider)
return NewGamePlayer(ctx, cl, logger, m, dir, game.Proxy, txSender, contract, []Validator{prestateValidator, genesisValidator}, creator)
}
oracle, err := createOracle(ctx, gameFactory, caller, faultTypes.CannonGameType)
oracle, err := createOracle(ctx, gameFactory, caller, gameType)
if err != nil {
return err
}
registry.RegisterGameType(faultTypes.CannonGameType, playerCreator, oracle)
registry.RegisterGameType(gameType, playerCreator, oracle)
contractCreator := func(game types.GameMetadata) (claims.BondContract, error) {
return contracts.NewFaultDisputeGameContract(game.Proxy, caller)
}
registry.RegisterBondContract(faultTypes.CannonGameType, contractCreator)
registry.RegisterBondContract(gameType, contractCreator)
return nil
}
......@@ -19,8 +19,9 @@ var (
)
const (
CannonGameType uint32 = 0
AlphabetGameType uint32 = 255
CannonGameType uint32 = 0
PermissionedGameType uint32 = 1
AlphabetGameType uint32 = 255
)
type ClockReader interface {
......
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