Commit a9dcc0b1 authored by OptimismBot's avatar OptimismBot Committed by GitHub

Merge pull request #6452 from ethereum-optimism/inphi/op-program-chain-id

op-program: Add L2 Chain ID to client boot
parents 20f11766 9e7ec4dd
package config
package chainconfig
import (
"fmt"
"math/big"
"strconv"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum/go-ethereum/params"
)
......@@ -97,3 +101,24 @@ var L2ChainConfigsByName = map[string]*params.ChainConfig{
"sepolia": OPSepoliaChainConfig,
"mainnet": OPMainnetChainConfig,
}
func RollupConfigByChainID(chainID uint64) (*rollup.Config, error) {
network := chaincfg.L2ChainIDToNetworkName[strconv.FormatUint(chainID, 10)]
if network == "" {
return nil, fmt.Errorf("unknown chain ID: %d", chainID)
}
config, ok := chaincfg.NetworksByName[network]
if !ok {
return nil, fmt.Errorf("unknown network %s for chain ID %d", network, chainID)
}
return &config, nil
}
func ChainConfigByChainID(chainID uint64) (*params.ChainConfig, error) {
network := chaincfg.L2ChainIDToNetworkName[strconv.FormatUint(chainID, 10)]
chainConfig, ok := L2ChainConfigsByName[network]
if !ok {
return nil, fmt.Errorf("unknown network %s for chain ID %d", network, chainID)
}
return chainConfig, nil
}
......@@ -3,9 +3,11 @@ package client
import (
"encoding/binary"
"encoding/json"
"math"
"github.com/ethereum-optimism/optimism/op-node/rollup"
preimage "github.com/ethereum-optimism/optimism/op-preimage"
"github.com/ethereum-optimism/optimism/op-program/chainconfig"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/params"
)
......@@ -15,17 +17,25 @@ const (
L2OutputRootLocalIndex
L2ClaimLocalIndex
L2ClaimBlockNumberLocalIndex
L2ChainIDLocalIndex
// These local keys are only used for custom chains
L2ChainConfigLocalIndex
RollupConfigLocalIndex
)
// CustomChainIDIndicator is used to detect when the program should load custom chain configuration
const CustomChainIDIndicator = uint64(math.MaxUint64)
type BootInfo struct {
L1Head common.Hash
L2OutputRoot common.Hash
L2Claim common.Hash
L2ClaimBlockNumber uint64
L2ChainConfig *params.ChainConfig
RollupConfig *rollup.Config
L2ChainID uint64
L2ChainConfig *params.ChainConfig
RollupConfig *rollup.Config
}
type oracleClient interface {
......@@ -45,15 +55,31 @@ func (br *BootstrapClient) BootInfo() *BootInfo {
l2OutputRoot := common.BytesToHash(br.r.Get(L2OutputRootLocalIndex))
l2Claim := common.BytesToHash(br.r.Get(L2ClaimLocalIndex))
l2ClaimBlockNumber := binary.BigEndian.Uint64(br.r.Get(L2ClaimBlockNumberLocalIndex))
l2ChainConfig := new(params.ChainConfig)
err := json.Unmarshal(br.r.Get(L2ChainConfigLocalIndex), &l2ChainConfig)
if err != nil {
panic("failed to bootstrap l2ChainConfig")
}
rollupConfig := new(rollup.Config)
err = json.Unmarshal(br.r.Get(RollupConfigLocalIndex), rollupConfig)
if err != nil {
panic("failed to bootstrap rollup config")
l2ChainID := binary.BigEndian.Uint64(br.r.Get(L2ChainIDLocalIndex))
var l2ChainConfig *params.ChainConfig
var rollupConfig *rollup.Config
if l2ChainID == CustomChainIDIndicator {
l2ChainConfig = new(params.ChainConfig)
err := json.Unmarshal(br.r.Get(L2ChainConfigLocalIndex), &l2ChainConfig)
if err != nil {
panic("failed to bootstrap l2ChainConfig")
}
rollupConfig = new(rollup.Config)
err = json.Unmarshal(br.r.Get(RollupConfigLocalIndex), rollupConfig)
if err != nil {
panic("failed to bootstrap rollup config")
}
} else {
var err error
rollupConfig, err = chainconfig.RollupConfigByChainID(l2ChainID)
if err != nil {
panic(err)
}
l2ChainConfig, err = chainconfig.ChainConfigByChainID(l2ChainID)
if err != nil {
panic(err)
}
}
return &BootInfo{
......@@ -61,6 +87,7 @@ func (br *BootstrapClient) BootInfo() *BootInfo {
L2OutputRoot: l2OutputRoot,
L2Claim: l2Claim,
L2ClaimBlockNumber: l2ClaimBlockNumber,
L2ChainID: l2ChainID,
L2ChainConfig: l2ChainConfig,
RollupConfig: rollupConfig,
}
......
......@@ -3,12 +3,13 @@ package client
import (
"encoding/binary"
"encoding/json"
"fmt"
"testing"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
preimage "github.com/ethereum-optimism/optimism/op-preimage"
"github.com/ethereum-optimism/optimism/op-program/chainconfig"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/params"
"github.com/stretchr/testify/require"
)
......@@ -18,16 +19,46 @@ func TestBootstrapClient(t *testing.T) {
L2OutputRoot: common.HexToHash("0x2222"),
L2Claim: common.HexToHash("0x3333"),
L2ClaimBlockNumber: 1,
L2ChainConfig: params.GoerliChainConfig,
L2ChainID: chaincfg.Goerli.L2ChainID.Uint64(),
L2ChainConfig: chainconfig.OPGoerliChainConfig,
RollupConfig: &chaincfg.Goerli,
}
mockOracle := &mockBoostrapOracle{bootInfo}
mockOracle := &mockBoostrapOracle{bootInfo, false}
readBootInfo := NewBootstrapClient(mockOracle).BootInfo()
require.EqualValues(t, bootInfo, readBootInfo)
}
func TestBootstrapClient_CustomChain(t *testing.T) {
bootInfo := &BootInfo{
L1Head: common.HexToHash("0x1111"),
L2OutputRoot: common.HexToHash("0x2222"),
L2Claim: common.HexToHash("0x3333"),
L2ClaimBlockNumber: 1,
L2ChainID: CustomChainIDIndicator,
L2ChainConfig: chainconfig.OPGoerliChainConfig,
RollupConfig: &chaincfg.Goerli,
}
mockOracle := &mockBoostrapOracle{bootInfo, true}
readBootInfo := NewBootstrapClient(mockOracle).BootInfo()
require.EqualValues(t, bootInfo, readBootInfo)
}
func TestBootstrapClient_UnknownChainPanics(t *testing.T) {
bootInfo := &BootInfo{
L1Head: common.HexToHash("0x1111"),
L2OutputRoot: common.HexToHash("0x2222"),
L2Claim: common.HexToHash("0x3333"),
L2ClaimBlockNumber: 1,
L2ChainID: uint64(0xdead),
}
mockOracle := &mockBoostrapOracle{bootInfo, false}
client := NewBootstrapClient(mockOracle)
require.Panics(t, func() { client.BootInfo() })
}
type mockBoostrapOracle struct {
b *BootInfo
b *BootInfo
custom bool
}
func (o *mockBoostrapOracle) Get(key preimage.Key) []byte {
......@@ -40,10 +71,18 @@ func (o *mockBoostrapOracle) Get(key preimage.Key) []byte {
return o.b.L2Claim[:]
case L2ClaimBlockNumberLocalIndex.PreimageKey():
return binary.BigEndian.AppendUint64(nil, o.b.L2ClaimBlockNumber)
case L2ChainIDLocalIndex.PreimageKey():
return binary.BigEndian.AppendUint64(nil, o.b.L2ChainID)
case L2ChainConfigLocalIndex.PreimageKey():
if !o.custom {
panic(fmt.Sprintf("unexpected oracle request for preimage key %x", key.PreimageKey()))
}
b, _ := json.Marshal(o.b.L2ChainConfig)
return b
case RollupConfigLocalIndex.PreimageKey():
if !o.custom {
panic(fmt.Sprintf("unexpected oracle request for preimage key %x", key.PreimageKey()))
}
b, _ := json.Marshal(o.b.RollupConfig)
return b
default:
......
......@@ -8,6 +8,7 @@ import (
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum-optimism/optimism/op-program/chainconfig"
"github.com/ethereum-optimism/optimism/op-program/host/config"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
......@@ -46,7 +47,7 @@ func TestDefaultCLIOptionsMatchDefaultConfig(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs())
defaultCfg := config.NewConfig(
&chaincfg.Goerli,
config.OPGoerliChainConfig,
chainconfig.OPGoerliChainConfig,
common.HexToHash(l1HeadValue),
common.HexToHash(l2HeadValue),
common.HexToHash(l2OutputRoot),
......@@ -114,7 +115,7 @@ func TestL2Genesis(t *testing.T) {
t.Run("NotRequiredForGoerli", func(t *testing.T) {
cfg := configForArgs(t, replaceRequiredArg("--network", "goerli"))
require.Equal(t, config.OPGoerliChainConfig, cfg.L2ChainConfig)
require.Equal(t, chainconfig.OPGoerliChainConfig, cfg.L2ChainConfig)
})
}
......
......@@ -9,6 +9,7 @@ import (
opnode "github.com/ethereum-optimism/optimism/op-node"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum-optimism/optimism/op-program/chainconfig"
"github.com/ethereum-optimism/optimism/op-program/host/flags"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
......@@ -156,7 +157,7 @@ func NewConfigFromCLI(log log.Logger, ctx *cli.Context) (*Config, error) {
var l2ChainConfig *params.ChainConfig
if l2GenesisPath == "" {
networkName := ctx.String(flags.Network.Name)
l2ChainConfig = L2ChainConfigsByName[networkName]
l2ChainConfig = chainconfig.L2ChainConfigsByName[networkName]
if l2ChainConfig == nil {
return nil, fmt.Errorf("flag %s is required for network %s", flags.L2GenesisPath.Name, networkName)
}
......
......@@ -9,6 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/testlog"
preimage "github.com/ethereum-optimism/optimism/op-preimage"
"github.com/ethereum-optimism/optimism/op-program/chainconfig"
"github.com/ethereum-optimism/optimism/op-program/client"
"github.com/ethereum-optimism/optimism/op-program/client/l1"
"github.com/ethereum-optimism/optimism/op-program/host/config"
......@@ -24,7 +25,7 @@ func TestServerMode(t *testing.T) {
l1Head := common.Hash{0x11}
l2OutputRoot := common.Hash{0x33}
cfg := config.NewConfig(&chaincfg.Goerli, config.OPGoerliChainConfig, l1Head, common.Hash{0x22}, l2OutputRoot, common.Hash{0x44}, 1000)
cfg := config.NewConfig(&chaincfg.Goerli, chainconfig.OPGoerliChainConfig, l1Head, common.Hash{0x22}, l2OutputRoot, common.Hash{0x44}, 1000)
cfg.DataDir = dir
cfg.ServerMode = true
......
......@@ -22,6 +22,7 @@ var (
l2OutputRootKey = client.L2OutputRootLocalIndex.PreimageKey()
l2ClaimKey = client.L2ClaimLocalIndex.PreimageKey()
l2ClaimBlockNumberKey = client.L2ClaimBlockNumberLocalIndex.PreimageKey()
l2ChainIDKey = client.L2ChainIDLocalIndex.PreimageKey()
l2ChainConfigKey = client.L2ChainConfigLocalIndex.PreimageKey()
rollupKey = client.RollupConfigLocalIndex.PreimageKey()
)
......@@ -36,6 +37,8 @@ func (s *LocalPreimageSource) Get(key common.Hash) ([]byte, error) {
return s.config.L2Claim.Bytes(), nil
case l2ClaimBlockNumberKey:
return binary.BigEndian.AppendUint64(nil, s.config.L2ClaimBlockNumber), nil
case l2ChainIDKey:
return binary.BigEndian.AppendUint64(nil, client.CustomChainIDIndicator), nil
case l2ChainConfigKey:
return json.Marshal(s.config.L2ChainConfig)
case rollupKey:
......
......@@ -7,6 +7,7 @@ import (
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
preimage "github.com/ethereum-optimism/optimism/op-preimage"
"github.com/ethereum-optimism/optimism/op-program/client"
"github.com/ethereum-optimism/optimism/op-program/host/config"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/params"
......@@ -32,6 +33,7 @@ func TestLocalPreimageSource(t *testing.T) {
{"L2OutputRoot", l2OutputRootKey, cfg.L2OutputRoot.Bytes()},
{"L2Claim", l2ClaimKey, cfg.L2Claim.Bytes()},
{"L2ClaimBlockNumber", l2ClaimBlockNumberKey, binary.BigEndian.AppendUint64(nil, cfg.L2ClaimBlockNumber)},
{"L2ChainID", l2ChainIDKey, binary.BigEndian.AppendUint64(nil, client.CustomChainIDIndicator)},
{"Rollup", rollupKey, asJson(t, cfg.Rollup)},
{"ChainConfig", l2ChainConfigKey, asJson(t, cfg.L2ChainConfig)},
{"Unknown", preimage.LocalIndexKey(1000).PreimageKey(), 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