Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 27 additions & 12 deletions beacon/params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"crypto/sha256"
"fmt"
"math"
"math/big"
"os"
"slices"
"sort"
Expand Down Expand Up @@ -90,12 +91,8 @@ func (c *ChainConfig) AddFork(name string, epoch uint64, version []byte) *ChainC

// LoadForks parses the beacon chain configuration file (config.yaml) and extracts
// the list of forks.
func (c *ChainConfig) LoadForks(path string) error {
file, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("failed to read beacon chain config file: %v", err)
}
config := make(map[string]string)
func (c *ChainConfig) LoadForks(file []byte) error {
config := make(map[string]any)
if err := yaml.Unmarshal(file, &config); err != nil {
return fmt.Errorf("failed to parse beacon chain config file: %v", err)
}
Expand All @@ -108,18 +105,36 @@ func (c *ChainConfig) LoadForks(path string) error {
for key, value := range config {
if strings.HasSuffix(key, "_FORK_VERSION") {
name := key[:len(key)-len("_FORK_VERSION")]
if v, err := hexutil.Decode(value); err == nil {
switch version := value.(type) {
case int:
versions[name] = new(big.Int).SetUint64(uint64(version)).FillBytes(make([]byte, 4))
case uint64:
versions[name] = new(big.Int).SetUint64(version).FillBytes(make([]byte, 4))
case string:
v, err := hexutil.Decode(version)
if err != nil {
return fmt.Errorf("failed to decode hex fork id %q in beacon chain config file: %v", version, err)
}
versions[name] = v
} else {
return fmt.Errorf("failed to decode hex fork id %q in beacon chain config file: %v", value, err)
default:
return fmt.Errorf("invalid fork version %q in beacon chain config file", version)
}
}
if strings.HasSuffix(key, "_FORK_EPOCH") {
name := key[:len(key)-len("_FORK_EPOCH")]
if v, err := strconv.ParseUint(value, 10, 64); err == nil {
switch epoch := value.(type) {
case int:
epochs[name] = uint64(epoch)
case uint64:
epochs[name] = epoch
case string:
v, err := strconv.ParseUint(epoch, 10, 64)
if err != nil {
return fmt.Errorf("failed to parse epoch number %q in beacon chain config file: %v", epoch, err)
}
epochs[name] = v
} else {
return fmt.Errorf("failed to parse epoch number %q in beacon chain config file: %v", value, err)
default:
return fmt.Errorf("invalid fork epoch %q in beacon chain config file", epoch)
}
}
}
Expand Down
34 changes: 34 additions & 0 deletions beacon/params/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package params

import (
"bytes"
"testing"
)

func TestChainConfig_LoadForks(t *testing.T) {
const config = `
GENESIS_FORK_VERSION: 0x00000000

ALTAIR_FORK_VERSION: 0x00000001
ALTAIR_FORK_EPOCH: 1

EIP7928_FORK_VERSION: 0xb0000038
EIP7928_FORK_EPOCH: 18446744073709551615

BLOB_SCHEDULE: []
`
c := &ChainConfig{}
err := c.LoadForks([]byte(config))
if err != nil {
t.Fatal(err)
}

for _, fork := range c.Forks {
if fork.Name == "GENESIS" && (fork.Epoch != 0) {
t.Errorf("unexpected genesis fork epoch %d", fork.Epoch)
}
if fork.Name == "ALTAIR" && (fork.Epoch != 1 || !bytes.Equal(fork.Version, []byte{0, 0, 0, 1})) {
t.Errorf("unexpected altair fork epoch %d version %x", fork.Epoch, fork.Version)
}
}
}
12 changes: 8 additions & 4 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1902,11 +1902,15 @@ func MakeBeaconLightConfig(ctx *cli.Context) bparams.ClientConfig {
} else {
Fatalf("Could not parse --%s: %v", BeaconGenesisRootFlag.Name, err)
}
configFile := ctx.String(BeaconConfigFlag.Name)
if err := config.ChainConfig.LoadForks(configFile); err != nil {
Fatalf("Could not load beacon chain config '%s': %v", configFile, err)
configPath := ctx.String(BeaconConfigFlag.Name)
file, err := os.ReadFile(configPath)
if err != nil {
Fatalf("failed to read beacon chain config file '%s': %v", configPath, err)
}
if err := config.ChainConfig.LoadForks(file); err != nil {
Fatalf("Could not load beacon chain config '%s': %v", configPath, err)
}
log.Info("Using custom beacon chain config", "file", configFile)
log.Info("Using custom beacon chain config", "file", configPath)
} else {
if ctx.IsSet(BeaconGenesisRootFlag.Name) {
Fatalf("Genesis root is specified but custom beacon chain config is missing")
Expand Down
Loading