Skip to content

Commit

Permalink
feat: op-program supports custom chain config (ethereum-optimism#12310)
Browse files Browse the repository at this point in the history
* feat: op-program supports custom chain config

* address comments

* address comments

* update mainnet.go/sepolia.go

* Update op-program/chainconfig/chaincfg.go

Co-authored-by: Adrian Sutton <[email protected]>

* more error info on config file not found

---------

Co-authored-by: Qi Zhou <[email protected]>
Co-authored-by: Adrian Sutton <[email protected]>
  • Loading branch information
3 people authored and samlaf committed Nov 10, 2024
1 parent ab52c30 commit efad673
Show file tree
Hide file tree
Showing 11 changed files with 15,661 additions and 32 deletions.
4 changes: 4 additions & 0 deletions op-program/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ test:
verify-sepolia: op-program-host op-program-client
env GO111MODULE=on go run ./verify/sepolia/cmd/sepolia.go --l1 $$SEPOLIA_L1URL --l1.beacon $$SEPOLIA_BEACON_URL --l2 $$SEPOLIA_L2URL --datadir /tmp/test-sepolia

verify-devnet:
env GO111MODULE=on go run ./verify/devnet/cmd/devnet.go --l1 http://localhost:8545 --l1.beacon http://localhost:5052 --l2 http://localhost:9545 --datadir /tmp/test-devnet

capture-mainnet-genesis: op-program-host op-program-client
rm -rf "$(COMPAT_DIR)/mainnet-genesis" "$(COMPAT_DIR)/mainnet-genesis.tar.bz"
env GO111MODULE=on go run ./verify/mainnet/cmd/mainnet.go --l1 $$MAINNET_L1URL --l1.beacon $$MAINNET_BEACON_URL --l2 $$MAINNET_L2URL --datadir "$(COMPAT_DIR)/mainnet-genesis" --l1.head "0x4903424f6cc2cfba7c2bf8c8f48ca46721c963fa64b411cfee3697b781e3e5f1" --l2.start "105235063" --l2.end "105235064"
Expand Down Expand Up @@ -97,6 +100,7 @@ verify-compat: verify-sepolia-delta verify-sepolia-ecotone verify-mainnet-genesi
test \
capture-goerli-verify \
verify-sepolia \
verify-devnet \
capture-mainnet-genesis \
capture-sepolia-delta \
capture-sepolia-ecotone \
Expand Down
51 changes: 48 additions & 3 deletions op-program/chainconfig/chaincfg.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package chainconfig

import (
"embed"
"encoding/json"
"errors"
"fmt"
"os"

"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/params"
)

Expand All @@ -13,16 +18,56 @@ func OPSepoliaChainConfig() *params.ChainConfig {
return mustLoadChainConfig("op-sepolia")
}

//go:embed configs/*json
var customChainConfigFS embed.FS

func RollupConfigByChainID(chainID uint64) (*rollup.Config, error) {
config, err := rollup.LoadOPStackRollupConfig(chainID)
if err != nil {
if err == nil {
return config, err
}
return rollupConfigByChainID(chainID, customChainConfigFS)
}

func rollupConfigByChainID(chainID uint64, customChainFS embed.FS) (*rollup.Config, error) {
// Load custom rollup configs from embed FS
file, err := customChainFS.Open(fmt.Sprintf("configs/%d-rollup.json", chainID))
if errors.Is(err, os.ErrNotExist) {
return nil, fmt.Errorf("no rollup config available for chain ID: %d", chainID)
} else if err != nil {
return nil, fmt.Errorf("failed to get rollup config for chain ID %d: %w", chainID, err)
}
return config, nil
dec := json.NewDecoder(file)
dec.DisallowUnknownFields()
var customRollupConfig rollup.Config
if err := dec.Decode(&customRollupConfig); err != nil {
return nil, fmt.Errorf("failed to parse rollup config for chain ID %d: %w", chainID, err)
}
return &customRollupConfig, nil
}

func ChainConfigByChainID(chainID uint64) (*params.ChainConfig, error) {
return params.LoadOPStackChainConfig(chainID)
config, err := params.LoadOPStackChainConfig(chainID)
if err == nil {
return config, err
}
return chainConfigByChainID(chainID, customChainConfigFS)
}

func chainConfigByChainID(chainID uint64, customChainFS embed.FS) (*params.ChainConfig, error) {
// Load from custom chain configs from embed FS
data, err := customChainFS.ReadFile(fmt.Sprintf("configs/%d-genesis-l2.json", chainID))
if errors.Is(err, os.ErrNotExist) {
return nil, fmt.Errorf("no chain config available for chain ID: %d", chainID)
} else if err != nil {
return nil, fmt.Errorf("failed to get chain config for chain ID %d: %w", chainID, err)
}
var genesis core.Genesis
err = json.Unmarshal(data, &genesis)
if err != nil {
return nil, fmt.Errorf("failed to parse chain config for chain ID %d: %w", chainID, err)
}
return genesis.Config, nil
}

func mustLoadChainConfig(name string) *params.ChainConfig {
Expand Down
29 changes: 29 additions & 0 deletions op-program/chainconfig/chaincfg_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package chainconfig

import (
"testing"

"github.com/ethereum-optimism/optimism/op-program/chainconfig/test"
"github.com/stretchr/testify/require"
)

// TestGetCustomRollupConfig tests loading the custom rollup configs from test embed FS.
func TestGetCustomRollupConfig(t *testing.T) {
config, err := rollupConfigByChainID(901, test.TestCustomChainConfigFS)
require.NoError(t, err)
require.Equal(t, config.L1ChainID.Uint64(), uint64(900))
require.Equal(t, config.L2ChainID.Uint64(), uint64(901))

_, err = rollupConfigByChainID(900, test.TestCustomChainConfigFS)
require.Error(t, err)
}

// TestGetCustomChainConfig tests loading the custom chain configs from test embed FS.
func TestGetCustomChainConfig(t *testing.T) {
config, err := chainConfigByChainID(901, test.TestCustomChainConfigFS)
require.NoError(t, err)
require.Equal(t, config.ChainID.Uint64(), uint64(901))

_, err = chainConfigByChainID(900, test.TestCustomChainConfigFS)
require.Error(t, err)
}
1 change: 1 addition & 0 deletions op-program/chainconfig/configs/placeholder.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Loading

0 comments on commit efad673

Please sign in to comment.