Commit 0b009e58 authored by Hamdi Allam's avatar Hamdi Allam

indexer.config

parent 11642bea
...@@ -144,60 +144,72 @@ type ServerConfig struct { ...@@ -144,60 +144,72 @@ type ServerConfig struct {
func LoadConfig(log log.Logger, path string) (Config, error) { func LoadConfig(log log.Logger, path string) (Config, error) {
log.Debug("loading config", "path", path) log.Debug("loading config", "path", path)
var conf Config var cfg Config
data, err := os.ReadFile(path) data, err := os.ReadFile(path)
if err != nil { if err != nil {
return conf, err return cfg, err
} }
data = []byte(os.ExpandEnv(string(data))) data = []byte(os.ExpandEnv(string(data)))
log.Debug("parsed config file", "data", string(data)) log.Debug("parsed config file", "data", string(data))
if _, err := toml.Decode(string(data), &conf); err != nil {
log.Info("failed to decode config file", "err", err) if _, err := toml.Decode(string(data), &cfg); err != nil {
return conf, err log.Error("failed to decode config file", "err", err)
return cfg, err
} }
if conf.Chain.Preset == DEVNET_L2_CHAIN_ID { if cfg.Chain.Preset == DevnetPresetId {
preset, err := GetDevnetPreset() preset, err := DevnetPreset()
if err != nil { if err != nil {
return conf, err return cfg, err
} }
conf.Chain = preset.ChainConfig
} else if conf.Chain.Preset != 0 { log.Info("loaded local devnet preset")
preset, ok := Presets[conf.Chain.Preset] cfg.Chain = preset.ChainConfig
} else if cfg.Chain.Preset != 0 {
preset, ok := Presets[cfg.Chain.Preset]
if !ok { if !ok {
return conf, fmt.Errorf("unknown preset: %d", conf.Chain.Preset) return cfg, fmt.Errorf("unknown preset: %d", cfg.Chain.Preset)
} }
log.Info("detected preset", "preset", conf.Chain.Preset, "name", preset.Name)
log.Info("setting L1 information from preset") log.Info("detected preset", "preset", cfg.Chain.Preset, "name", preset.Name)
conf.Chain = preset.ChainConfig cfg.Chain = preset.ChainConfig
} }
// Setup L2Contracts from predeploys // Setup L2Contracts from predeploys
conf.Chain.L2Contracts = L2ContractsFromPredeploys() cfg.Chain.L2Contracts = L2ContractsFromPredeploys()
// Deserialize the config file again when a preset is configured such that
// precedence is given to the config file vs the preset
if cfg.Chain.Preset > 0 {
if _, err := toml.Decode(string(data), &cfg); err != nil {
log.Error("failed to decode config file", "err", err)
return cfg, err
}
}
// Setup defaults for some unset options // Defaults for any unset options
if conf.Chain.L1PollingInterval == 0 { if cfg.Chain.L1PollingInterval == 0 {
log.Info("setting default L1 polling interval", "interval", defaultLoopInterval) log.Info("setting default L1 polling interval", "interval", defaultLoopInterval)
conf.Chain.L1PollingInterval = defaultLoopInterval cfg.Chain.L1PollingInterval = defaultLoopInterval
} }
if conf.Chain.L2PollingInterval == 0 { if cfg.Chain.L2PollingInterval == 0 {
log.Info("setting default L2 polling interval", "interval", defaultLoopInterval) log.Info("setting default L2 polling interval", "interval", defaultLoopInterval)
conf.Chain.L2PollingInterval = defaultLoopInterval cfg.Chain.L2PollingInterval = defaultLoopInterval
} }
if conf.Chain.L1HeaderBufferSize == 0 { if cfg.Chain.L1HeaderBufferSize == 0 {
log.Info("setting default L1 header buffer", "size", defaultHeaderBufferSize) log.Info("setting default L1 header buffer", "size", defaultHeaderBufferSize)
conf.Chain.L1HeaderBufferSize = defaultHeaderBufferSize cfg.Chain.L1HeaderBufferSize = defaultHeaderBufferSize
} }
if conf.Chain.L2HeaderBufferSize == 0 { if cfg.Chain.L2HeaderBufferSize == 0 {
log.Info("setting default L2 header buffer", "size", defaultHeaderBufferSize) log.Info("setting default L2 header buffer", "size", defaultHeaderBufferSize)
conf.Chain.L2HeaderBufferSize = defaultHeaderBufferSize cfg.Chain.L2HeaderBufferSize = defaultHeaderBufferSize
} }
log.Info("loaded config") log.Info("loaded config")
return conf, nil return cfg, nil
} }
...@@ -141,6 +141,8 @@ func TestLoadConfigWithUnknownPreset(t *testing.T) { ...@@ -141,6 +141,8 @@ func TestLoadConfigWithUnknownPreset(t *testing.T) {
logger := testlog.Logger(t, log.LvlInfo) logger := testlog.Logger(t, log.LvlInfo)
conf, err := LoadConfig(logger, tmpfile.Name()) conf, err := LoadConfig(logger, tmpfile.Name())
require.Error(t, err)
var faultyPreset = 1234567890 var faultyPreset = 1234567890
require.Equal(t, conf.Chain.Preset, faultyPreset) require.Equal(t, conf.Chain.Preset, faultyPreset)
require.Error(t, err) require.Error(t, err)
...@@ -170,10 +172,87 @@ func TestLoadConfigPollingValues(t *testing.T) { ...@@ -170,10 +172,87 @@ func TestLoadConfigPollingValues(t *testing.T) {
logger := testlog.Logger(t, log.LvlInfo) logger := testlog.Logger(t, log.LvlInfo)
conf, err := LoadConfig(logger, tmpfile.Name()) conf, err := LoadConfig(logger, tmpfile.Name())
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, conf.Chain.L1PollingInterval, uint(1000)) require.Equal(t, conf.Chain.L1PollingInterval, uint(1000))
require.Equal(t, conf.Chain.L2PollingInterval, uint(1005)) require.Equal(t, conf.Chain.L2PollingInterval, uint(1005))
require.Equal(t, conf.Chain.L1HeaderBufferSize, uint(100)) require.Equal(t, conf.Chain.L1HeaderBufferSize, uint(100))
require.Equal(t, conf.Chain.L2HeaderBufferSize, uint(105)) require.Equal(t, conf.Chain.L2HeaderBufferSize, uint(105))
} }
func TestLoadedConfigPresetPrecendence(t *testing.T) {
tmpfile, err := os.CreateTemp("", "test_bad_preset.toml")
require.NoError(t, err)
defer os.Remove(tmpfile.Name())
defer tmpfile.Close()
testData := `
[chain]
preset = 10 # Optimism Mainnet
# confirmation depths are explicitly set
l1-confirmation-depth = 50
l2-confirmation-depth = 100
# override a contract address
[chain.l1-contracts]
optimism-portal = "0x0000000000000000000000000000000000000001"
[rpcs]
l1-rpc = "https://l1.example.com"
l2-rpc = "https://l2.example.com"
`
data := []byte(testData)
err = os.WriteFile(tmpfile.Name(), data, 0644)
require.NoError(t, err)
defer os.Remove(tmpfile.Name())
err = tmpfile.Close()
require.NoError(t, err)
logger := testlog.Logger(t, log.LvlInfo)
conf, err := LoadConfig(logger, tmpfile.Name())
require.NoError(t, err)
// confirmation depths
require.Equal(t, uint(50), conf.Chain.L1ConfirmationDepth)
require.Equal(t, uint(100), conf.Chain.L2ConfirmationDepth)
// overriden preset conifg
require.Equal(t, common.HexToAddress("0x0000000000000000000000000000000000000001"), conf.Chain.L1Contracts.OptimismPortalProxy)
}
func TestLocalDevnet(t *testing.T) {
tmpfile, err := os.CreateTemp("", "test_user_values.toml")
require.NoError(t, err)
defer os.Remove(tmpfile.Name())
defer tmpfile.Close()
testData := `
[chain]
preset = 901
[rpcs]
l1-rpc = "https://l1.example.com"
l2-rpc = "https://l2.example.com"
`
data := []byte(testData)
err = os.WriteFile(tmpfile.Name(), data, 0644)
require.NoError(t, err)
defer os.Remove(tmpfile.Name())
err = tmpfile.Close()
require.NoError(t, err)
logger := testlog.Logger(t, log.LvlInfo)
conf, err := LoadConfig(logger, tmpfile.Name())
require.NoError(t, err)
devnetPreset, err := DevnetPreset()
require.NoError(t, err)
require.Equal(t, devnetPreset.ChainConfig.L1Contracts, conf.Chain.L1Contracts)
}
...@@ -3,38 +3,64 @@ package config ...@@ -3,38 +3,64 @@ package config
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"io/fs" "io/fs"
"os" "os"
"path/filepath"
) )
var ( var DevnetPresetId = 901
filePath = "../.devnet/addresses.json"
DEVNET_L2_CHAIN_ID = 901
)
func GetDevnetPreset() (*Preset, error) { func DevnetPreset() (*Preset, error) {
if _, err := os.Stat(filePath); errors.Is(err, fs.ErrNotExist) { cwd, err := os.Getwd()
if err != nil {
return nil, err return nil, err
} }
content, err := os.ReadFile(filePath) root, err := findMonorepoRoot(cwd)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var l1Contracts L1Contracts devnetFilepath := filepath.Join(root, ".devnet", "addresses.json")
if err := json.Unmarshal(content, &l1Contracts); err != nil { if _, err := os.Stat(devnetFilepath); errors.Is(err, fs.ErrNotExist) {
return nil, err return nil, err
} }
content, err := os.ReadFile(devnetFilepath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var l1Contracts L1Contracts
if err := json.Unmarshal(content, &l1Contracts); err != nil {
return nil, err
}
return &Preset{ return &Preset{
Name: "devnet", Name: "Local Devnet",
ChainConfig: ChainConfig{ ChainConfig: ChainConfig{Preset: DevnetPresetId, L1Contracts: l1Contracts},
Preset: DEVNET_L2_CHAIN_ID,
L1Contracts: l1Contracts,
},
}, nil }, nil
} }
// findMonorepoRoot will recursively search upwards for a go.mod file.
// This depends on the structure of the monorepo having a go.mod file at the root.
func findMonorepoRoot(startDir string) (string, error) {
dir, err := filepath.Abs(startDir)
if err != nil {
return "", err
}
for {
modulePath := filepath.Join(dir, "go.mod")
if _, err := os.Stat(modulePath); err == nil {
return dir, nil
}
parentDir := filepath.Dir(dir)
// Check if we reached the filesystem root
if parentDir == dir {
break
}
dir = parentDir
}
return "", fmt.Errorf("monorepo root not found")
}
...@@ -57,6 +57,22 @@ var Presets = map[int]Preset{ ...@@ -57,6 +57,22 @@ var Presets = map[int]Preset{
L2BedrockStartingHeight: 4061224, L2BedrockStartingHeight: 4061224,
}, },
}, },
11155420: {
Name: "Optimism Sepolia",
ChainConfig: ChainConfig{
Preset: 11155420,
L1Contracts: L1Contracts{
AddressManager: common.HexToAddress("0x9bFE9c5609311DF1c011c47642253B78a4f33F4B"),
SystemConfigProxy: common.HexToAddress("0x034edD2A225f7f429A63E0f1D2084B9E0A93b538"),
OptimismPortalProxy: common.HexToAddress("0x16Fc5058F25648194471939df75CF27A2fdC48BC"),
L2OutputOracleProxy: common.HexToAddress("0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F"),
L1CrossDomainMessengerProxy: common.HexToAddress("0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef"),
L1StandardBridgeProxy: common.HexToAddress("0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1"),
L1ERC721BridgeProxy: common.HexToAddress("0xd83e03D576d23C9AEab8cC44Fa98d058D2176D1f"),
},
L1StartingHeight: 4071408,
},
},
8453: { 8453: {
Name: "Base", Name: "Base",
ChainConfig: ChainConfig{ ChainConfig: ChainConfig{
...@@ -137,22 +153,6 @@ var Presets = map[int]Preset{ ...@@ -137,22 +153,6 @@ var Presets = map[int]Preset{
L1StartingHeight: 8942381, L1StartingHeight: 8942381,
}, },
}, },
11155420: {
Name: "OP Sepolia",
ChainConfig: ChainConfig{
Preset: 11155420,
L1Contracts: L1Contracts{
AddressManager: common.HexToAddress("0x9bFE9c5609311DF1c011c47642253B78a4f33F4B"),
SystemConfigProxy: common.HexToAddress("0x034edD2A225f7f429A63E0f1D2084B9E0A93b538"),
OptimismPortalProxy: common.HexToAddress("0x16Fc5058F25648194471939df75CF27A2fdC48BC"),
L2OutputOracleProxy: common.HexToAddress("0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F"),
L1CrossDomainMessengerProxy: common.HexToAddress("0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef"),
L1StandardBridgeProxy: common.HexToAddress("0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1"),
L1ERC721BridgeProxy: common.HexToAddress("0xd83e03D576d23C9AEab8cC44Fa98d058D2176D1f"),
},
L1StartingHeight: 4071408,
},
},
424: { 424: {
Name: "PGN", Name: "PGN",
ChainConfig: ChainConfig{ ChainConfig: ChainConfig{
......
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