Skip to content

Commit

Permalink
op-deployer: Add support for additional dispute games (ethereum-optim…
Browse files Browse the repository at this point in the history
…ism#13346)

Users can now specify additional dispute games with custom VM types and preimage oracles. This will help with removing allocs files in the future.
  • Loading branch information
mslipper authored Dec 11, 2024
1 parent 8398e25 commit 4d30eea
Show file tree
Hide file tree
Showing 12 changed files with 320 additions and 51 deletions.
13 changes: 10 additions & 3 deletions op-deployer/pkg/deployer/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,11 @@ func ApplyPipeline(
L2: l2ArtifactsFS,
}

var deployer common.Address
deployer := common.Address{0x01}
if opts.DeployerPrivateKey != nil {
deployer = crypto.PubkeyToAddress(opts.DeployerPrivateKey.PublicKey)
}

var bcaster broadcaster.Broadcaster
var l1Client *ethclient.Client
var l1Host *script.Host
Expand All @@ -193,7 +197,6 @@ func ApplyPipeline(
}

signer := opcrypto.SignerFnFromBind(opcrypto.PrivateKeySignerFn(opts.DeployerPrivateKey, chainID))
deployer = crypto.PubkeyToAddress(opts.DeployerPrivateKey.PublicKey)

bcaster, err = broadcaster.NewKeyedBroadcaster(broadcaster.KeyedBroadcasterOpts{
Logger: opts.Logger,
Expand Down Expand Up @@ -235,7 +238,6 @@ func ApplyPipeline(
return fmt.Errorf("failed to select fork: %w", err)
}
} else {
deployer = common.Address{0x01}
bcaster = broadcaster.NoopBroadcaster()
l1Host, err = env.DefaultScriptHost(
bcaster,
Expand Down Expand Up @@ -286,6 +288,11 @@ func ApplyPipeline(
func() error {
return pipeline.DeployAltDA(pEnv, intent, st, chainID)
},
}, pipelineStage{
fmt.Sprintf("deploy-additional-dispute-games-%s", chainID.Hex()),
func() error {
return pipeline.DeployAdditionalDisputeGames(pEnv, intent, st, chainID)
},
}, pipelineStage{
fmt.Sprintf("generate-l2-genesis-%s", chainID.Hex()),
func() error {
Expand Down
3 changes: 2 additions & 1 deletion op-deployer/pkg/deployer/bootstrap/dispute_game.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"crypto/ecdsa"
"fmt"
"math/big"
"strings"

artifacts2 "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/artifacts"
Expand Down Expand Up @@ -224,7 +225,7 @@ func DisputeGame(ctx context.Context, cfg DisputeGameConfig) (opcm.DeployDispute
MaxClockDuration: cfg.MaxClockDuration,
DelayedWethProxy: cfg.DelayedWethProxy,
AnchorStateRegistryProxy: cfg.AnchorStateRegistryProxy,
L2ChainId: cfg.L2ChainId,
L2ChainId: common.BigToHash(new(big.Int).SetUint64(cfg.L2ChainId)),
Proposer: cfg.Proposer,
Challenger: cfg.Challenger,
},
Expand Down
42 changes: 41 additions & 1 deletion op-deployer/pkg/deployer/integration_test/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,47 @@ func TestInvalidL2Genesis(t *testing.T) {
}
}

func TestAdditionalDisputeGames(t *testing.T) {
op_e2e.InitParallel(t)

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

opts, intent, st := setupGenesisChain(t, defaultL1ChainID)
(&intent.Chains[0].Roles).L1ProxyAdminOwner = crypto.PubkeyToAddress(opts.DeployerPrivateKey.PublicKey)
intent.GlobalDeployOverrides = map[string]any{
"challengePeriodSeconds": 1,
}
intent.Chains[0].AdditionalDisputeGames = []state.AdditionalDisputeGame{
{
ChainProofParams: state.ChainProofParams{
DisputeGameType: 255,
DisputeAbsolutePrestate: standard.DisputeAbsolutePrestate,
DisputeMaxGameDepth: 50,
DisputeSplitDepth: 14,
DisputeClockExtension: 0,
DisputeMaxClockDuration: 1200,
DangerouslyAllowCustomDisputeParameters: true,
},
UseCustomOracle: true,
OracleMinProposalSize: 10000,
OracleChallengePeriodSeconds: 120,
VMType: state.VMTypeAlphabet,
},
}

require.NoError(t, deployer.ApplyPipeline(ctx, opts))

chainState := st.Chains[0]
require.Equal(t, 1, len(chainState.AdditionalDisputeGames))

gameInfo := chainState.AdditionalDisputeGames[0]
require.NotEmpty(t, gameInfo.VMAddress)
require.NotEmpty(t, gameInfo.GameAddress)
require.NotEmpty(t, gameInfo.OracleAddress)
require.NotEqual(t, st.ImplementationsDeployment.PreimageOracleSingletonAddress, gameInfo.OracleAddress)
}

func setupGenesisChain(t *testing.T, l1ChainID uint64) (deployer.ApplyPipelineOpts, *state.Intent, *state.State) {
lgr := testlog.Logger(t, slog.LevelDebug)

Expand All @@ -711,7 +752,6 @@ func setupGenesisChain(t *testing.T, l1ChainID uint64) (deployer.ApplyPipelineOp
loc, _ := testutil.LocalArtifacts(t)

intent, st := newIntent(t, l1ChainIDBig, dk, l2ChainID1, loc, loc)
intent.Chains = append(intent.Chains, newChainIntent(t, dk, l1ChainIDBig, l2ChainID1))
intent.DeploymentStrategy = state.DeploymentStrategyGenesis

opts := deployer.ApplyPipelineOpts{
Expand Down
2 changes: 1 addition & 1 deletion op-deployer/pkg/deployer/opcm/dispute_game.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type DeployDisputeGameInput struct {
MaxClockDuration uint64
DelayedWethProxy common.Address
AnchorStateRegistryProxy common.Address
L2ChainId uint64
L2ChainId common.Hash
Proposer common.Address
Challenger common.Address
}
Expand Down
3 changes: 2 additions & 1 deletion op-deployer/pkg/deployer/opcm/dispute_game_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package opcm

import (
"math/big"
"testing"

"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/broadcaster"
Expand Down Expand Up @@ -47,7 +48,7 @@ func TestDeployDisputeGame(t *testing.T) {
MaxClockDuration: standard.DisputeMaxClockDuration,
DelayedWethProxy: common.Address{'D'},
AnchorStateRegistryProxy: common.Address{'A'},
L2ChainId: 69,
L2ChainId: common.BigToHash(big.NewInt(69)),
Proposer: common.Address{'P'},
Challenger: common.Address{'C'},
}
Expand Down
145 changes: 145 additions & 0 deletions op-deployer/pkg/deployer/pipeline/dispute_games.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package pipeline

import (
"fmt"
"math/big"

"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/standard"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/state"
"github.com/ethereum/go-ethereum/common"
)

func DeployAdditionalDisputeGames(
env *Env,
intent *state.Intent,
st *state.State,
chainID common.Hash,
) error {
lgr := env.Logger.New("stage", "deploy-additional-dispute-games")

thisIntent, err := intent.Chain(chainID)
if err != nil {
return fmt.Errorf("failed to get chain intent: %w", err)
}

thisState, err := st.Chain(chainID)
if err != nil {
return fmt.Errorf("failed to get chain state: %w", err)
}

if !shouldDeployAdditionalDisputeGames(thisIntent, thisState) {
lgr.Info("additional dispute games deployment not needed")
return nil
}

if thisIntent.Roles.L1ProxyAdminOwner != env.Deployer {
return fmt.Errorf("cannot deploy additional dispute games when deployer is not L1PAO")
}

for _, game := range thisIntent.AdditionalDisputeGames {
if err := deployDisputeGame(env, st, thisIntent, thisState, game); err != nil {
return fmt.Errorf("failed to deploy additional dispute game: %w", err)
}
}

return nil
}

func deployDisputeGame(
env *Env,
st *state.State,
thisIntent *state.ChainIntent,
thisState *state.ChainState,
game state.AdditionalDisputeGame,
) error {
lgr := env.Logger.New("gameType", game.DisputeGameType)

var oracleAddr common.Address
if game.UseCustomOracle {
lgr.Info("deploying custom oracle")

out, err := opcm.DeployPreimageOracle(env.L1ScriptHost, opcm.DeployPreimageOracleInput{
MinProposalSize: new(big.Int).SetUint64(game.OracleMinProposalSize),
ChallengePeriod: new(big.Int).SetUint64(game.OracleChallengePeriodSeconds),
})
if err != nil {
return fmt.Errorf("failed to deploy preimage oracle: %w", err)
}
oracleAddr = out.PreimageOracle
} else {
lgr.Debug("using existing preimage oracle")
}

lgr.Info("deploying VM", "vmType", game.VMType)
var vmAddr common.Address
switch game.VMType {
case state.VMTypeAlphabet:
out, err := opcm.DeployAlphabetVM(env.L1ScriptHost, opcm.DeployAlphabetVMInput{
AbsolutePrestate: game.DisputeAbsolutePrestate,
PreimageOracle: st.ImplementationsDeployment.PreimageOracleSingletonAddress,
})
if err != nil {
return fmt.Errorf("failed to deploy Alphabet VM: %w", err)
}
vmAddr = out.AlphabetVM
default:
return fmt.Errorf("unsupported VM type: %v", game.VMType)
}
lgr.Info("vm deployed", "vmAddr", vmAddr)

lgr.Info("deploying dispute game")
out, err := opcm.DeployDisputeGame(env.L1ScriptHost, opcm.DeployDisputeGameInput{
Release: "dev",
VmAddress: vmAddr,
GameKind: "FaultDisputeGame",
GameType: game.DisputeGameType,
AbsolutePrestate: standard.DisputeAbsolutePrestate,
MaxGameDepth: game.DisputeMaxGameDepth,
SplitDepth: game.DisputeSplitDepth,
ClockExtension: game.DisputeClockExtension,
MaxClockDuration: game.DisputeMaxClockDuration,
DelayedWethProxy: thisState.DelayedWETHPermissionedGameProxyAddress,
AnchorStateRegistryProxy: thisState.AnchorStateRegistryProxyAddress,
L2ChainId: thisIntent.ID,
Proposer: thisIntent.Roles.Proposer,
Challenger: thisIntent.Roles.Challenger,
})
if err != nil {
return fmt.Errorf("failed to deploy dispute game: %w", err)
}
lgr.Info("dispute game deployed", "impl", out.DisputeGameImpl)

lgr.Info("setting dispute game impl on factory")
if err := opcm.SetDisputeGameImpl(
env.L1ScriptHost,
opcm.SetDisputeGameImplInput{
Factory: thisState.DisputeGameFactoryProxyAddress,
Impl: out.DisputeGameImpl,
},
); err != nil {
return fmt.Errorf("failed to set dispute game impl: %w", err)
}

thisState.AdditionalDisputeGames = append(thisState.AdditionalDisputeGames, state.AdditionalDisputeGameState{
GameType: game.DisputeGameType,
VMType: game.VMType,
GameAddress: out.DisputeGameImpl,
OracleAddress: oracleAddr,
VMAddress: vmAddr,
})

return nil
}

func shouldDeployAdditionalDisputeGames(thisIntent *state.ChainIntent, thisState *state.ChainState) bool {
if len(thisIntent.AdditionalDisputeGames) == 0 {
return false
}

if len(thisState.AdditionalDisputeGames) > 0 {
return false
}

return true
}
13 changes: 2 additions & 11 deletions op-deployer/pkg/deployer/pipeline/implementations.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,13 @@ import (
"fmt"
"math/big"

"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/standard"
"github.com/ethereum-optimism/optimism/op-service/jsonutil"

"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/standard"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/state"
)

type SuperchainProofParams struct {
WithdrawalDelaySeconds uint64 `json:"withdrawalDelaySeconds" toml:"withdrawalDelaySeconds"`
MinProposalSizeBytes uint64 `json:"minProposalSizeBytes" toml:"minProposalSizeBytes"`
ChallengePeriodSeconds uint64 `json:"challengePeriodSeconds" toml:"challengePeriodSeconds"`
ProofMaturityDelaySeconds uint64 `json:"proofMaturityDelaySeconds" toml:"proofMaturityDelaySeconds"`
DisputeGameFinalityDelaySeconds uint64 `json:"disputeGameFinalityDelaySeconds" toml:"disputeGameFinalityDelaySeconds"`
MIPSVersion uint64 `json:"mipsVersion" toml:"mipsVersion"`
}

func DeployImplementations(env *Env, intent *state.Intent, st *state.State) error {
lgr := env.Logger.New("stage", "deploy-implementations")

Expand All @@ -46,7 +37,7 @@ func DeployImplementations(env *Env, intent *state.Intent, st *state.State) erro
}

proofParams, err := jsonutil.MergeJSON(
SuperchainProofParams{
state.SuperchainProofParams{
WithdrawalDelaySeconds: standard.WithdrawalDelaySeconds,
MinProposalSizeBytes: standard.MinProposalSizeBytes,
ChallengePeriodSeconds: standard.ChallengePeriodSeconds,
Expand Down
14 changes: 2 additions & 12 deletions op-deployer/pkg/deployer/pipeline/opchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package pipeline
import (
"fmt"

"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/standard"
"github.com/ethereum-optimism/optimism/op-service/jsonutil"

"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/standard"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/state"
"github.com/ethereum/go-ethereum/common"
)
Expand Down Expand Up @@ -89,19 +89,9 @@ func DeployOPChain(env *Env, intent *state.Intent, st *state.State, chainID comm
return nil
}

type ChainProofParams struct {
DisputeGameType uint32 `json:"disputeGameType" toml:"disputeGameType"`
DisputeAbsolutePrestate common.Hash `json:"disputeAbsolutePrestate" toml:"disputeAbsolutePrestate"`
DisputeMaxGameDepth uint64 `json:"disputeMaxGameDepth" toml:"disputeMaxGameDepth"`
DisputeSplitDepth uint64 `json:"disputeSplitDepth" toml:"disputeSplitDepth"`
DisputeClockExtension uint64 `json:"disputeClockExtension" toml:"disputeClockExtension"`
DisputeMaxClockDuration uint64 `json:"disputeMaxClockDuration" toml:"disputeMaxClockDuration"`
DangerouslyAllowCustomDisputeParameters bool `json:"dangerouslyAllowCustomDisputeParameters" toml:"dangerouslyAllowCustomDisputeParameters"`
}

func makeDCIV160(intent *state.Intent, thisIntent *state.ChainIntent, chainID common.Hash, st *state.State) (opcm.DeployOPChainInputV160, error) {
proofParams, err := jsonutil.MergeJSON(
ChainProofParams{
state.ChainProofParams{
DisputeGameType: standard.DisputeGameType,
DisputeAbsolutePrestate: standard.DisputeAbsolutePrestate,
DisputeMaxGameDepth: standard.DisputeMaxGameDepth,
Expand Down
25 changes: 25 additions & 0 deletions op-deployer/pkg/deployer/state/chain_intent.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,30 @@ import (
"github.com/ethereum/go-ethereum/common"
)

type VMType string

const (
VMTypeAlphabet = "ALPHABET"
)

type ChainProofParams struct {
DisputeGameType uint32 `json:"disputeGameType" toml:"disputeGameType"`
DisputeAbsolutePrestate common.Hash `json:"disputeAbsolutePrestate" toml:"disputeAbsolutePrestate"`
DisputeMaxGameDepth uint64 `json:"disputeMaxGameDepth" toml:"disputeMaxGameDepth"`
DisputeSplitDepth uint64 `json:"disputeSplitDepth" toml:"disputeSplitDepth"`
DisputeClockExtension uint64 `json:"disputeClockExtension" toml:"disputeClockExtension"`
DisputeMaxClockDuration uint64 `json:"disputeMaxClockDuration" toml:"disputeMaxClockDuration"`
DangerouslyAllowCustomDisputeParameters bool `json:"dangerouslyAllowCustomDisputeParameters" toml:"dangerouslyAllowCustomDisputeParameters"`
}

type AdditionalDisputeGame struct {
ChainProofParams
VMType VMType
UseCustomOracle bool
OracleMinProposalSize uint64
OracleChallengePeriodSeconds uint64
}

type ChainIntent struct {
ID common.Hash `json:"id" toml:"id"`
BaseFeeVaultRecipient common.Address `json:"baseFeeVaultRecipient" toml:"baseFeeVaultRecipient"`
Expand All @@ -19,6 +43,7 @@ type ChainIntent struct {
Roles ChainRoles `json:"roles" toml:"roles"`
DeployOverrides map[string]any `json:"deployOverrides" toml:"deployOverrides"`
DangerousAltDAConfig genesis.AltDADeployConfig `json:"dangerousAltDAConfig,omitempty" toml:"dangerousAltDAConfig,omitempty"`
AdditionalDisputeGames []AdditionalDisputeGame `json:"dangerousAdditionalDisputeGames" toml:"dangerousAdditionalDisputeGames,omitempty"`
}

type ChainRoles struct {
Expand Down
Loading

0 comments on commit 4d30eea

Please sign in to comment.