Skip to content

Commit

Permalink
feat: specify number of L2s to spin up (#309)
Browse files Browse the repository at this point in the history
* l2 count

* fixes
  • Loading branch information
hamdiallam authored Dec 22, 2024
1 parent b27245e commit 0e8c196
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 242 deletions.
11 changes: 5 additions & 6 deletions admin/admin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ import (
"testing"
"time"

"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum-optimism/supersim/config"
"github.com/ethereum-optimism/supersim/genesis"
"github.com/ethereum-optimism/supersim/testutils"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestAdminServerBasicFunctionality(t *testing.T) {
networkConfig := config.GetDefaultNetworkConfig(uint64(time.Now().Unix()), "")
networkConfig := config.GetNetworkConfig(&config.CLIConfig{L2Count: 2})
testlog := testlog.Logger(t, log.LevelInfo)

ctx, cancel := context.WithCancel(context.Background())
Expand All @@ -42,7 +42,7 @@ func TestAdminServerBasicFunctionality(t *testing.T) {
}

func TestGetL1AddressesRPC(t *testing.T) {
networkConfig := config.GetDefaultNetworkConfig(uint64(time.Now().Unix()), "")
networkConfig := config.GetNetworkConfig(&config.CLIConfig{L2Count: 2})
testlog := testlog.Logger(t, log.LevelInfo)

ctx, cancel := context.WithCancel(context.Background())
Expand All @@ -52,15 +52,14 @@ func TestGetL1AddressesRPC(t *testing.T) {
require.NoError(t, adminServer.Start(ctx))

var client *rpc.Client
waitErr := testutils.WaitForWithTimeout(context.Background(), 500*time.Millisecond, 10*time.Second, func() (bool, error) {
require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) {
newClient, err := rpc.Dial(adminServer.Endpoint())
if err != nil {
return false, err
}
client = newClient
return true, nil
})
assert.NoError(t, waitErr)
}))

var addresses map[string]string
chainID := genesis.GeneratedGenesisDeployment.L2s[1].ChainID
Expand Down
70 changes: 39 additions & 31 deletions config/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"math/big"
"strings"
"time"

"github.com/ethereum-optimism/optimism/op-chain-ops/devkeys"
registry "github.com/ethereum-optimism/superchain-registry/superchain"
Expand Down Expand Up @@ -100,53 +101,60 @@ type Chain interface {
Stop(ctx context.Context) error
}

func GetDefaultNetworkConfig(startingTimestamp uint64, logsDirectory string) NetworkConfig {
return NetworkConfig{
func GetNetworkConfig(cliConfig *CLIConfig) NetworkConfig {
startingTimestamp := uint64(time.Now().Unix())
nameSuffix := []string{"A", "B", "C", "D", "E"}

cfg := NetworkConfig{
// Enabled by default as it is included in genesis
InteropEnabled: true,

// Populated based on L2 count
L2Configs: make([]ChainConfig, cliConfig.L2Count),

L1Config: ChainConfig{
Name: "Local",
ChainID: genesis.GeneratedGenesisDeployment.L1.ChainID,
SecretsConfig: DefaultSecretsConfig,
GenesisJSON: genesis.GeneratedGenesisDeployment.L1.GenesisJSON,
StartingTimestamp: startingTimestamp,
LogsDirectory: logsDirectory,
LogsDirectory: cliConfig.LogsDirectory,
},
L2Configs: []ChainConfig{
{
Name: "OPChainA",
ChainID: genesis.GeneratedGenesisDeployment.L2s[0].ChainID,
SecretsConfig: DefaultSecretsConfig,
GenesisJSON: genesis.GeneratedGenesisDeployment.L2s[0].GenesisJSON,
L2Config: &L2Config{
L1ChainID: genesis.GeneratedGenesisDeployment.L1.ChainID,
L1Addresses: genesis.GeneratedGenesisDeployment.L2s[0].RegistryAddressList(),
DependencySet: []uint64{genesis.GeneratedGenesisDeployment.L2s[1].ChainID},
},
StartingTimestamp: startingTimestamp,
LogsDirectory: logsDirectory,
},
{
Name: "OPChainB",
ChainID: genesis.GeneratedGenesisDeployment.L2s[1].ChainID,
SecretsConfig: DefaultSecretsConfig,
GenesisJSON: genesis.GeneratedGenesisDeployment.L2s[1].GenesisJSON,
L2Config: &L2Config{
L1ChainID: genesis.GeneratedGenesisDeployment.L1.ChainID,
L1Addresses: genesis.GeneratedGenesisDeployment.L2s[1].RegistryAddressList(),
DependencySet: []uint64{genesis.GeneratedGenesisDeployment.L2s[0].ChainID},
},
StartingTimestamp: startingTimestamp,
LogsDirectory: logsDirectory,
}

for i := uint64(0); i < cliConfig.L2Count; i++ {
l2Cfg := ChainConfig{
Name: fmt.Sprintf("OPChain%s", nameSuffix[i]),
ChainID: genesis.GeneratedGenesisDeployment.L2s[i].ChainID,
SecretsConfig: DefaultSecretsConfig,
GenesisJSON: genesis.GeneratedGenesisDeployment.L2s[i].GenesisJSON,
StartingTimestamp: startingTimestamp,
LogsDirectory: cliConfig.LogsDirectory,
L2Config: &L2Config{
L1ChainID: genesis.GeneratedGenesisDeployment.L1.ChainID,
L1Addresses: genesis.GeneratedGenesisDeployment.L2s[i].RegistryAddressList(),
DependencySet: []uint64{},
},
},
}

// populate dep set
for j := uint64(0); j < cliConfig.L2Count; j++ {
if i == j {
continue
}

peerChainID := genesis.GeneratedGenesisDeployment.L2s[j].ChainID
l2Cfg.L2Config.DependencySet = append(l2Cfg.L2Config.DependencySet, peerChainID)
}

cfg.L2Configs[i] = l2Cfg
}

return cfg
}

// Note: The default secrets config is used everywhere
func DefaultSecretsConfigAsString() string {

keys, err := devkeys.NewMnemonicDevKeys(devkeys.TestMnemonic)
if err != nil {
panic(err)
Expand Down
26 changes: 21 additions & 5 deletions config/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const (
NetworkFlagName = "network"
L2StartingPortFlagName = "l2.starting.port"
L2HostFlagName = "l2.host"
L2CountFlagName = "l2.count"

LogsDirectoryFlagName = "logs.directory"

Expand All @@ -36,6 +37,8 @@ const (
InteropDelayFlagName = "interop.delay"

OdysseyEnabledFlagName = "odyssey.enabled"

MaxL2Count = 5
)

var documentationLinks = []struct {
Expand All @@ -61,6 +64,12 @@ func BaseCLIFlags(envPrefix string) []cli.Flag {
Value: 8545,
EnvVars: opservice.PrefixEnvVar(envPrefix, "L1_PORT"),
},
&cli.Uint64Flag{
Name: L2CountFlagName,
Usage: fmt.Sprintf("Number of L2s. Max of %d", MaxL2Count),
Value: 2,
EnvVars: opservice.PrefixEnvVar(envPrefix, "L2_COUNT"),
},
&cli.Uint64Flag{
Name: L2StartingPortFlagName,
Usage: "Starting port to increment from for L2 chains. `0` binds each chain to any available port",
Expand Down Expand Up @@ -149,8 +158,10 @@ type ForkCLIConfig struct {
type CLIConfig struct {
AdminPort uint64

L1Port uint64
L1Port uint64

L2StartingPort uint64
L2Count uint64

InteropAutoRelay bool
InteropDelay uint64
Expand All @@ -169,18 +180,19 @@ func ReadCLIConfig(ctx *cli.Context) (*CLIConfig, error) {
cfg := &CLIConfig{
AdminPort: ctx.Uint64(AdminPortFlagName),

L1Port: ctx.Uint64(L1PortFlagName),
L1Port: ctx.Uint64(L1PortFlagName),
L1Host: ctx.String(L1HostFlagName),

L2StartingPort: ctx.Uint64(L2StartingPortFlagName),
L2Count: ctx.Uint64(L2CountFlagName),
L2Host: ctx.String(L2HostFlagName),

InteropAutoRelay: ctx.Bool(InteropAutoRelayFlagName),
InteropDelay: ctx.Uint64(InteropDelayFlagName),

LogsDirectory: ctx.String(LogsDirectoryFlagName),

OdysseyEnabled: ctx.Bool(OdysseyEnabledFlagName),

L1Host: ctx.String(L1HostFlagName),
L2Host: ctx.String(L2HostFlagName),
}

if ctx.Command.Name == ForkCommandName {
Expand All @@ -206,6 +218,10 @@ func (c *CLIConfig) Check() error {
return fmt.Errorf("invalid L2 host address: %w", err)
}

if c.L2Count == 0 || c.L2Count > MaxL2Count {
return fmt.Errorf("min 1, max %d L2 chains", MaxL2Count)
}

if c.ForkConfig != nil {
forkCfg := c.ForkConfig

Expand Down
4 changes: 2 additions & 2 deletions orchestrator/orchestrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,15 @@ func (o *Orchestrator) Start(ctx context.Context) error {
o.log.Info("configuring interop contracts")

var wg sync.WaitGroup
var errs []error
wg.Add(len(o.l2Chains))
errs := make([]error, len(o.l2Chains))

// Iterate over the underlying l2Chains for configuration as it relies
// on deposit txs from system addresses which opsimulator will reject
for i, chain := range o.l2Chains {
go func(i uint64) {
if err := interop.Configure(ctx, chain); err != nil {
errs[i] = fmt.Errorf("failed to configure interop for chain %s: %w", chain.Config().Name, err)
errs = append(errs, fmt.Errorf("failed to configure interop for chain %s: %w", chain.Config().Name, err))
}
wg.Done()
}(i)
Expand Down
92 changes: 0 additions & 92 deletions orchestrator/orchestrator_test.go

This file was deleted.

Loading

0 comments on commit 0e8c196

Please sign in to comment.