[caplin/sentinel] config reorganizations (#8844)

This commit is contained in:
a 2023-11-28 22:45:58 -06:00 committed by GitHub
parent 3e8a028cbb
commit a2673c62c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 454 additions and 391 deletions

View File

@ -0,0 +1,124 @@
package caplincli
import (
"errors"
"fmt"
"os"
"strings"
"time"
"github.com/ledgerwatch/erigon-lib/common/datadir"
"github.com/ledgerwatch/erigon/cl/clparams"
"github.com/ledgerwatch/erigon/cl/phase1/core/state"
"github.com/ledgerwatch/erigon/cmd/caplin/caplinflags"
"github.com/ledgerwatch/erigon/cmd/sentinel/sentinelcli"
"github.com/ledgerwatch/erigon/cmd/sentinel/sentinelflags"
"github.com/ledgerwatch/erigon/cmd/utils"
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/log/v3"
"github.com/urfave/cli/v2"
)
type CaplinCliCfg struct {
*sentinelcli.SentinelCliCfg
CheckpointUri string `json:"checkpoint_uri"`
Chaindata string `json:"chaindata"`
ErigonPrivateApi string `json:"erigon_private_api"`
TransitionChain bool `json:"transition_chain"`
InitialSync bool `json:"initial_sync"`
NoBeaconApi bool `json:"no_beacon_api"`
BeaconApiReadTimeout time.Duration `json:"beacon_api_read_timeout"`
BeaconApiWriteTimeout time.Duration `json:"beacon_api_write_timeout"`
BeaconAddr string `json:"beacon_addr"`
BeaconProtocol string `json:"beacon_protocol"`
RecordMode bool `json:"record_mode"`
RecordDir string `json:"record_dir"`
DataDir string `json:"data_dir"`
RunEngineAPI bool `json:"run_engine_api"`
EngineAPIAddr string `json:"engine_api_addr"`
EngineAPIPort int `json:"engine_api_port"`
JwtSecret []byte
InitalState *state.CachingBeaconState
Dirs datadir.Dirs
}
func SetupCaplinCli(ctx *cli.Context) (cfg *CaplinCliCfg, err error) {
cfg = &CaplinCliCfg{}
cfg.SentinelCliCfg, err = sentinelcli.SetupSentinelCli(ctx)
if err != nil {
return nil, err
}
cfg.ErigonPrivateApi = ctx.String(caplinflags.ErigonPrivateApiFlag.Name)
if ctx.String(sentinelflags.BeaconConfigFlag.Name) != "" {
var stateByte []byte
// Now parse genesis time and genesis fork
if *cfg.GenesisCfg, stateByte, err = clparams.ParseGenesisSSZToGenesisConfig(
ctx.String(sentinelflags.GenesisSSZFlag.Name),
cfg.BeaconCfg.GetCurrentStateVersion(0)); err != nil {
return nil, err
}
cfg.InitalState = state.New(cfg.BeaconCfg)
if cfg.InitalState.DecodeSSZ(stateByte, int(cfg.BeaconCfg.GetCurrentStateVersion(0))); err != nil {
return nil, err
}
}
cfg.NoBeaconApi = ctx.Bool(caplinflags.NoBeaconApi.Name)
cfg.BeaconApiReadTimeout = time.Duration(ctx.Uint64(caplinflags.BeaconApiReadTimeout.Name)) * time.Second
cfg.BeaconApiWriteTimeout = time.Duration(ctx.Uint(caplinflags.BeaconApiWriteTimeout.Name)) * time.Second
cfg.BeaconAddr = fmt.Sprintf("%s:%d", ctx.String(caplinflags.BeaconApiAddr.Name), ctx.Int(caplinflags.BeaconApiPort.Name))
cfg.BeaconProtocol = "tcp"
cfg.RecordMode = ctx.Bool(caplinflags.RecordModeFlag.Name)
cfg.RecordDir = ctx.String(caplinflags.RecordModeDir.Name)
cfg.DataDir = ctx.String(utils.DataDirFlag.Name)
cfg.Dirs = datadir.New(cfg.DataDir)
cfg.RunEngineAPI = ctx.Bool(caplinflags.RunEngineAPI.Name)
cfg.EngineAPIAddr = ctx.String(caplinflags.EngineApiHostFlag.Name)
cfg.EngineAPIPort = ctx.Int(caplinflags.EngineApiPortFlag.Name)
if cfg.RunEngineAPI {
secret, err := ObtainJwtSecret(ctx)
if err != nil {
log.Error("Failed to obtain jwt secret", "err", err)
cfg.RunEngineAPI = false
} else {
cfg.JwtSecret = secret
}
}
if ctx.String(caplinflags.CheckpointSyncUrlFlag.Name) != "" {
cfg.CheckpointUri = ctx.String(caplinflags.CheckpointSyncUrlFlag.Name)
} else {
cfg.CheckpointUri = clparams.GetCheckpointSyncEndpoint(cfg.NetworkType)
}
cfg.Chaindata = ctx.String(caplinflags.ChaindataFlag.Name)
cfg.TransitionChain = ctx.Bool(caplinflags.TransitionChainFlag.Name)
cfg.InitialSync = ctx.Bool(caplinflags.InitSyncFlag.Name)
return nil, err
}
func ObtainJwtSecret(ctx *cli.Context) ([]byte, error) {
path := ctx.String(caplinflags.JwtSecret.Name)
if len(strings.TrimSpace(path)) == 0 {
return nil, errors.New("Missing jwt secret path")
}
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
jwtSecret := common.FromHex(strings.TrimSpace(string(data)))
if len(jwtSecret) == 32 {
return jwtSecret, nil
}
return nil, fmt.Errorf("Invalid JWT secret at %s, invalid size", path)
}

View File

@ -1,34 +1,35 @@
package flags
package caplinflags
import (
"github.com/ledgerwatch/erigon/cmd/utils"
"github.com/urfave/cli/v2"
)
var CliFlags = []cli.Flag{
&NoBeaconApi,
&BeaconApiReadTimeout,
&BeaconApiWriteTimeout,
&BeaconApiPort,
&BeaconApiAddr,
&ChaindataFlag,
&BeaconDBModeFlag,
&CheckpointSyncUrlFlag,
&TransitionChainFlag,
&InitSyncFlag,
&RecordModeDir,
&RecordModeFlag,
&RunEngineAPI,
&EngineApiHostFlag,
&EngineApiPortFlag,
&JwtSecret,
&utils.DataDirFlag,
}
var (
SentinelDiscoveryPort = cli.IntFlag{
Name: "discovery.port",
Usage: "sets the lightclient port",
Value: 4000,
}
SentinelDiscoveryAddr = cli.StringFlag{
Name: "discovery.addr",
Usage: "sets the lightclient discovery addr",
Value: "127.0.0.1",
}
SentinelTcpPort = cli.UintFlag{
Name: "sentinel.tcp.port",
Usage: "sets lightclient tcp port",
Value: 4001,
}
SentinelServerPort = cli.IntFlag{
Name: "sentinel.port",
Usage: "sets the lightclient server port",
Value: 7777,
}
SentinelServerAddr = cli.StringFlag{
Name: "sentinel.addr",
Usage: "sets the lightclient server host addr",
Value: "localhost",
ChaindataFlag = cli.StringFlag{
Name: "chaindata",
Usage: "chaindata of database",
Value: "",
}
NoBeaconApi = cli.BoolFlag{
Name: "no-beacon-api",
@ -55,41 +56,7 @@ var (
Usage: "sets the port to listen for beacon api requests",
Value: 5555,
}
BootnodesFlag = cli.StringFlag{
Name: "sentinel.bootnodes",
Usage: "Comma separated enode URLs for P2P discovery bootstrap",
Value: "",
}
BeaconConfigFlag = cli.StringFlag{
Name: "beacon-config",
Usage: "Path to beacon config",
Value: "",
}
GenesisSSZFlag = cli.StringFlag{
Name: "genesis-ssz",
Usage: "Path to genesis ssz",
Value: "",
}
Chain = cli.StringFlag{
Name: "chain",
Usage: "sets the chain specs for the lightclient",
Value: "mainnet",
}
NoDiscovery = cli.BoolFlag{
Name: "no-discovery",
Usage: "turn off or on the lightclient finding peers",
Value: false,
}
LocalDiscovery = cli.BoolFlag{
Name: "local-discovery",
Usage: "enable to also attempt to find peers over private ips. turning this on may cause issues with hosts such as hetzner",
Value: false,
}
ChaindataFlag = cli.StringFlag{
Name: "chaindata",
Usage: "chaindata of database",
Value: "",
}
BeaconDBModeFlag = cli.StringFlag{
Name: "beacon-db-mode",
Usage: "level of storing on beacon chain, minimal(only 500k blocks stored), full (all blocks stored), light (no blocks stored)",
@ -100,6 +67,25 @@ var (
Usage: "checkpoint sync endpoint",
Value: "",
}
TransitionChainFlag = cli.BoolFlag{
Name: "transition-chain",
Usage: "enable chain transition",
}
InitSyncFlag = cli.BoolFlag{
Value: false,
Name: "initial-sync",
Usage: "use initial-sync",
}
RecordModeFlag = cli.BoolFlag{
Value: false,
Name: "record-mode",
Usage: "enable/disable record mode",
}
RecordModeDir = cli.StringFlag{
Value: "caplin-recordings",
Name: "record-dir",
Usage: "directory for states and block recordings",
}
ErigonPrivateApiFlag = cli.StringFlag{
Name: "private.api.addr",
Usage: "connect to existing erigon instance",
@ -125,28 +111,4 @@ var (
Usage: "Path to the token that ensures safe connection between CL and EL",
Value: "",
}
SentinelStaticPeersFlag = cli.StringFlag{
Name: "sentinel.staticpeers",
Usage: "connect to comma-separated Consensus static peers",
Value: "",
}
TransitionChainFlag = cli.BoolFlag{
Name: "transition-chain",
Usage: "enable chain transition",
}
InitSyncFlag = cli.BoolFlag{
Value: false,
Name: "initial-sync",
Usage: "use initial-sync",
}
RecordModeFlag = cli.BoolFlag{
Value: false,
Name: "record-mode",
Usage: "enable/disable record mode",
}
RecordModeDir = cli.StringFlag{
Value: "caplin-recordings",
Name: "record-dir",
Usage: "directory for states and block recordings",
}
)

View File

@ -1,15 +1,13 @@
/*
Copyright 2022 Erigon-Lightclient contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Copyright 2022 Erigon-Lightclient contributors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
@ -32,14 +30,16 @@ import (
"github.com/urfave/cli/v2"
"github.com/ledgerwatch/erigon/cmd/caplin/caplin1"
lcCli "github.com/ledgerwatch/erigon/cmd/sentinel/cli"
"github.com/ledgerwatch/erigon/cmd/sentinel/cli/flags"
"github.com/ledgerwatch/erigon/cmd/caplin/caplincli"
"github.com/ledgerwatch/erigon/cmd/caplin/caplinflags"
"github.com/ledgerwatch/erigon/cmd/sentinel/sentinelflags"
"github.com/ledgerwatch/erigon/cmd/utils"
"github.com/ledgerwatch/erigon/turbo/app"
"github.com/ledgerwatch/erigon/turbo/debug"
)
func main() {
app := app.MakeApp("caplin", runCaplinNode, flags.CLDefaultFlags)
app := app.MakeApp("caplin", runCaplinNode, append(caplinflags.CliFlags, sentinelflags.CliFlags...))
if err := app.Run(os.Args); err != nil {
_, printErr := fmt.Fprintln(os.Stderr, err)
if printErr != nil {
@ -50,10 +50,7 @@ func main() {
}
func runCaplinNode(cliCtx *cli.Context) error {
ctx, cn := context.WithCancel(context.Background())
defer cn()
cfg, err := lcCli.SetupConsensusClientCfg(cliCtx)
cfg, err := caplincli.SetupCaplinCli(cliCtx)
if err != nil {
log.Error("[Phase1] Could not initialize caplin", "err", err)
}
@ -61,9 +58,11 @@ func runCaplinNode(cliCtx *cli.Context) error {
return err
}
log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(cfg.LogLvl), log.StderrHandler))
log.Info("[Phase1]", "chain", cliCtx.String(flags.Chain.Name))
log.Info("[Phase1]", "chain", cliCtx.String(utils.ChainFlag.Name))
log.Info("[Phase1] Running Caplin")
// Either start from genesis or a checkpoint
ctx, cn := context.WithCancel(context.Background())
defer cn()
var state *state.CachingBeaconState
if cfg.InitialSync {
state = cfg.InitalState

View File

@ -1,23 +1,16 @@
package main
import (
"errors"
"fmt"
"net/http"
"os"
"path/filepath"
"reflect"
"strings"
"github.com/ledgerwatch/log/v3"
"github.com/pelletier/go-toml"
"github.com/urfave/cli/v2"
"gopkg.in/yaml.v2"
"github.com/ledgerwatch/erigon-lib/common/datadir"
"github.com/ledgerwatch/erigon-lib/common/dbg"
"github.com/ledgerwatch/erigon-lib/metrics"
"github.com/ledgerwatch/erigon/cmd/utils"
"github.com/ledgerwatch/erigon/diagnostics"
"github.com/ledgerwatch/erigon/params"
erigonapp "github.com/ledgerwatch/erigon/turbo/app"
@ -48,14 +41,6 @@ func main() {
}
func runErigon(cliCtx *cli.Context) error {
configFilePath := cliCtx.String(utils.ConfigFlag.Name)
if configFilePath != "" {
if err := setFlagsFromConfigFile(cliCtx, configFilePath); err != nil {
log.Error("failed setting config flags from yaml/toml file", "err", err)
return err
}
}
var logger log.Logger
var err error
var metricsMux *http.ServeMux
@ -93,55 +78,3 @@ func runErigon(cliCtx *cli.Context) error {
}
return err
}
func setFlagsFromConfigFile(ctx *cli.Context, filePath string) error {
fileExtension := filepath.Ext(filePath)
fileConfig := make(map[string]interface{})
if fileExtension == ".yaml" {
yamlFile, err := os.ReadFile(filePath)
if err != nil {
return err
}
err = yaml.Unmarshal(yamlFile, fileConfig)
if err != nil {
return err
}
} else if fileExtension == ".toml" {
tomlFile, err := os.ReadFile(filePath)
if err != nil {
return err
}
err = toml.Unmarshal(tomlFile, &fileConfig)
if err != nil {
return err
}
} else {
return errors.New("config files only accepted are .yaml and .toml")
}
// sets global flags to value in yaml/toml file
for key, value := range fileConfig {
if !ctx.IsSet(key) {
if reflect.ValueOf(value).Kind() == reflect.Slice {
sliceInterface := value.([]interface{})
s := make([]string, len(sliceInterface))
for i, v := range sliceInterface {
s[i] = fmt.Sprintf("%v", v)
}
err := ctx.Set(key, strings.Join(s, ","))
if err != nil {
return fmt.Errorf("failed setting %s flag with values=%s error=%s", key, s, err)
}
} else {
err := ctx.Set(key, fmt.Sprintf("%v", value))
if err != nil {
return fmt.Errorf("failed setting %s flag with value=%v error=%s", key, value, err)
}
}
}
}
return nil
}

View File

@ -1,161 +0,0 @@
package cli
import (
"errors"
"fmt"
"os"
"strings"
"time"
"github.com/ledgerwatch/erigon/cl/clparams"
"github.com/ledgerwatch/erigon/cl/phase1/core/state"
common2 "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/common/datadir"
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/cmd/utils"
"github.com/urfave/cli/v2"
"github.com/ledgerwatch/erigon/cmd/sentinel/cli/flags"
"github.com/ledgerwatch/erigon/turbo/logging"
"github.com/ledgerwatch/log/v3"
)
type ConsensusClientCliCfg struct {
GenesisCfg *clparams.GenesisConfig
BeaconCfg *clparams.BeaconChainConfig
NetworkCfg *clparams.NetworkConfig
Port uint `json:"port"`
Addr string `json:"address"`
ServerAddr string `json:"server_addr"`
ServerProtocol string `json:"server_protocol"`
ServerTcpPort uint `json:"server_tcp_port"`
LogLvl uint `json:"log_level"`
NoDiscovery bool `json:"no_discovery"`
LocalDiscovery bool `json:"local_discovery"`
CheckpointUri string `json:"checkpoint_uri"`
Chaindata string `json:"chaindata"`
ErigonPrivateApi string `json:"erigon_private_api"`
TransitionChain bool `json:"transition_chain"`
NetworkType clparams.NetworkType
InitialSync bool `json:"initial_sync"`
NoBeaconApi bool `json:"no_beacon_api"`
BeaconApiReadTimeout time.Duration `json:"beacon_api_read_timeout"`
BeaconApiWriteTimeout time.Duration `json:"beacon_api_write_timeout"`
BeaconAddr string `json:"beacon_addr"`
BeaconProtocol string `json:"beacon_protocol"`
RecordMode bool `json:"record_mode"`
RecordDir string `json:"record_dir"`
DataDir string `json:"data_dir"`
RunEngineAPI bool `json:"run_engine_api"`
EngineAPIAddr string `json:"engine_api_addr"`
EngineAPIPort int `json:"engine_api_port"`
JwtSecret []byte
InitalState *state.CachingBeaconState
Dirs datadir.Dirs
}
func SetupConsensusClientCfg(ctx *cli.Context) (*ConsensusClientCliCfg, error) {
cfg := &ConsensusClientCliCfg{}
chainName := ctx.String(flags.Chain.Name)
var err error
cfg.GenesisCfg, cfg.NetworkCfg, cfg.BeaconCfg, cfg.NetworkType, err = clparams.GetConfigsByNetworkName(chainName)
if err != nil {
return nil, err
}
cfg.ErigonPrivateApi = ctx.String(flags.ErigonPrivateApiFlag.Name)
if ctx.String(flags.BeaconConfigFlag.Name) != "" {
cfg.BeaconCfg = new(clparams.BeaconChainConfig)
if *cfg.BeaconCfg, err = clparams.CustomConfig(ctx.String(flags.BeaconConfigFlag.Name)); err != nil {
return nil, err
}
if ctx.String(flags.GenesisSSZFlag.Name) == "" {
return nil, fmt.Errorf("no genesis file provided")
}
cfg.GenesisCfg = new(clparams.GenesisConfig)
var stateByte []byte
// Now parse genesis time and genesis fork
if *cfg.GenesisCfg, stateByte, err = clparams.ParseGenesisSSZToGenesisConfig(
ctx.String(flags.GenesisSSZFlag.Name),
cfg.BeaconCfg.GetCurrentStateVersion(0)); err != nil {
return nil, err
}
cfg.InitalState = state.New(cfg.BeaconCfg)
if cfg.InitalState.DecodeSSZ(stateByte, int(cfg.BeaconCfg.GetCurrentStateVersion(0))); err != nil {
return nil, err
}
}
cfg.ServerAddr = fmt.Sprintf("%s:%d", ctx.String(flags.SentinelServerAddr.Name), ctx.Int(flags.SentinelServerPort.Name))
cfg.ServerProtocol = "tcp"
cfg.NoBeaconApi = ctx.Bool(flags.NoBeaconApi.Name)
cfg.BeaconApiReadTimeout = time.Duration(ctx.Uint64(flags.BeaconApiReadTimeout.Name)) * time.Second
cfg.BeaconApiWriteTimeout = time.Duration(ctx.Uint(flags.BeaconApiWriteTimeout.Name)) * time.Second
cfg.BeaconAddr = fmt.Sprintf("%s:%d", ctx.String(flags.BeaconApiAddr.Name), ctx.Int(flags.BeaconApiPort.Name))
cfg.BeaconProtocol = "tcp"
cfg.RecordMode = ctx.Bool(flags.RecordModeFlag.Name)
cfg.RecordDir = ctx.String(flags.RecordModeDir.Name)
cfg.DataDir = ctx.String(utils.DataDirFlag.Name)
cfg.Dirs = datadir.New(cfg.DataDir)
cfg.RunEngineAPI = ctx.Bool(flags.RunEngineAPI.Name)
cfg.EngineAPIAddr = ctx.String(flags.EngineApiHostFlag.Name)
cfg.EngineAPIPort = ctx.Int(flags.EngineApiPortFlag.Name)
if cfg.RunEngineAPI {
secret, err := ObtainJwtSecret(ctx)
if err != nil {
log.Error("Failed to obtain jwt secret", "err", err)
cfg.RunEngineAPI = false
} else {
cfg.JwtSecret = secret
}
}
cfg.Port = uint(ctx.Int(flags.SentinelDiscoveryPort.Name))
cfg.Addr = ctx.String(flags.SentinelDiscoveryAddr.Name)
cfg.LogLvl = ctx.Uint(logging.LogVerbosityFlag.Name)
if cfg.LogLvl == uint(log.LvlInfo) || cfg.LogLvl == 0 {
cfg.LogLvl = uint(log.LvlDebug)
}
cfg.NoDiscovery = ctx.Bool(flags.NoDiscovery.Name)
cfg.LocalDiscovery = ctx.Bool(flags.LocalDiscovery.Name)
if ctx.String(flags.CheckpointSyncUrlFlag.Name) != "" {
cfg.CheckpointUri = ctx.String(flags.CheckpointSyncUrlFlag.Name)
} else {
cfg.CheckpointUri = clparams.GetCheckpointSyncEndpoint(cfg.NetworkType)
}
cfg.Chaindata = ctx.String(flags.ChaindataFlag.Name)
// Process bootnodes
if ctx.String(flags.BootnodesFlag.Name) != "" {
cfg.NetworkCfg.BootNodes = common2.CliString2Array(ctx.String(flags.BootnodesFlag.Name))
}
if ctx.String(flags.SentinelStaticPeersFlag.Name) != "" {
cfg.NetworkCfg.StaticPeers = common2.CliString2Array(ctx.String(flags.SentinelStaticPeersFlag.Name))
}
cfg.TransitionChain = ctx.Bool(flags.TransitionChainFlag.Name)
cfg.InitialSync = ctx.Bool(flags.InitSyncFlag.Name)
return cfg, nil
}
func ObtainJwtSecret(ctx *cli.Context) ([]byte, error) {
path := ctx.String(flags.JwtSecret.Name)
if len(strings.TrimSpace(path)) == 0 {
return nil, errors.New("Missing jwt secret path")
}
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
jwtSecret := common.FromHex(strings.TrimSpace(string(data)))
if len(jwtSecret) == 32 {
return jwtSecret, nil
}
return nil, fmt.Errorf("Invalid JWT secret at %s, invalid size", path)
}

View File

@ -1,37 +0,0 @@
package flags
import (
"github.com/ledgerwatch/erigon/cmd/utils"
"github.com/urfave/cli/v2"
)
var CLDefaultFlags = []cli.Flag{
&SentinelDiscoveryPort,
&SentinelDiscoveryAddr,
&SentinelServerPort,
&SentinelServerAddr,
&NoBeaconApi,
&BeaconApiReadTimeout,
&BeaconApiWriteTimeout,
&BeaconApiPort,
&BeaconApiAddr,
&Chain,
&SentinelTcpPort,
&NoDiscovery,
&ChaindataFlag,
&BeaconDBModeFlag,
&BootnodesFlag,
&BeaconConfigFlag,
&GenesisSSZFlag,
&CheckpointSyncUrlFlag,
&SentinelStaticPeersFlag,
&TransitionChainFlag,
&InitSyncFlag,
&RecordModeDir,
&RecordModeFlag,
&RunEngineAPI,
&EngineApiHostFlag,
&EngineApiPortFlag,
&JwtSecret,
&utils.DataDirFlag,
}

View File

@ -1,35 +1,34 @@
/*
Copyright 2022 Erigon-Lightclient contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Copyright 2022 Erigon-Lightclient contributors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"context"
"fmt"
"os"
"github.com/ledgerwatch/erigon/cl/sentinel"
"github.com/ledgerwatch/erigon/cl/sentinel/service"
"os"
"github.com/ledgerwatch/erigon/cmd/sentinel/sentinelcli"
"github.com/ledgerwatch/erigon/cmd/sentinel/sentinelflags"
"github.com/ledgerwatch/log/v3"
"github.com/urfave/cli/v2"
lcCli "github.com/ledgerwatch/erigon/cmd/sentinel/cli"
"github.com/ledgerwatch/erigon/cmd/sentinel/cli/flags"
sentinelapp "github.com/ledgerwatch/erigon/turbo/app"
)
func main() {
app := sentinelapp.MakeApp("sentinel", runSentinelNode, flags.CLDefaultFlags)
app := sentinelapp.MakeApp("sentinel", runSentinelNode, sentinelflags.CliFlags)
if err := app.Run(os.Args); err != nil {
_, printErr := fmt.Fprintln(os.Stderr, err)
if printErr != nil {
@ -40,11 +39,13 @@ func main() {
}
func runSentinelNode(cliCtx *cli.Context) error {
cfg, _ := lcCli.SetupConsensusClientCfg(cliCtx)
cfg, err := sentinelcli.SetupSentinelCli(cliCtx)
if err != nil {
return err
}
log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(cfg.LogLvl), log.StderrHandler))
log.Info("[Sentinel] running sentinel with configuration", "cfg", cfg)
_, err := service.StartSentinelService(&sentinel.SentinelConfig{
_, err = service.StartSentinelService(&sentinel.SentinelConfig{
IpAddr: cfg.Addr,
Port: int(cfg.Port),
TCPPort: cfg.ServerTcpPort,

View File

@ -0,0 +1,74 @@
package sentinelcli
import (
"fmt"
"github.com/ledgerwatch/erigon/cl/clparams"
"github.com/ledgerwatch/erigon/cmd/sentinel/sentinelflags"
"github.com/ledgerwatch/erigon/cmd/utils"
"github.com/ledgerwatch/erigon-lib/common"
"github.com/urfave/cli/v2"
"github.com/ledgerwatch/erigon/turbo/logging"
"github.com/ledgerwatch/log/v3"
)
type SentinelCliCfg struct {
GenesisCfg *clparams.GenesisConfig
BeaconCfg *clparams.BeaconChainConfig
NetworkCfg *clparams.NetworkConfig
NetworkType clparams.NetworkType
Port uint `json:"port"`
Addr string `json:"address"`
ServerAddr string `json:"server_addr"`
ServerProtocol string `json:"server_protocol"`
ServerTcpPort uint `json:"server_tcp_port"`
LogLvl uint `json:"log_level"`
NoDiscovery bool `json:"no_discovery"`
LocalDiscovery bool `json:"local_discovery"`
}
func SetupSentinelCli(ctx *cli.Context) (*SentinelCliCfg, error) {
cfg := &SentinelCliCfg{}
chainName := ctx.String(utils.ChainFlag.Name)
var err error
cfg.GenesisCfg, cfg.NetworkCfg, cfg.BeaconCfg, cfg.NetworkType, err = clparams.GetConfigsByNetworkName(chainName)
if err != nil {
return nil, err
}
if ctx.String(sentinelflags.BeaconConfigFlag.Name) != "" {
cfg.BeaconCfg = new(clparams.BeaconChainConfig)
if *cfg.BeaconCfg, err = clparams.CustomConfig(ctx.String(sentinelflags.BeaconConfigFlag.Name)); err != nil {
return nil, err
}
if ctx.String(sentinelflags.GenesisSSZFlag.Name) == "" {
return nil, fmt.Errorf("no genesis file provided")
}
cfg.GenesisCfg = new(clparams.GenesisConfig)
}
cfg.ServerAddr = fmt.Sprintf("%s:%d", ctx.String(sentinelflags.SentinelServerAddr.Name), ctx.Int(sentinelflags.SentinelServerPort.Name))
cfg.ServerProtocol = "tcp"
cfg.Port = uint(ctx.Int(sentinelflags.SentinelDiscoveryPort.Name))
cfg.Addr = ctx.String(sentinelflags.SentinelDiscoveryAddr.Name)
cfg.LogLvl = ctx.Uint(logging.LogVerbosityFlag.Name)
if cfg.LogLvl == uint(log.LvlInfo) || cfg.LogLvl == 0 {
cfg.LogLvl = uint(log.LvlDebug)
}
cfg.NoDiscovery = ctx.Bool(sentinelflags.NoDiscovery.Name)
cfg.LocalDiscovery = ctx.Bool(sentinelflags.LocalDiscovery.Name)
// Process bootnodes
if ctx.String(sentinelflags.BootnodesFlag.Name) != "" {
cfg.NetworkCfg.BootNodes = common.CliString2Array(ctx.String(sentinelflags.BootnodesFlag.Name))
}
if ctx.String(sentinelflags.SentinelStaticPeersFlag.Name) != "" {
cfg.NetworkCfg.StaticPeers = common.CliString2Array(ctx.String(sentinelflags.SentinelStaticPeersFlag.Name))
}
return cfg, nil
}

View File

@ -0,0 +1 @@
package flags

View File

@ -0,0 +1 @@
package flags

View File

@ -0,0 +1,79 @@
package sentinelflags
import (
"github.com/ledgerwatch/erigon/cmd/utils"
"github.com/urfave/cli/v2"
)
var CliFlags = []cli.Flag{
&utils.ChainFlag,
&SentinelDiscoveryPort,
&SentinelDiscoveryAddr,
&SentinelServerPort,
&SentinelServerAddr,
&SentinelTcpPort,
&NoDiscovery,
&BootnodesFlag,
&BeaconConfigFlag,
&GenesisSSZFlag,
&SentinelStaticPeersFlag,
}
var (
SentinelDiscoveryPort = cli.IntFlag{
Name: "discovery.port",
Usage: "sets the lightclient port",
Value: 4000,
}
SentinelDiscoveryAddr = cli.StringFlag{
Name: "discovery.addr",
Usage: "sets the lightclient discovery addr",
Value: "127.0.0.1",
}
SentinelTcpPort = cli.UintFlag{
Name: "sentinel.tcp.port",
Usage: "sets lightclient tcp port",
Value: 4001,
}
SentinelServerPort = cli.IntFlag{
Name: "sentinel.port",
Usage: "sets the lightclient server port",
Value: 7777,
}
SentinelServerAddr = cli.StringFlag{
Name: "sentinel.addr",
Usage: "sets the lightclient server host addr",
Value: "localhost",
}
NoDiscovery = cli.BoolFlag{
Name: "no-discovery",
Usage: "turn off or on the lightclient finding peers",
Value: false,
}
LocalDiscovery = cli.BoolFlag{
Name: "local-discovery",
Usage: "enable to also attempt to find peers over private ips. turning this on may cause issues with hosts such as hetzner",
Value: false,
}
BootnodesFlag = cli.StringFlag{
Name: "sentinel.bootnodes",
Usage: "Comma separated enode URLs for P2P discovery bootstrap",
Value: "",
}
BeaconConfigFlag = cli.StringFlag{
Name: "beacon-config",
Usage: "Path to beacon config",
Value: "",
}
GenesisSSZFlag = cli.StringFlag{
Name: "genesis-ssz",
Usage: "Path to genesis ssz",
Value: "",
}
SentinelStaticPeersFlag = cli.StringFlag{
Name: "sentinel.staticpeers",
Usage: "connect to comma-separated Consensus static peers",
Value: "",
}
)

View File

@ -97,7 +97,7 @@ var (
}
ChainFlag = cli.StringFlag{
Name: "chain",
Usage: "Name of the testnet to join",
Usage: "name of the network to join",
Value: networkname.MainnetChainName,
}
IdentityFlag = cli.StringFlag{

View File

@ -39,12 +39,35 @@ func MakeApp(name string, action cli.ActionFunc, cliFlags []cli.Flag) *cli.App {
cli.ShowAppHelpAndExit(context, 1)
}
// handle case: config flag
configFilePath := context.String(utils.ConfigFlag.Name)
if configFilePath != "" {
if err := cli2.SetFlagsFromConfigFile(context, configFilePath); err != nil {
log.Error("failed setting config flags from yaml/toml file", "err", err)
return err
}
}
// run default action
return action(context)
}
app.Flags = append(cliFlags, debug.Flags...) // debug flags are required
app.Flags = append(app.Flags, utils.MetricFlags...)
app.Flags = append(app.Flags, logging.Flags...)
app.Flags = append(app.Flags, &utils.ConfigFlag)
// remove exact duplicate flags, keeping only the first one. this will allow easier composition later down the line
allFlags := app.Flags
newFlags := make([]cli.Flag, 0, len(allFlags))
seen := map[string]struct{}{}
for _, vv := range allFlags {
v := vv
if _, ok := seen[v.String()]; ok {
continue
}
newFlags = append(newFlags, v)
}
app.Flags = newFlags
app.After = func(ctx *cli.Context) error {
debug.Exit()

66
turbo/cli/config_file.go Normal file
View File

@ -0,0 +1,66 @@
package cli
import (
"errors"
"fmt"
"os"
"path/filepath"
"reflect"
"strings"
"github.com/pelletier/go-toml"
"github.com/urfave/cli/v2"
"gopkg.in/yaml.v2"
)
func SetFlagsFromConfigFile(ctx *cli.Context, filePath string) error {
fileExtension := filepath.Ext(filePath)
fileConfig := make(map[string]interface{})
if fileExtension == ".yml" || fileExtension == ".yaml" {
yamlFile, err := os.ReadFile(filePath)
if err != nil {
return err
}
err = yaml.Unmarshal(yamlFile, fileConfig)
if err != nil {
return err
}
} else if fileExtension == ".toml" {
tomlFile, err := os.ReadFile(filePath)
if err != nil {
return err
}
err = toml.Unmarshal(tomlFile, &fileConfig)
if err != nil {
return err
}
} else {
return errors.New("config files only accepted are .yaml and .toml")
}
// sets global flags to value in yaml/toml file
for key, value := range fileConfig {
if !ctx.IsSet(key) {
if reflect.ValueOf(value).Kind() == reflect.Slice {
sliceInterface := value.([]interface{})
s := make([]string, len(sliceInterface))
for i, v := range sliceInterface {
s[i] = fmt.Sprintf("%v", v)
}
err := ctx.Set(key, strings.Join(s, ","))
if err != nil {
return fmt.Errorf("failed setting %s flag with values=%s error=%s", key, s, err)
}
} else {
err := ctx.Set(key, fmt.Sprintf("%v", value))
if err != nil {
return fmt.Errorf("failed setting %s flag with value=%v error=%s", key, value, err)
}
}
}
}
return nil
}

View File

@ -155,8 +155,6 @@ var DefaultFlags = []cli.Flag{
&utils.EthStatsURLFlag,
&utils.OverrideCancunFlag,
&utils.ConfigFlag,
&utils.LightClientDiscoveryAddrFlag,
&utils.LightClientDiscoveryPortFlag,
&utils.LightClientDiscoveryTCPPortFlag,