Commit 2622d2f4 authored by inphi's avatar inphi Committed by refcell

feat(op-challenger): introduce the output_alphabet trace type

fix(ctb): bad rebase

fix(op-challenger): split and game depth loading

chore(op-challenger): issue comments

revert output cannon trace type to 0
parent d4ec4c7d
...@@ -468,6 +468,8 @@ func requiredArgs(traceType config.TraceType) map[string]string { ...@@ -468,6 +468,8 @@ func requiredArgs(traceType config.TraceType) map[string]string {
addRequiredCannonArgs(args) addRequiredCannonArgs(args)
case config.TraceTypeOutputCannon: case config.TraceTypeOutputCannon:
addRequiredOutputCannonArgs(args) addRequiredOutputCannonArgs(args)
case config.TraceTypeOutputAlphabet:
addRequiredOutputAlphabetArgs(args)
} }
return args return args
} }
...@@ -476,8 +478,16 @@ func addRequiredAlphabetArgs(args map[string]string) { ...@@ -476,8 +478,16 @@ func addRequiredAlphabetArgs(args map[string]string) {
args["--alphabet"] = alphabetTrace args["--alphabet"] = alphabetTrace
} }
func addRequiredOutputAlphabetArgs(args map[string]string) {
addRequiredOutputArgs(args)
}
func addRequiredOutputCannonArgs(args map[string]string) { func addRequiredOutputCannonArgs(args map[string]string) {
addRequiredCannonArgs(args) addRequiredCannonArgs(args)
addRequiredOutputArgs(args)
}
func addRequiredOutputArgs(args map[string]string) {
args["--rollup-rpc"] = rollupRpc args["--rollup-rpc"] = rollupRpc
} }
......
...@@ -40,9 +40,10 @@ var ( ...@@ -40,9 +40,10 @@ var (
type TraceType string type TraceType string
const ( const (
TraceTypeAlphabet TraceType = "alphabet" TraceTypeAlphabet TraceType = "alphabet"
TraceTypeCannon TraceType = "cannon" TraceTypeCannon TraceType = "cannon"
TraceTypeOutputCannon TraceType = "output_cannon" TraceTypeOutputCannon TraceType = "output_cannon"
TraceTypeOutputAlphabet TraceType = "output_alphabet"
// Mainnet games // Mainnet games
CannonFaultGameID = 0 CannonFaultGameID = 0
...@@ -51,7 +52,7 @@ const ( ...@@ -51,7 +52,7 @@ const (
AlphabetFaultGameID = 255 AlphabetFaultGameID = 255
) )
var TraceTypes = []TraceType{TraceTypeAlphabet, TraceTypeCannon, TraceTypeOutputCannon} var TraceTypes = []TraceType{TraceTypeAlphabet, TraceTypeCannon, TraceTypeOutputCannon, TraceTypeOutputAlphabet}
// GameIdToString maps game IDs to their string representation. // GameIdToString maps game IDs to their string representation.
var GameIdToString = map[uint8]string{ var GameIdToString = map[uint8]string{
...@@ -179,10 +180,13 @@ func (c Config) Check() error { ...@@ -179,10 +180,13 @@ func (c Config) Check() error {
if c.MaxConcurrency == 0 { if c.MaxConcurrency == 0 {
return ErrMaxConcurrencyZero return ErrMaxConcurrencyZero
} }
if c.TraceTypeEnabled(TraceTypeOutputCannon) { if c.TraceTypeEnabled(TraceTypeOutputCannon) || c.TraceTypeEnabled(TraceTypeOutputAlphabet) {
if c.RollupRpc == "" { if c.RollupRpc == "" {
return ErrMissingRollupRpc return ErrMissingRollupRpc
} }
if c.TraceTypeEnabled(TraceTypeCannon) && (c.TraceTypeEnabled(TraceTypeOutputCannon) || c.TraceTypeEnabled(TraceTypeOutputAlphabet)) {
return ErrCannonAndOutputCannonConflict
}
} }
if c.TraceTypeEnabled(TraceTypeCannon) && c.TraceTypeEnabled(TraceTypeOutputCannon) { if c.TraceTypeEnabled(TraceTypeCannon) && c.TraceTypeEnabled(TraceTypeOutputCannon) {
return ErrCannonAndOutputCannonConflict return ErrCannonAndOutputCannonConflict
......
...@@ -35,7 +35,7 @@ func validConfig(traceType TraceType) Config { ...@@ -35,7 +35,7 @@ func validConfig(traceType TraceType) Config {
cfg.CannonL2 = validCannonL2 cfg.CannonL2 = validCannonL2
cfg.CannonNetwork = validCannonNetwork cfg.CannonNetwork = validCannonNetwork
} }
if traceType == TraceTypeOutputCannon { if traceType == TraceTypeOutputCannon || traceType == TraceTypeOutputAlphabet {
cfg.RollupRpc = validRollupRpc cfg.RollupRpc = validRollupRpc
} }
return cfg return cfg
...@@ -84,6 +84,12 @@ func TestAlphabetTraceRequired(t *testing.T) { ...@@ -84,6 +84,12 @@ func TestAlphabetTraceRequired(t *testing.T) {
require.ErrorIs(t, config.Check(), ErrMissingAlphabetTrace) require.ErrorIs(t, config.Check(), ErrMissingAlphabetTrace)
} }
func TestAlphabetTraceNotRequiredForOutputAlphabet(t *testing.T) {
config := validConfig(TraceTypeOutputAlphabet)
config.AlphabetTrace = ""
require.NoError(t, config.Check())
}
func TestCannonBinRequired(t *testing.T) { func TestCannonBinRequired(t *testing.T) {
config := validConfig(TraceTypeCannon) config := validConfig(TraceTypeCannon)
config.CannonBin = "" config.CannonBin = ""
...@@ -128,12 +134,18 @@ func TestHttpPollInterval(t *testing.T) { ...@@ -128,12 +134,18 @@ func TestHttpPollInterval(t *testing.T) {
}) })
} }
func TestRollupRpcRequired(t *testing.T) { func TestRollupRpcRequired_OutputCannon(t *testing.T) {
config := validConfig(TraceTypeOutputCannon) config := validConfig(TraceTypeOutputCannon)
config.RollupRpc = "" config.RollupRpc = ""
require.ErrorIs(t, config.Check(), ErrMissingRollupRpc) require.ErrorIs(t, config.Check(), ErrMissingRollupRpc)
} }
func TestRollupRpcRequired_OutputAlphabet(t *testing.T) {
config := validConfig(TraceTypeOutputAlphabet)
config.RollupRpc = ""
require.ErrorIs(t, config.Check(), ErrMissingRollupRpc)
}
func TestCannotEnableBothCannonAndOutputCannonTraceTypes(t *testing.T) { func TestCannotEnableBothCannonAndOutputCannonTraceTypes(t *testing.T) {
config := validConfig(TraceTypeOutputCannon) config := validConfig(TraceTypeOutputCannon)
config.TraceTypes = append(config.TraceTypes, TraceTypeCannon) config.TraceTypes = append(config.TraceTypes, TraceTypeCannon)
......
...@@ -224,6 +224,10 @@ func CheckRequired(ctx *cli.Context, traceTypes []config.TraceType) error { ...@@ -224,6 +224,10 @@ func CheckRequired(ctx *cli.Context, traceTypes []config.TraceType) error {
if !ctx.IsSet(RollupRpcFlag.Name) { if !ctx.IsSet(RollupRpcFlag.Name) {
return fmt.Errorf("flag %s is required", RollupRpcFlag.Name) return fmt.Errorf("flag %s is required", RollupRpcFlag.Name)
} }
case config.TraceTypeOutputAlphabet:
if !ctx.IsSet(RollupRpcFlag.Name) {
return fmt.Errorf("flag %s is required", RollupRpcFlag.Name)
}
default: default:
return fmt.Errorf("invalid trace type. must be one of %v", config.TraceTypes) return fmt.Errorf("invalid trace type. must be one of %v", config.TraceTypes)
} }
......
...@@ -22,9 +22,10 @@ import ( ...@@ -22,9 +22,10 @@ import (
) )
var ( var (
cannonGameType = uint8(0) cannonGameType = uint8(0)
outputCannonGameType = uint8(0) // TODO(client-pod#43): This should be a unique game type outputCannonGameType = uint8(0) // TODO(client-pod#260): Switch the output cannon game type to 1
alphabetGameType = uint8(255) outputAlphabetGameType = uint8(254)
alphabetGameType = uint8(255)
) )
type CloseFunc func() type CloseFunc func()
...@@ -55,6 +56,9 @@ func RegisterGameTypes( ...@@ -55,6 +56,9 @@ func RegisterGameTypes(
if cfg.TraceTypeEnabled(config.TraceTypeOutputCannon) { if cfg.TraceTypeEnabled(config.TraceTypeOutputCannon) {
registerOutputCannon(registry, ctx, logger, m, cfg, txMgr, caller, l2Client) registerOutputCannon(registry, ctx, logger, m, cfg, txMgr, caller, l2Client)
} }
if cfg.TraceTypeEnabled(config.TraceTypeOutputAlphabet) {
registerOutputAlphabet(registry, ctx, logger, m, cfg, txMgr, caller, l2Client)
}
if cfg.TraceTypeEnabled(config.TraceTypeCannon) { if cfg.TraceTypeEnabled(config.TraceTypeCannon) {
registerCannon(registry, ctx, logger, m, cfg, txMgr, caller, l2Client) registerCannon(registry, ctx, logger, m, cfg, txMgr, caller, l2Client)
} }
...@@ -64,6 +68,61 @@ func RegisterGameTypes( ...@@ -64,6 +68,61 @@ func RegisterGameTypes(
return closer, nil return closer, nil
} }
func registerOutputAlphabet(
registry Registry,
ctx context.Context,
logger log.Logger,
m metrics.Metricer,
cfg *config.Config,
txMgr txmgr.TxManager,
caller *batching.MultiCaller,
l2Client cannon.L2HeaderSource) {
resourceCreator := func(addr common.Address) (gameTypeResources, error) {
contract, err := contracts.NewOutputBisectionGameContract(addr, caller)
if err != nil {
return nil, err
}
return &outputAlphabetResources{
m: m,
cfg: cfg,
l2Client: l2Client,
contract: contract,
}, nil
}
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, resourceCreator)
}
registry.RegisterGameType(outputAlphabetGameType, playerCreator)
}
type outputAlphabetResources struct {
m metrics.Metricer
cfg *config.Config
l2Client cannon.L2HeaderSource
contract *contracts.OutputBisectionGameContract
}
func (r *outputAlphabetResources) Contract() GameContract {
return r.contract
}
func (r *outputAlphabetResources) CreateAccessor(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 := r.contract.GetBlockRange(ctx)
if err != nil {
return nil, err
}
splitDepth, err := r.contract.GetSplitDepth(ctx)
if err != nil {
return nil, err
}
accessor, err := outputs.NewOutputAlphabetTraceAccessor(ctx, logger, r.m, r.cfg, gameDepth, splitDepth, prestateBlock, poststateBlock)
if err != nil {
return nil, err
}
return accessor, nil
}
func registerOutputCannon( func registerOutputCannon(
registry Registry, registry Registry,
ctx context.Context, ctx context.Context,
...@@ -97,7 +156,7 @@ type outputCannonResources struct { ...@@ -97,7 +156,7 @@ type outputCannonResources struct {
m metrics.Metricer m metrics.Metricer
cfg *config.Config cfg *config.Config
l2Client cannon.L2HeaderSource l2Client cannon.L2HeaderSource
contract *contracts.FaultDisputeGameContract contract *contracts.FaultDisputeGameContract // TODO(client-pod#260): Use the OutputBisectionGame Contract
} }
func (r *outputCannonResources) Contract() GameContract { func (r *outputCannonResources) Contract() GameContract {
......
package outputs
import (
"context"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/split"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
)
func NewOutputAlphabetTraceAccessor(
ctx context.Context,
logger log.Logger,
m metrics.Metricer,
cfg *config.Config,
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
}
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
}
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