Commit 25c1249b authored by refcell.eth's avatar refcell.eth Committed by GitHub

Switch game address parameter to an allowlist. (#6926)

parent dbed8eed
...@@ -105,20 +105,20 @@ func TestGameFactoryAddress(t *testing.T) { ...@@ -105,20 +105,20 @@ func TestGameFactoryAddress(t *testing.T) {
}) })
} }
func TestGameAddress(t *testing.T) { func TestGameAllowlist(t *testing.T) {
t.Run("Optional", func(t *testing.T) { t.Run("Optional", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--game-address")) cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--game-allowlist"))
require.NoError(t, cfg.Check()) require.NoError(t, cfg.Check())
}) })
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
addr := common.Address{0xbb, 0xcc, 0xdd} addr := common.Address{0xbb, 0xcc, 0xdd}
cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--game-address", "--game-address="+addr.Hex())) cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--game-allowlist", "--game-allowlist="+addr.Hex()))
require.Equal(t, addr, cfg.GameAddress) require.Contains(t, cfg.GameAllowlist, addr)
}) })
t.Run("Invalid", func(t *testing.T) { t.Run("Invalid", func(t *testing.T) {
verifyArgsInvalid(t, "invalid address: foo", addRequiredArgsExcept(config.TraceTypeAlphabet, "--game-address", "--game-address=foo")) verifyArgsInvalid(t, "invalid address: foo", addRequiredArgsExcept(config.TraceTypeAlphabet, "--game-allowlist", "--game-allowlist=foo"))
}) })
} }
......
...@@ -4,11 +4,12 @@ import ( ...@@ -4,11 +4,12 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum-optimism/optimism/op-node/chaincfg" "github.com/ethereum-optimism/optimism/op-node/chaincfg"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
"github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/common"
) )
var ( var (
...@@ -80,7 +81,7 @@ const DefaultCannonSnapshotFreq = uint(1_000_000_000) ...@@ -80,7 +81,7 @@ const DefaultCannonSnapshotFreq = uint(1_000_000_000)
type Config struct { type Config struct {
L1EthRpc string // L1 RPC Url L1EthRpc string // L1 RPC Url
GameFactoryAddress common.Address // Address of the dispute game factory GameFactoryAddress common.Address // Address of the dispute game factory
GameAddress common.Address // Address of the fault game GameAllowlist []common.Address // Allowlist of fault game addresses
AgreeWithProposedOutput bool // Temporary config if we agree or disagree with the posted output AgreeWithProposedOutput bool // Temporary config if we agree or disagree with the posted output
TraceType TraceType // Type of trace TraceType TraceType // Type of trace
......
...@@ -3,9 +3,10 @@ package config ...@@ -3,9 +3,10 @@ package config
import ( import (
"testing" "testing"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
) )
var ( var (
...@@ -68,9 +69,9 @@ func TestGameFactoryAddressRequired(t *testing.T) { ...@@ -68,9 +69,9 @@ func TestGameFactoryAddressRequired(t *testing.T) {
require.ErrorIs(t, config.Check(), ErrMissingGameFactoryAddress) require.ErrorIs(t, config.Check(), ErrMissingGameFactoryAddress)
} }
func TestGameAddressNotRequired(t *testing.T) { func TestGameAllowlistNotRequired(t *testing.T) {
config := validConfig(TraceTypeCannon) config := validConfig(TraceTypeCannon)
config.GameAddress = common.Address{} config.GameAllowlist = []common.Address{}
require.NoError(t, config.Check()) require.NoError(t, config.Check())
} }
......
...@@ -29,22 +29,34 @@ type gameMonitor struct { ...@@ -29,22 +29,34 @@ type gameMonitor struct {
source gameSource source gameSource
createPlayer playerCreator createPlayer playerCreator
fetchBlockNumber blockNumberFetcher fetchBlockNumber blockNumberFetcher
allowedGame common.Address allowedGames []common.Address
players map[common.Address]gamePlayer players map[common.Address]gamePlayer
} }
func newGameMonitor(logger log.Logger, cl clock.Clock, fetchBlockNumber blockNumberFetcher, allowedGame common.Address, source gameSource, createGame playerCreator) *gameMonitor { func newGameMonitor(logger log.Logger, cl clock.Clock, fetchBlockNumber blockNumberFetcher, allowedGames []common.Address, source gameSource, createGame playerCreator) *gameMonitor {
return &gameMonitor{ return &gameMonitor{
logger: logger, logger: logger,
clock: cl, clock: cl,
source: source, source: source,
createPlayer: createGame, createPlayer: createGame,
fetchBlockNumber: fetchBlockNumber, fetchBlockNumber: fetchBlockNumber,
allowedGame: allowedGame, allowedGames: allowedGames,
players: make(map[common.Address]gamePlayer), players: make(map[common.Address]gamePlayer),
} }
} }
func (m *gameMonitor) allowedGame(game common.Address) bool {
if len(m.allowedGames) == 0 {
return true
}
for _, allowed := range m.allowedGames {
if allowed == game {
return true
}
}
return false
}
func (m *gameMonitor) progressGames(ctx context.Context) error { func (m *gameMonitor) progressGames(ctx context.Context) error {
blockNum, err := m.fetchBlockNumber(ctx) blockNum, err := m.fetchBlockNumber(ctx)
if err != nil { if err != nil {
...@@ -55,7 +67,7 @@ func (m *gameMonitor) progressGames(ctx context.Context) error { ...@@ -55,7 +67,7 @@ func (m *gameMonitor) progressGames(ctx context.Context) error {
return fmt.Errorf("failed to load games: %w", err) return fmt.Errorf("failed to load games: %w", err)
} }
for _, game := range games { for _, game := range games {
if m.allowedGame != (common.Address{}) && m.allowedGame != game.Proxy { if !m.allowedGame(game.Proxy) {
m.logger.Debug("Skipping game not on allow list", "game", game.Proxy) m.logger.Debug("Skipping game not on allow list", "game", game.Proxy)
continue continue
} }
......
...@@ -14,7 +14,7 @@ import ( ...@@ -14,7 +14,7 @@ import (
) )
func TestMonitorExitsWhenContextDone(t *testing.T) { func TestMonitorExitsWhenContextDone(t *testing.T) {
monitor, _, _ := setupMonitorTest(t, common.Address{}) monitor, _, _ := setupMonitorTest(t, []common.Address{common.Address{}})
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
cancel() cancel()
err := monitor.MonitorGames(ctx) err := monitor.MonitorGames(ctx)
...@@ -22,7 +22,7 @@ func TestMonitorExitsWhenContextDone(t *testing.T) { ...@@ -22,7 +22,7 @@ func TestMonitorExitsWhenContextDone(t *testing.T) {
} }
func TestMonitorCreateAndProgressGameAgents(t *testing.T) { func TestMonitorCreateAndProgressGameAgents(t *testing.T) {
monitor, source, games := setupMonitorTest(t, common.Address{}) monitor, source, games := setupMonitorTest(t, []common.Address{})
addr1 := common.Address{0xaa} addr1 := common.Address{0xaa}
addr2 := common.Address{0xbb} addr2 := common.Address{0xbb}
...@@ -55,7 +55,7 @@ func TestMonitorCreateAndProgressGameAgents(t *testing.T) { ...@@ -55,7 +55,7 @@ func TestMonitorCreateAndProgressGameAgents(t *testing.T) {
func TestMonitorOnlyCreateSpecifiedGame(t *testing.T) { func TestMonitorOnlyCreateSpecifiedGame(t *testing.T) {
addr1 := common.Address{0xaa} addr1 := common.Address{0xaa}
addr2 := common.Address{0xbb} addr2 := common.Address{0xbb}
monitor, source, games := setupMonitorTest(t, addr2) monitor, source, games := setupMonitorTest(t, []common.Address{addr2})
source.games = []FaultDisputeGame{ source.games = []FaultDisputeGame{
{ {
...@@ -77,7 +77,7 @@ func TestMonitorOnlyCreateSpecifiedGame(t *testing.T) { ...@@ -77,7 +77,7 @@ func TestMonitorOnlyCreateSpecifiedGame(t *testing.T) {
require.Equal(t, 1, games.created[addr2].progressCount) require.Equal(t, 1, games.created[addr2].progressCount)
} }
func setupMonitorTest(t *testing.T, allowedGame common.Address) (*gameMonitor, *stubGameSource, *createdGames) { func setupMonitorTest(t *testing.T, allowedGames []common.Address) (*gameMonitor, *stubGameSource, *createdGames) {
logger := testlog.Logger(t, log.LvlDebug) logger := testlog.Logger(t, log.LvlDebug)
source := &stubGameSource{} source := &stubGameSource{}
games := &createdGames{ games := &createdGames{
...@@ -87,7 +87,7 @@ func setupMonitorTest(t *testing.T, allowedGame common.Address) (*gameMonitor, * ...@@ -87,7 +87,7 @@ func setupMonitorTest(t *testing.T, allowedGame common.Address) (*gameMonitor, *
fetchBlockNum := func(ctx context.Context) (uint64, error) { fetchBlockNum := func(ctx context.Context) (uint64, error) {
return 1234, nil return 1234, nil
} }
monitor := newGameMonitor(logger, clock.SystemClock, fetchBlockNum, allowedGame, source, games.CreateGame) monitor := newGameMonitor(logger, clock.SystemClock, fetchBlockNum, allowedGames, source, games.CreateGame)
return monitor, source, games return monitor, source, games
} }
......
...@@ -73,7 +73,7 @@ func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*se ...@@ -73,7 +73,7 @@ func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*se
} }
loader := NewGameLoader(factory) loader := NewGameLoader(factory)
monitor := newGameMonitor(logger, cl, client.BlockNumber, cfg.GameAddress, loader, func(addr common.Address) (gamePlayer, error) { monitor := newGameMonitor(logger, cl, client.BlockNumber, cfg.GameAllowlist, loader, func(addr common.Address) (gamePlayer, error) {
return NewGamePlayer(ctx, logger, cfg, addr, txMgr, client) return NewGamePlayer(ctx, logger, cfg, addr, txMgr, client)
}) })
......
...@@ -4,6 +4,9 @@ import ( ...@@ -4,6 +4,9 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/ethereum/go-ethereum/common"
"github.com/urfave/cli/v2"
"github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-node/chaincfg" "github.com/ethereum-optimism/optimism/op-node/chaincfg"
opservice "github.com/ethereum-optimism/optimism/op-service" opservice "github.com/ethereum-optimism/optimism/op-service"
...@@ -12,9 +15,6 @@ import ( ...@@ -12,9 +15,6 @@ import (
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof" oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
"github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/common"
"github.com/urfave/cli/v2"
) )
const ( const (
...@@ -37,10 +37,11 @@ var ( ...@@ -37,10 +37,11 @@ var (
Usage: "Address of the fault game factory contract.", Usage: "Address of the fault game factory contract.",
EnvVars: prefixEnvVars("GAME_FACTORY_ADDRESS"), EnvVars: prefixEnvVars("GAME_FACTORY_ADDRESS"),
} }
GameAddressFlag = &cli.StringFlag{ GameAllowlistFlag = &cli.StringSliceFlag{
Name: "game-address", Name: "game-allowlist",
Usage: "Address of the Fault Game contract.", Usage: "List of Fault Game contract addresses the challenger is allowed to play. " +
EnvVars: prefixEnvVars("GAME_ADDRESS"), "If empty, the challenger will play all games.",
EnvVars: prefixEnvVars("GAME_ALLOWLIST"),
} }
TraceTypeFlag = &cli.GenericFlag{ TraceTypeFlag = &cli.GenericFlag{
Name: "trace-type", Name: "trace-type",
...@@ -121,7 +122,7 @@ var requiredFlags = []cli.Flag{ ...@@ -121,7 +122,7 @@ var requiredFlags = []cli.Flag{
// optionalFlags is a list of unchecked cli flags // optionalFlags is a list of unchecked cli flags
var optionalFlags = []cli.Flag{ var optionalFlags = []cli.Flag{
AlphabetFlag, AlphabetFlag,
GameAddressFlag, GameAllowlistFlag,
CannonNetworkFlag, CannonNetworkFlag,
CannonRollupConfigFlag, CannonRollupConfigFlag,
CannonL2GenesisFlag, CannonL2GenesisFlag,
...@@ -154,11 +155,13 @@ func CheckRequired(ctx *cli.Context) error { ...@@ -154,11 +155,13 @@ func CheckRequired(ctx *cli.Context) error {
gameType := config.TraceType(strings.ToLower(ctx.String(TraceTypeFlag.Name))) gameType := config.TraceType(strings.ToLower(ctx.String(TraceTypeFlag.Name)))
switch gameType { switch gameType {
case config.TraceTypeCannon: case config.TraceTypeCannon:
if !ctx.IsSet(CannonNetworkFlag.Name) && !(ctx.IsSet(CannonRollupConfigFlag.Name) && ctx.IsSet(CannonL2GenesisFlag.Name)) { if !ctx.IsSet(CannonNetworkFlag.Name) &&
!(ctx.IsSet(CannonRollupConfigFlag.Name) && ctx.IsSet(CannonL2GenesisFlag.Name)) {
return fmt.Errorf("flag %v or %v and %v is required", return fmt.Errorf("flag %v or %v and %v is required",
CannonNetworkFlag.Name, CannonRollupConfigFlag.Name, CannonL2GenesisFlag.Name) CannonNetworkFlag.Name, CannonRollupConfigFlag.Name, CannonL2GenesisFlag.Name)
} }
if ctx.IsSet(CannonNetworkFlag.Name) && (ctx.IsSet(CannonRollupConfigFlag.Name) || ctx.IsSet(CannonL2GenesisFlag.Name)) { if ctx.IsSet(CannonNetworkFlag.Name) &&
(ctx.IsSet(CannonRollupConfigFlag.Name) || ctx.IsSet(CannonL2GenesisFlag.Name)) {
return fmt.Errorf("flag %v can not be used with %v and %v", return fmt.Errorf("flag %v can not be used with %v and %v",
CannonNetworkFlag.Name, CannonRollupConfigFlag.Name, CannonL2GenesisFlag.Name) CannonNetworkFlag.Name, CannonRollupConfigFlag.Name, CannonL2GenesisFlag.Name)
} }
...@@ -196,12 +199,15 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) { ...@@ -196,12 +199,15 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
var gameAddress common.Address var allowedGames []common.Address
if ctx.IsSet(GameAddressFlag.Name) { if ctx.StringSlice(GameAllowlistFlag.Name) != nil {
gameAddress, err = opservice.ParseAddress(ctx.String(GameAddressFlag.Name)) for _, addr := range ctx.StringSlice(GameAllowlistFlag.Name) {
gameAddress, err := opservice.ParseAddress(addr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
allowedGames = append(allowedGames, gameAddress)
}
} }
txMgrConfig := txmgr.ReadCLIConfig(ctx) txMgrConfig := txmgr.ReadCLIConfig(ctx)
...@@ -215,7 +221,7 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) { ...@@ -215,7 +221,7 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) {
L1EthRpc: ctx.String(L1EthRpcFlag.Name), L1EthRpc: ctx.String(L1EthRpcFlag.Name),
TraceType: traceTypeFlag, TraceType: traceTypeFlag,
GameFactoryAddress: gameFactoryAddress, GameFactoryAddress: gameFactoryAddress,
GameAddress: gameAddress, GameAllowlist: allowedGames,
AlphabetTrace: ctx.String(AlphabetFlag.Name), AlphabetTrace: ctx.String(AlphabetFlag.Name),
CannonNetwork: ctx.String(CannonNetworkFlag.Name), CannonNetwork: ctx.String(CannonNetworkFlag.Name),
CannonRollupConfigPath: ctx.String(CannonRollupConfigFlag.Name), CannonRollupConfigPath: ctx.String(CannonRollupConfigFlag.Name),
......
...@@ -38,7 +38,10 @@ func WithFactoryAddress(addr common.Address) Option { ...@@ -38,7 +38,10 @@ func WithFactoryAddress(addr common.Address) Option {
func WithGameAddress(addr common.Address) Option { func WithGameAddress(addr common.Address) Option {
return func(c *config.Config) { return func(c *config.Config) {
c.GameAddress = addr if c.GameAllowlist == nil {
c.GameAllowlist = make([]common.Address, 0)
}
c.GameAllowlist = append(c.GameAllowlist, addr)
} }
} }
......
...@@ -5,6 +5,8 @@ import ( ...@@ -5,6 +5,8 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum/go-ethereum/common"
) )
type AlphabetGameHelper struct { type AlphabetGameHelper struct {
...@@ -16,7 +18,7 @@ func (g *AlphabetGameHelper) StartChallenger(ctx context.Context, l1Endpoint str ...@@ -16,7 +18,7 @@ func (g *AlphabetGameHelper) StartChallenger(ctx context.Context, l1Endpoint str
opts := []challenger.Option{ opts := []challenger.Option{
func(c *config.Config) { func(c *config.Config) {
c.GameFactoryAddress = g.factoryAddr c.GameFactoryAddress = g.factoryAddr
c.GameAddress = g.addr c.GameAllowlist = []common.Address{g.addr}
c.TraceType = config.TraceTypeAlphabet c.TraceType = config.TraceTypeAlphabet
// By default the challenger agrees with the root claim (thus disagrees with the proposed output) // By default the challenger agrees with the root claim (thus disagrees with the proposed output)
// This can be overridden by passing in options // This can be overridden by passing in options
......
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