beacon/blsync: remove cli dependencies (#30720)
This PR moves chain config related code (config file processing, fork logic, network defaults) from `beacon/types` and `beacon/blsync` into `beacon/params` while the command line flag logic of the chain config is moved into `cmd/utils`, thereby removing the cli dependencies from package `beacon` and its sub-packages.
This commit is contained in:
parent
d42d45046c
commit
7cbce8ed58
|
@ -17,25 +17,22 @@
|
||||||
package blsync
|
package blsync
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/beacon/light"
|
"github.com/ethereum/go-ethereum/beacon/light"
|
||||||
"github.com/ethereum/go-ethereum/beacon/light/api"
|
"github.com/ethereum/go-ethereum/beacon/light/api"
|
||||||
"github.com/ethereum/go-ethereum/beacon/light/request"
|
"github.com/ethereum/go-ethereum/beacon/light/request"
|
||||||
"github.com/ethereum/go-ethereum/beacon/light/sync"
|
"github.com/ethereum/go-ethereum/beacon/light/sync"
|
||||||
|
"github.com/ethereum/go-ethereum/beacon/params"
|
||||||
"github.com/ethereum/go-ethereum/beacon/types"
|
"github.com/ethereum/go-ethereum/beacon/types"
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
|
||||||
"github.com/ethereum/go-ethereum/common/mclock"
|
"github.com/ethereum/go-ethereum/common/mclock"
|
||||||
"github.com/ethereum/go-ethereum/ethdb/memorydb"
|
"github.com/ethereum/go-ethereum/ethdb/memorydb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/urfave/cli/v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
urls []string
|
urls []string
|
||||||
customHeader map[string]string
|
customHeader map[string]string
|
||||||
chainConfig *lightClientConfig
|
config *params.ClientConfig
|
||||||
scheduler *request.Scheduler
|
scheduler *request.Scheduler
|
||||||
blockSync *beaconBlockSync
|
blockSync *beaconBlockSync
|
||||||
engineRPC *rpc.Client
|
engineRPC *rpc.Client
|
||||||
|
@ -44,34 +41,18 @@ type Client struct {
|
||||||
engineClient *engineClient
|
engineClient *engineClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(ctx *cli.Context) *Client {
|
func NewClient(config params.ClientConfig) *Client {
|
||||||
if !ctx.IsSet(utils.BeaconApiFlag.Name) {
|
|
||||||
utils.Fatalf("Beacon node light client API URL not specified")
|
|
||||||
}
|
|
||||||
var (
|
|
||||||
chainConfig = makeChainConfig(ctx)
|
|
||||||
customHeader = make(map[string]string)
|
|
||||||
)
|
|
||||||
for _, s := range ctx.StringSlice(utils.BeaconApiHeaderFlag.Name) {
|
|
||||||
kv := strings.Split(s, ":")
|
|
||||||
if len(kv) != 2 {
|
|
||||||
utils.Fatalf("Invalid custom API header entry: %s", s)
|
|
||||||
}
|
|
||||||
customHeader[strings.TrimSpace(kv[0])] = strings.TrimSpace(kv[1])
|
|
||||||
}
|
|
||||||
|
|
||||||
// create data structures
|
// create data structures
|
||||||
var (
|
var (
|
||||||
db = memorydb.New()
|
db = memorydb.New()
|
||||||
threshold = ctx.Int(utils.BeaconThresholdFlag.Name)
|
committeeChain = light.NewCommitteeChain(db, &config.ChainConfig, config.Threshold, !config.NoFilter)
|
||||||
committeeChain = light.NewCommitteeChain(db, chainConfig.ChainConfig, threshold, !ctx.Bool(utils.BeaconNoFilterFlag.Name))
|
headTracker = light.NewHeadTracker(committeeChain, config.Threshold)
|
||||||
headTracker = light.NewHeadTracker(committeeChain, threshold)
|
|
||||||
)
|
)
|
||||||
headSync := sync.NewHeadSync(headTracker, committeeChain)
|
headSync := sync.NewHeadSync(headTracker, committeeChain)
|
||||||
|
|
||||||
// set up scheduler and sync modules
|
// set up scheduler and sync modules
|
||||||
scheduler := request.NewScheduler()
|
scheduler := request.NewScheduler()
|
||||||
checkpointInit := sync.NewCheckpointInit(committeeChain, chainConfig.Checkpoint)
|
checkpointInit := sync.NewCheckpointInit(committeeChain, config.Checkpoint)
|
||||||
forwardSync := sync.NewForwardUpdateSync(committeeChain)
|
forwardSync := sync.NewForwardUpdateSync(committeeChain)
|
||||||
beaconBlockSync := newBeaconBlockSync(headTracker)
|
beaconBlockSync := newBeaconBlockSync(headTracker)
|
||||||
scheduler.RegisterTarget(headTracker)
|
scheduler.RegisterTarget(headTracker)
|
||||||
|
@ -83,9 +64,9 @@ func NewClient(ctx *cli.Context) *Client {
|
||||||
|
|
||||||
return &Client{
|
return &Client{
|
||||||
scheduler: scheduler,
|
scheduler: scheduler,
|
||||||
urls: ctx.StringSlice(utils.BeaconApiFlag.Name),
|
urls: config.Apis,
|
||||||
customHeader: customHeader,
|
customHeader: config.CustomHeader,
|
||||||
chainConfig: &chainConfig,
|
config: &config,
|
||||||
blockSync: beaconBlockSync,
|
blockSync: beaconBlockSync,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +78,7 @@ func (c *Client) SetEngineRPC(engine *rpc.Client) {
|
||||||
func (c *Client) Start() error {
|
func (c *Client) Start() error {
|
||||||
headCh := make(chan types.ChainHeadEvent, 16)
|
headCh := make(chan types.ChainHeadEvent, 16)
|
||||||
c.chainHeadSub = c.blockSync.SubscribeChainHead(headCh)
|
c.chainHeadSub = c.blockSync.SubscribeChainHead(headCh)
|
||||||
c.engineClient = startEngineClient(c.chainConfig, c.engineRPC, headCh)
|
c.engineClient = startEngineClient(c.config, c.engineRPC, headCh)
|
||||||
|
|
||||||
c.scheduler.Start()
|
c.scheduler.Start()
|
||||||
for _, url := range c.urls {
|
for _, url := range c.urls {
|
||||||
|
|
|
@ -1,129 +0,0 @@
|
||||||
// Copyright 2022 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package blsync
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/ethereum/go-ethereum/beacon/types"
|
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
||||||
"github.com/urfave/cli/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// lightClientConfig contains beacon light client configuration
|
|
||||||
type lightClientConfig struct {
|
|
||||||
*types.ChainConfig
|
|
||||||
Checkpoint common.Hash
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
MainnetConfig = lightClientConfig{
|
|
||||||
ChainConfig: (&types.ChainConfig{
|
|
||||||
GenesisValidatorsRoot: common.HexToHash("0x4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95"),
|
|
||||||
GenesisTime: 1606824023,
|
|
||||||
}).
|
|
||||||
AddFork("GENESIS", 0, []byte{0, 0, 0, 0}).
|
|
||||||
AddFork("ALTAIR", 74240, []byte{1, 0, 0, 0}).
|
|
||||||
AddFork("BELLATRIX", 144896, []byte{2, 0, 0, 0}).
|
|
||||||
AddFork("CAPELLA", 194048, []byte{3, 0, 0, 0}).
|
|
||||||
AddFork("DENEB", 269568, []byte{4, 0, 0, 0}),
|
|
||||||
Checkpoint: common.HexToHash("0x6509b691f4de4f7b083f2784938fd52f0e131675432b3fd85ea549af9aebd3d0"),
|
|
||||||
}
|
|
||||||
|
|
||||||
SepoliaConfig = lightClientConfig{
|
|
||||||
ChainConfig: (&types.ChainConfig{
|
|
||||||
GenesisValidatorsRoot: common.HexToHash("0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078"),
|
|
||||||
GenesisTime: 1655733600,
|
|
||||||
}).
|
|
||||||
AddFork("GENESIS", 0, []byte{144, 0, 0, 105}).
|
|
||||||
AddFork("ALTAIR", 50, []byte{144, 0, 0, 112}).
|
|
||||||
AddFork("BELLATRIX", 100, []byte{144, 0, 0, 113}).
|
|
||||||
AddFork("CAPELLA", 56832, []byte{144, 0, 0, 114}).
|
|
||||||
AddFork("DENEB", 132608, []byte{144, 0, 0, 115}),
|
|
||||||
Checkpoint: common.HexToHash("0x456e85f5608afab3465a0580bff8572255f6d97af0c5f939e3f7536b5edb2d3f"),
|
|
||||||
}
|
|
||||||
|
|
||||||
HoleskyConfig = lightClientConfig{
|
|
||||||
ChainConfig: (&types.ChainConfig{
|
|
||||||
GenesisValidatorsRoot: common.HexToHash("0x9143aa7c615a7f7115e2b6aac319c03529df8242ae705fba9df39b79c59fa8b1"),
|
|
||||||
GenesisTime: 1695902400,
|
|
||||||
}).
|
|
||||||
AddFork("GENESIS", 0, []byte{1, 1, 112, 0}).
|
|
||||||
AddFork("ALTAIR", 0, []byte{2, 1, 112, 0}).
|
|
||||||
AddFork("BELLATRIX", 0, []byte{3, 1, 112, 0}).
|
|
||||||
AddFork("CAPELLA", 256, []byte{4, 1, 112, 0}).
|
|
||||||
AddFork("DENEB", 29696, []byte{5, 1, 112, 0}),
|
|
||||||
Checkpoint: common.HexToHash("0x6456a1317f54d4b4f2cb5bc9d153b5af0988fe767ef0609f0236cf29030bcff7"),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func makeChainConfig(ctx *cli.Context) lightClientConfig {
|
|
||||||
var config lightClientConfig
|
|
||||||
customConfig := ctx.IsSet(utils.BeaconConfigFlag.Name)
|
|
||||||
utils.CheckExclusive(ctx, utils.MainnetFlag, utils.SepoliaFlag, utils.HoleskyFlag, utils.BeaconConfigFlag)
|
|
||||||
switch {
|
|
||||||
case ctx.Bool(utils.MainnetFlag.Name):
|
|
||||||
config = MainnetConfig
|
|
||||||
case ctx.Bool(utils.SepoliaFlag.Name):
|
|
||||||
config = SepoliaConfig
|
|
||||||
case ctx.Bool(utils.HoleskyFlag.Name):
|
|
||||||
config = HoleskyConfig
|
|
||||||
default:
|
|
||||||
if !customConfig {
|
|
||||||
config = MainnetConfig
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Genesis root and time should always be specified together with custom chain config
|
|
||||||
if customConfig {
|
|
||||||
if !ctx.IsSet(utils.BeaconGenesisRootFlag.Name) {
|
|
||||||
utils.Fatalf("Custom beacon chain config is specified but genesis root is missing")
|
|
||||||
}
|
|
||||||
if !ctx.IsSet(utils.BeaconGenesisTimeFlag.Name) {
|
|
||||||
utils.Fatalf("Custom beacon chain config is specified but genesis time is missing")
|
|
||||||
}
|
|
||||||
if !ctx.IsSet(utils.BeaconCheckpointFlag.Name) {
|
|
||||||
utils.Fatalf("Custom beacon chain config is specified but checkpoint is missing")
|
|
||||||
}
|
|
||||||
config.ChainConfig = &types.ChainConfig{
|
|
||||||
GenesisTime: ctx.Uint64(utils.BeaconGenesisTimeFlag.Name),
|
|
||||||
}
|
|
||||||
if c, err := hexutil.Decode(ctx.String(utils.BeaconGenesisRootFlag.Name)); err == nil && len(c) <= 32 {
|
|
||||||
copy(config.GenesisValidatorsRoot[:len(c)], c)
|
|
||||||
} else {
|
|
||||||
utils.Fatalf("Invalid hex string", "beacon.genesis.gvroot", ctx.String(utils.BeaconGenesisRootFlag.Name), "error", err)
|
|
||||||
}
|
|
||||||
if err := config.ChainConfig.LoadForks(ctx.String(utils.BeaconConfigFlag.Name)); err != nil {
|
|
||||||
utils.Fatalf("Could not load beacon chain config file", "file name", ctx.String(utils.BeaconConfigFlag.Name), "error", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ctx.IsSet(utils.BeaconGenesisRootFlag.Name) {
|
|
||||||
utils.Fatalf("Genesis root is specified but custom beacon chain config is missing")
|
|
||||||
}
|
|
||||||
if ctx.IsSet(utils.BeaconGenesisTimeFlag.Name) {
|
|
||||||
utils.Fatalf("Genesis time is specified but custom beacon chain config is missing")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Checkpoint is required with custom chain config and is optional with pre-defined config
|
|
||||||
if ctx.IsSet(utils.BeaconCheckpointFlag.Name) {
|
|
||||||
if c, err := hexutil.Decode(ctx.String(utils.BeaconCheckpointFlag.Name)); err == nil && len(c) <= 32 {
|
|
||||||
copy(config.Checkpoint[:len(c)], c)
|
|
||||||
} else {
|
|
||||||
utils.Fatalf("Invalid hex string", "beacon.checkpoint", ctx.String(utils.BeaconCheckpointFlag.Name), "error", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return config
|
|
||||||
}
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/beacon/engine"
|
"github.com/ethereum/go-ethereum/beacon/engine"
|
||||||
|
"github.com/ethereum/go-ethereum/beacon/params"
|
||||||
"github.com/ethereum/go-ethereum/beacon/types"
|
"github.com/ethereum/go-ethereum/beacon/types"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
ctypes "github.com/ethereum/go-ethereum/core/types"
|
ctypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
|
@ -31,14 +32,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type engineClient struct {
|
type engineClient struct {
|
||||||
config *lightClientConfig
|
config *params.ClientConfig
|
||||||
rpc *rpc.Client
|
rpc *rpc.Client
|
||||||
rootCtx context.Context
|
rootCtx context.Context
|
||||||
cancelRoot context.CancelFunc
|
cancelRoot context.CancelFunc
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
func startEngineClient(config *lightClientConfig, rpc *rpc.Client, headCh <-chan types.ChainHeadEvent) *engineClient {
|
func startEngineClient(config *params.ClientConfig, rpc *rpc.Client, headCh <-chan types.ChainHeadEvent) *engineClient {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
ec := &engineClient{
|
ec := &engineClient{
|
||||||
config: config,
|
config: config,
|
||||||
|
|
|
@ -76,24 +76,24 @@ type CommitteeChain struct {
|
||||||
unixNano func() int64 // system clock (simulated clock in tests)
|
unixNano func() int64 // system clock (simulated clock in tests)
|
||||||
sigVerifier committeeSigVerifier // BLS sig verifier (dummy verifier in tests)
|
sigVerifier committeeSigVerifier // BLS sig verifier (dummy verifier in tests)
|
||||||
|
|
||||||
config *types.ChainConfig
|
config *params.ChainConfig
|
||||||
minimumUpdateScore types.UpdateScore
|
minimumUpdateScore types.UpdateScore
|
||||||
enforceTime bool // enforceTime specifies whether the age of a signed header should be checked
|
enforceTime bool // enforceTime specifies whether the age of a signed header should be checked
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCommitteeChain creates a new CommitteeChain.
|
// NewCommitteeChain creates a new CommitteeChain.
|
||||||
func NewCommitteeChain(db ethdb.KeyValueStore, config *types.ChainConfig, signerThreshold int, enforceTime bool) *CommitteeChain {
|
func NewCommitteeChain(db ethdb.KeyValueStore, config *params.ChainConfig, signerThreshold int, enforceTime bool) *CommitteeChain {
|
||||||
return newCommitteeChain(db, config, signerThreshold, enforceTime, blsVerifier{}, &mclock.System{}, func() int64 { return time.Now().UnixNano() })
|
return newCommitteeChain(db, config, signerThreshold, enforceTime, blsVerifier{}, &mclock.System{}, func() int64 { return time.Now().UnixNano() })
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTestCommitteeChain creates a new CommitteeChain for testing.
|
// NewTestCommitteeChain creates a new CommitteeChain for testing.
|
||||||
func NewTestCommitteeChain(db ethdb.KeyValueStore, config *types.ChainConfig, signerThreshold int, enforceTime bool, clock *mclock.Simulated) *CommitteeChain {
|
func NewTestCommitteeChain(db ethdb.KeyValueStore, config *params.ChainConfig, signerThreshold int, enforceTime bool, clock *mclock.Simulated) *CommitteeChain {
|
||||||
return newCommitteeChain(db, config, signerThreshold, enforceTime, dummyVerifier{}, clock, func() int64 { return int64(clock.Now()) })
|
return newCommitteeChain(db, config, signerThreshold, enforceTime, dummyVerifier{}, clock, func() int64 { return int64(clock.Now()) })
|
||||||
}
|
}
|
||||||
|
|
||||||
// newCommitteeChain creates a new CommitteeChain with the option of replacing the
|
// newCommitteeChain creates a new CommitteeChain with the option of replacing the
|
||||||
// clock source and signature verification for testing purposes.
|
// clock source and signature verification for testing purposes.
|
||||||
func newCommitteeChain(db ethdb.KeyValueStore, config *types.ChainConfig, signerThreshold int, enforceTime bool, sigVerifier committeeSigVerifier, clock mclock.Clock, unixNano func() int64) *CommitteeChain {
|
func newCommitteeChain(db ethdb.KeyValueStore, config *params.ChainConfig, signerThreshold int, enforceTime bool, sigVerifier committeeSigVerifier, clock mclock.Clock, unixNano func() int64) *CommitteeChain {
|
||||||
s := &CommitteeChain{
|
s := &CommitteeChain{
|
||||||
committeeCache: lru.NewCache[uint64, syncCommittee](10),
|
committeeCache: lru.NewCache[uint64, syncCommittee](10),
|
||||||
db: db,
|
db: db,
|
||||||
|
@ -505,7 +505,7 @@ func (s *CommitteeChain) verifySignedHeader(head types.SignedHeader) (bool, time
|
||||||
if committee == nil {
|
if committee == nil {
|
||||||
return false, age, nil
|
return false, age, nil
|
||||||
}
|
}
|
||||||
if signingRoot, err := s.config.Forks.SigningRoot(head.Header); err == nil {
|
if signingRoot, err := s.config.Forks.SigningRoot(head.Header.Epoch(), head.Header.Hash()); err == nil {
|
||||||
return s.sigVerifier.verifySignature(committee, signingRoot, &head.Signature), age, nil
|
return s.sigVerifier.verifySignature(committee, signingRoot, &head.Signature), age, nil
|
||||||
}
|
}
|
||||||
return false, age, nil
|
return false, age, nil
|
||||||
|
|
|
@ -31,15 +31,15 @@ var (
|
||||||
testGenesis = newTestGenesis()
|
testGenesis = newTestGenesis()
|
||||||
testGenesis2 = newTestGenesis()
|
testGenesis2 = newTestGenesis()
|
||||||
|
|
||||||
tfBase = newTestForks(testGenesis, types.Forks{
|
tfBase = newTestForks(testGenesis, params.Forks{
|
||||||
&types.Fork{Epoch: 0, Version: []byte{0}},
|
¶ms.Fork{Epoch: 0, Version: []byte{0}},
|
||||||
})
|
})
|
||||||
tfAlternative = newTestForks(testGenesis, types.Forks{
|
tfAlternative = newTestForks(testGenesis, params.Forks{
|
||||||
&types.Fork{Epoch: 0, Version: []byte{0}},
|
¶ms.Fork{Epoch: 0, Version: []byte{0}},
|
||||||
&types.Fork{Epoch: 0x700, Version: []byte{1}},
|
¶ms.Fork{Epoch: 0x700, Version: []byte{1}},
|
||||||
})
|
})
|
||||||
tfAnotherGenesis = newTestForks(testGenesis2, types.Forks{
|
tfAnotherGenesis = newTestForks(testGenesis2, params.Forks{
|
||||||
&types.Fork{Epoch: 0, Version: []byte{0}},
|
¶ms.Fork{Epoch: 0, Version: []byte{0}},
|
||||||
})
|
})
|
||||||
|
|
||||||
tcBase = newTestCommitteeChain(nil, tfBase, true, 0, 10, 400, false)
|
tcBase = newTestCommitteeChain(nil, tfBase, true, 0, 10, 400, false)
|
||||||
|
@ -226,13 +226,13 @@ type committeeChainTest struct {
|
||||||
t *testing.T
|
t *testing.T
|
||||||
db *memorydb.Database
|
db *memorydb.Database
|
||||||
clock *mclock.Simulated
|
clock *mclock.Simulated
|
||||||
config types.ChainConfig
|
config params.ChainConfig
|
||||||
signerThreshold int
|
signerThreshold int
|
||||||
enforceTime bool
|
enforceTime bool
|
||||||
chain *CommitteeChain
|
chain *CommitteeChain
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCommitteeChainTest(t *testing.T, config types.ChainConfig, signerThreshold int, enforceTime bool) *committeeChainTest {
|
func newCommitteeChainTest(t *testing.T, config params.ChainConfig, signerThreshold int, enforceTime bool) *committeeChainTest {
|
||||||
c := &committeeChainTest{
|
c := &committeeChainTest{
|
||||||
t: t,
|
t: t,
|
||||||
db: memorydb.New(),
|
db: memorydb.New(),
|
||||||
|
@ -298,20 +298,20 @@ func (c *committeeChainTest) verifyRange(tc *testCommitteeChain, begin, end uint
|
||||||
c.verifySignedHeader(tc, float64(end)+1.5, false)
|
c.verifySignedHeader(tc, float64(end)+1.5, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestGenesis() types.ChainConfig {
|
func newTestGenesis() params.ChainConfig {
|
||||||
var config types.ChainConfig
|
var config params.ChainConfig
|
||||||
rand.Read(config.GenesisValidatorsRoot[:])
|
rand.Read(config.GenesisValidatorsRoot[:])
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestForks(config types.ChainConfig, forks types.Forks) types.ChainConfig {
|
func newTestForks(config params.ChainConfig, forks params.Forks) params.ChainConfig {
|
||||||
for _, fork := range forks {
|
for _, fork := range forks {
|
||||||
config.AddFork(fork.Name, fork.Epoch, fork.Version)
|
config.AddFork(fork.Name, fork.Epoch, fork.Version)
|
||||||
}
|
}
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestCommitteeChain(parent *testCommitteeChain, config types.ChainConfig, newCommittees bool, begin, end int, signerCount int, finalizedHeader bool) *testCommitteeChain {
|
func newTestCommitteeChain(parent *testCommitteeChain, config params.ChainConfig, newCommittees bool, begin, end int, signerCount int, finalizedHeader bool) *testCommitteeChain {
|
||||||
tc := &testCommitteeChain{
|
tc := &testCommitteeChain{
|
||||||
config: config,
|
config: config,
|
||||||
}
|
}
|
||||||
|
@ -337,7 +337,7 @@ type testPeriod struct {
|
||||||
|
|
||||||
type testCommitteeChain struct {
|
type testCommitteeChain struct {
|
||||||
periods []testPeriod
|
periods []testPeriod
|
||||||
config types.ChainConfig
|
config params.ChainConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tc *testCommitteeChain) fillCommittees(begin, end int) {
|
func (tc *testCommitteeChain) fillCommittees(begin, end int) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ func GenerateTestCommittee() *types.SerializedSyncCommittee {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateTestUpdate(config *types.ChainConfig, period uint64, committee, nextCommittee *types.SerializedSyncCommittee, signerCount int, finalizedHeader bool) *types.LightClientUpdate {
|
func GenerateTestUpdate(config *params.ChainConfig, period uint64, committee, nextCommittee *types.SerializedSyncCommittee, signerCount int, finalizedHeader bool) *types.LightClientUpdate {
|
||||||
update := new(types.LightClientUpdate)
|
update := new(types.LightClientUpdate)
|
||||||
update.NextSyncCommitteeRoot = nextCommittee.Root()
|
update.NextSyncCommitteeRoot = nextCommittee.Root()
|
||||||
var attestedHeader types.Header
|
var attestedHeader types.Header
|
||||||
|
@ -48,9 +48,9 @@ func GenerateTestUpdate(config *types.ChainConfig, period uint64, committee, nex
|
||||||
return update
|
return update
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateTestSignedHeader(header types.Header, config *types.ChainConfig, committee *types.SerializedSyncCommittee, signatureSlot uint64, signerCount int) types.SignedHeader {
|
func GenerateTestSignedHeader(header types.Header, config *params.ChainConfig, committee *types.SerializedSyncCommittee, signatureSlot uint64, signerCount int) types.SignedHeader {
|
||||||
bitmask := makeBitmask(signerCount)
|
bitmask := makeBitmask(signerCount)
|
||||||
signingRoot, _ := config.Forks.SigningRoot(header)
|
signingRoot, _ := config.Forks.SigningRoot(header.Epoch(), header.Hash())
|
||||||
c, _ := dummyVerifier{}.deserializeSyncCommittee(committee)
|
c, _ := dummyVerifier{}.deserializeSyncCommittee(committee)
|
||||||
return types.SignedHeader{
|
return types.SignedHeader{
|
||||||
Header: header,
|
Header: header,
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package types
|
package params
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
@ -39,81 +39,13 @@ const syncCommitteeDomain = 7
|
||||||
|
|
||||||
var knownForks = []string{"GENESIS", "ALTAIR", "BELLATRIX", "CAPELLA", "DENEB"}
|
var knownForks = []string{"GENESIS", "ALTAIR", "BELLATRIX", "CAPELLA", "DENEB"}
|
||||||
|
|
||||||
// Fork describes a single beacon chain fork and also stores the calculated
|
// ClientConfig contains beacon light client configuration.
|
||||||
// signature domain used after this fork.
|
type ClientConfig struct {
|
||||||
type Fork struct {
|
ChainConfig
|
||||||
// Name of the fork in the chain config (config.yaml) file
|
Apis []string
|
||||||
Name string
|
CustomHeader map[string]string
|
||||||
|
Threshold int
|
||||||
// Epoch when given fork version is activated
|
NoFilter bool
|
||||||
Epoch uint64
|
|
||||||
|
|
||||||
// Fork version, see https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types
|
|
||||||
Version []byte
|
|
||||||
|
|
||||||
// index in list of known forks or MaxInt if unknown
|
|
||||||
knownIndex int
|
|
||||||
|
|
||||||
// calculated by computeDomain, based on fork version and genesis validators root
|
|
||||||
domain merkle.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
// computeDomain returns the signature domain based on the given fork version
|
|
||||||
// and genesis validator set root.
|
|
||||||
func (f *Fork) computeDomain(genesisValidatorsRoot common.Hash) {
|
|
||||||
var (
|
|
||||||
hasher = sha256.New()
|
|
||||||
forkVersion32 merkle.Value
|
|
||||||
forkDataRoot merkle.Value
|
|
||||||
)
|
|
||||||
copy(forkVersion32[:], f.Version)
|
|
||||||
hasher.Write(forkVersion32[:])
|
|
||||||
hasher.Write(genesisValidatorsRoot[:])
|
|
||||||
hasher.Sum(forkDataRoot[:0])
|
|
||||||
|
|
||||||
f.domain[0] = syncCommitteeDomain
|
|
||||||
copy(f.domain[4:], forkDataRoot[:28])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Forks is the list of all beacon chain forks in the chain configuration.
|
|
||||||
type Forks []*Fork
|
|
||||||
|
|
||||||
// domain returns the signature domain for the given epoch (assumes that domains
|
|
||||||
// have already been calculated).
|
|
||||||
func (f Forks) domain(epoch uint64) (merkle.Value, error) {
|
|
||||||
for i := len(f) - 1; i >= 0; i-- {
|
|
||||||
if epoch >= f[i].Epoch {
|
|
||||||
return f[i].domain, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return merkle.Value{}, fmt.Errorf("unknown fork for epoch %d", epoch)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SigningRoot calculates the signing root of the given header.
|
|
||||||
func (f Forks) SigningRoot(header Header) (common.Hash, error) {
|
|
||||||
domain, err := f.domain(header.Epoch())
|
|
||||||
if err != nil {
|
|
||||||
return common.Hash{}, err
|
|
||||||
}
|
|
||||||
var (
|
|
||||||
signingRoot common.Hash
|
|
||||||
headerHash = header.Hash()
|
|
||||||
hasher = sha256.New()
|
|
||||||
)
|
|
||||||
hasher.Write(headerHash[:])
|
|
||||||
hasher.Write(domain[:])
|
|
||||||
hasher.Sum(signingRoot[:0])
|
|
||||||
|
|
||||||
return signingRoot, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f Forks) Len() int { return len(f) }
|
|
||||||
func (f Forks) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
|
|
||||||
func (f Forks) Less(i, j int) bool {
|
|
||||||
if f[i].Epoch != f[j].Epoch {
|
|
||||||
return f[i].Epoch < f[j].Epoch
|
|
||||||
}
|
|
||||||
return f[i].knownIndex < f[j].knownIndex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChainConfig contains the beacon chain configuration.
|
// ChainConfig contains the beacon chain configuration.
|
||||||
|
@ -121,6 +53,7 @@ type ChainConfig struct {
|
||||||
GenesisTime uint64 // Unix timestamp of slot 0
|
GenesisTime uint64 // Unix timestamp of slot 0
|
||||||
GenesisValidatorsRoot common.Hash // Root hash of the genesis validator set, used for signature domain calculation
|
GenesisValidatorsRoot common.Hash // Root hash of the genesis validator set, used for signature domain calculation
|
||||||
Forks Forks
|
Forks Forks
|
||||||
|
Checkpoint common.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForkAtEpoch returns the latest active fork at the given epoch.
|
// ForkAtEpoch returns the latest active fork at the given epoch.
|
||||||
|
@ -202,3 +135,79 @@ func (c *ChainConfig) LoadForks(path string) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fork describes a single beacon chain fork and also stores the calculated
|
||||||
|
// signature domain used after this fork.
|
||||||
|
type Fork struct {
|
||||||
|
// Name of the fork in the chain config (config.yaml) file
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// Epoch when given fork version is activated
|
||||||
|
Epoch uint64
|
||||||
|
|
||||||
|
// Fork version, see https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types
|
||||||
|
Version []byte
|
||||||
|
|
||||||
|
// index in list of known forks or MaxInt if unknown
|
||||||
|
knownIndex int
|
||||||
|
|
||||||
|
// calculated by computeDomain, based on fork version and genesis validators root
|
||||||
|
domain merkle.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// computeDomain returns the signature domain based on the given fork version
|
||||||
|
// and genesis validator set root.
|
||||||
|
func (f *Fork) computeDomain(genesisValidatorsRoot common.Hash) {
|
||||||
|
var (
|
||||||
|
hasher = sha256.New()
|
||||||
|
forkVersion32 merkle.Value
|
||||||
|
forkDataRoot merkle.Value
|
||||||
|
)
|
||||||
|
copy(forkVersion32[:], f.Version)
|
||||||
|
hasher.Write(forkVersion32[:])
|
||||||
|
hasher.Write(genesisValidatorsRoot[:])
|
||||||
|
hasher.Sum(forkDataRoot[:0])
|
||||||
|
|
||||||
|
f.domain[0] = syncCommitteeDomain
|
||||||
|
copy(f.domain[4:], forkDataRoot[:28])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forks is the list of all beacon chain forks in the chain configuration.
|
||||||
|
type Forks []*Fork
|
||||||
|
|
||||||
|
// domain returns the signature domain for the given epoch (assumes that domains
|
||||||
|
// have already been calculated).
|
||||||
|
func (f Forks) domain(epoch uint64) (merkle.Value, error) {
|
||||||
|
for i := len(f) - 1; i >= 0; i-- {
|
||||||
|
if epoch >= f[i].Epoch {
|
||||||
|
return f[i].domain, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return merkle.Value{}, fmt.Errorf("unknown fork for epoch %d", epoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SigningRoot calculates the signing root of the given header.
|
||||||
|
func (f Forks) SigningRoot(epoch uint64, root common.Hash) (common.Hash, error) {
|
||||||
|
domain, err := f.domain(epoch)
|
||||||
|
if err != nil {
|
||||||
|
return common.Hash{}, err
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
signingRoot common.Hash
|
||||||
|
hasher = sha256.New()
|
||||||
|
)
|
||||||
|
hasher.Write(root[:])
|
||||||
|
hasher.Write(domain[:])
|
||||||
|
hasher.Sum(signingRoot[:0])
|
||||||
|
|
||||||
|
return signingRoot, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f Forks) Len() int { return len(f) }
|
||||||
|
func (f Forks) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
|
||||||
|
func (f Forks) Less(i, j int) bool {
|
||||||
|
if f[i].Epoch != f[j].Epoch {
|
||||||
|
return f[i].Epoch < f[j].Epoch
|
||||||
|
}
|
||||||
|
return f[i].knownIndex < f[j].knownIndex
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright 2016 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package params
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
MainnetLightConfig = (&ChainConfig{
|
||||||
|
GenesisValidatorsRoot: common.HexToHash("0x4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95"),
|
||||||
|
GenesisTime: 1606824023,
|
||||||
|
Checkpoint: common.HexToHash("0x6509b691f4de4f7b083f2784938fd52f0e131675432b3fd85ea549af9aebd3d0"),
|
||||||
|
}).
|
||||||
|
AddFork("GENESIS", 0, []byte{0, 0, 0, 0}).
|
||||||
|
AddFork("ALTAIR", 74240, []byte{1, 0, 0, 0}).
|
||||||
|
AddFork("BELLATRIX", 144896, []byte{2, 0, 0, 0}).
|
||||||
|
AddFork("CAPELLA", 194048, []byte{3, 0, 0, 0}).
|
||||||
|
AddFork("DENEB", 269568, []byte{4, 0, 0, 0})
|
||||||
|
|
||||||
|
SepoliaLightConfig = (&ChainConfig{
|
||||||
|
GenesisValidatorsRoot: common.HexToHash("0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078"),
|
||||||
|
GenesisTime: 1655733600,
|
||||||
|
Checkpoint: common.HexToHash("0x456e85f5608afab3465a0580bff8572255f6d97af0c5f939e3f7536b5edb2d3f"),
|
||||||
|
}).
|
||||||
|
AddFork("GENESIS", 0, []byte{144, 0, 0, 105}).
|
||||||
|
AddFork("ALTAIR", 50, []byte{144, 0, 0, 112}).
|
||||||
|
AddFork("BELLATRIX", 100, []byte{144, 0, 0, 113}).
|
||||||
|
AddFork("CAPELLA", 56832, []byte{144, 0, 0, 114}).
|
||||||
|
AddFork("DENEB", 132608, []byte{144, 0, 0, 115})
|
||||||
|
|
||||||
|
HoleskyLightConfig = (&ChainConfig{
|
||||||
|
GenesisValidatorsRoot: common.HexToHash("0x9143aa7c615a7f7115e2b6aac319c03529df8242ae705fba9df39b79c59fa8b1"),
|
||||||
|
GenesisTime: 1695902400,
|
||||||
|
Checkpoint: common.HexToHash("0x6456a1317f54d4b4f2cb5bc9d153b5af0988fe767ef0609f0236cf29030bcff7"),
|
||||||
|
}).
|
||||||
|
AddFork("GENESIS", 0, []byte{1, 1, 112, 0}).
|
||||||
|
AddFork("ALTAIR", 0, []byte{2, 1, 112, 0}).
|
||||||
|
AddFork("BELLATRIX", 0, []byte{3, 1, 112, 0}).
|
||||||
|
AddFork("CAPELLA", 256, []byte{4, 1, 112, 0}).
|
||||||
|
AddFork("DENEB", 29696, []byte{5, 1, 112, 0})
|
||||||
|
)
|
|
@ -70,7 +70,7 @@ func main() {
|
||||||
|
|
||||||
func sync(ctx *cli.Context) error {
|
func sync(ctx *cli.Context) error {
|
||||||
// set up blsync
|
// set up blsync
|
||||||
client := blsync.NewClient(ctx)
|
client := blsync.NewClient(utils.MakeBeaconLightConfig(ctx))
|
||||||
client.SetEngineRPC(makeRPCClient(ctx))
|
client.SetEngineRPC(makeRPCClient(ctx))
|
||||||
client.Start()
|
client.Start()
|
||||||
|
|
||||||
|
|
|
@ -240,7 +240,7 @@ func makeFullNode(ctx *cli.Context) *node.Node {
|
||||||
// Start blsync mode.
|
// Start blsync mode.
|
||||||
srv := rpc.NewServer()
|
srv := rpc.NewServer()
|
||||||
srv.RegisterName("engine", catalyst.NewConsensusAPI(eth))
|
srv.RegisterName("engine", catalyst.NewConsensusAPI(eth))
|
||||||
blsyncer := blsync.NewClient(ctx)
|
blsyncer := blsync.NewClient(utils.MakeBeaconLightConfig(ctx))
|
||||||
blsyncer.SetEngineRPC(rpc.DialInProc(srv))
|
blsyncer.SetEngineRPC(rpc.DialInProc(srv))
|
||||||
stack.RegisterLifecycle(blsyncer)
|
stack.RegisterLifecycle(blsyncer)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -40,6 +40,7 @@ import (
|
||||||
bparams "github.com/ethereum/go-ethereum/beacon/params"
|
bparams "github.com/ethereum/go-ethereum/beacon/params"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/fdlimit"
|
"github.com/ethereum/go-ethereum/common/fdlimit"
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/core/txpool/blobpool"
|
"github.com/ethereum/go-ethereum/core/txpool/blobpool"
|
||||||
|
@ -1889,6 +1890,81 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MakeBeaconLightConfig constructs a beacon light client config based on the
|
||||||
|
// related command line flags.
|
||||||
|
func MakeBeaconLightConfig(ctx *cli.Context) bparams.ClientConfig {
|
||||||
|
var config bparams.ClientConfig
|
||||||
|
customConfig := ctx.IsSet(BeaconConfigFlag.Name)
|
||||||
|
CheckExclusive(ctx, MainnetFlag, SepoliaFlag, HoleskyFlag, BeaconConfigFlag)
|
||||||
|
switch {
|
||||||
|
case ctx.Bool(MainnetFlag.Name):
|
||||||
|
config.ChainConfig = *bparams.MainnetLightConfig
|
||||||
|
case ctx.Bool(SepoliaFlag.Name):
|
||||||
|
config.ChainConfig = *bparams.SepoliaLightConfig
|
||||||
|
case ctx.Bool(HoleskyFlag.Name):
|
||||||
|
config.ChainConfig = *bparams.HoleskyLightConfig
|
||||||
|
default:
|
||||||
|
if !customConfig {
|
||||||
|
config.ChainConfig = *bparams.MainnetLightConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Genesis root and time should always be specified together with custom chain config
|
||||||
|
if customConfig {
|
||||||
|
if !ctx.IsSet(BeaconGenesisRootFlag.Name) {
|
||||||
|
Fatalf("Custom beacon chain config is specified but genesis root is missing")
|
||||||
|
}
|
||||||
|
if !ctx.IsSet(BeaconGenesisTimeFlag.Name) {
|
||||||
|
Fatalf("Custom beacon chain config is specified but genesis time is missing")
|
||||||
|
}
|
||||||
|
if !ctx.IsSet(BeaconCheckpointFlag.Name) {
|
||||||
|
Fatalf("Custom beacon chain config is specified but checkpoint is missing")
|
||||||
|
}
|
||||||
|
config.ChainConfig = bparams.ChainConfig{
|
||||||
|
GenesisTime: ctx.Uint64(BeaconGenesisTimeFlag.Name),
|
||||||
|
}
|
||||||
|
if c, err := hexutil.Decode(ctx.String(BeaconGenesisRootFlag.Name)); err == nil && len(c) <= 32 {
|
||||||
|
copy(config.GenesisValidatorsRoot[:len(c)], c)
|
||||||
|
} else {
|
||||||
|
Fatalf("Invalid hex string", "beacon.genesis.gvroot", ctx.String(BeaconGenesisRootFlag.Name), "error", err)
|
||||||
|
}
|
||||||
|
configFile := ctx.String(BeaconConfigFlag.Name)
|
||||||
|
if err := config.ChainConfig.LoadForks(configFile); err != nil {
|
||||||
|
Fatalf("Could not load beacon chain config", "file", configFile, "error", err)
|
||||||
|
}
|
||||||
|
log.Info("Using custom beacon chain config", "file", configFile)
|
||||||
|
} else {
|
||||||
|
if ctx.IsSet(BeaconGenesisRootFlag.Name) {
|
||||||
|
Fatalf("Genesis root is specified but custom beacon chain config is missing")
|
||||||
|
}
|
||||||
|
if ctx.IsSet(BeaconGenesisTimeFlag.Name) {
|
||||||
|
Fatalf("Genesis time is specified but custom beacon chain config is missing")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Checkpoint is required with custom chain config and is optional with pre-defined config
|
||||||
|
if ctx.IsSet(BeaconCheckpointFlag.Name) {
|
||||||
|
if c, err := hexutil.Decode(ctx.String(BeaconCheckpointFlag.Name)); err == nil && len(c) <= 32 {
|
||||||
|
copy(config.Checkpoint[:len(c)], c)
|
||||||
|
} else {
|
||||||
|
Fatalf("Invalid hex string", "beacon.checkpoint", ctx.String(BeaconCheckpointFlag.Name), "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config.Apis = ctx.StringSlice(BeaconApiFlag.Name)
|
||||||
|
if config.Apis == nil {
|
||||||
|
Fatalf("Beacon node light client API URL not specified")
|
||||||
|
}
|
||||||
|
config.CustomHeader = make(map[string]string)
|
||||||
|
for _, s := range ctx.StringSlice(BeaconApiHeaderFlag.Name) {
|
||||||
|
kv := strings.Split(s, ":")
|
||||||
|
if len(kv) != 2 {
|
||||||
|
Fatalf("Invalid custom API header entry: %s", s)
|
||||||
|
}
|
||||||
|
config.CustomHeader[strings.TrimSpace(kv[0])] = strings.TrimSpace(kv[1])
|
||||||
|
}
|
||||||
|
config.Threshold = ctx.Int(BeaconThresholdFlag.Name)
|
||||||
|
config.NoFilter = ctx.Bool(BeaconNoFilterFlag.Name)
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
// SetDNSDiscoveryDefaults configures DNS discovery with the given URL if
|
// SetDNSDiscoveryDefaults configures DNS discovery with the given URL if
|
||||||
// no URLs are set.
|
// no URLs are set.
|
||||||
func SetDNSDiscoveryDefaults(cfg *ethconfig.Config, genesis common.Hash) {
|
func SetDNSDiscoveryDefaults(cfg *ethconfig.Config, genesis common.Hash) {
|
||||||
|
|
Loading…
Reference in New Issue