From 14d492827a14d65fef8a7a11c02f5fbd1c09994b Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 7 May 2024 17:18:47 +0200 Subject: [PATCH 1/5] make eth node log level configurable via TOML --- config/private_ethereum_network.go | 13 ++++ config/tomls/default_ethereum_env.toml | 1 + docker/test_env/besu_eth1.go | 2 +- docker/test_env/besu_eth2.go | 2 +- docker/test_env/env_component.go | 9 +++ docker/test_env/erigon_eth1.go | 4 +- docker/test_env/erigon_eth2.go | 16 ++++- docker/test_env/ethereum_env.go | 14 +++-- docker/test_env/ethereum_env_test.go | 85 ++++++++++++++++++++++++++ docker/test_env/geth_base.go | 19 ++++++ docker/test_env/geth_eth2.go | 9 ++- docker/test_env/nethermind_eth1.go | 1 + docker/test_env/nethermind_eth2.go | 1 + utils/templates/geth.go | 49 --------------- 14 files changed, 164 insertions(+), 61 deletions(-) diff --git a/config/private_ethereum_network.go b/config/private_ethereum_network.go index f9d092b1a..98e1e741c 100644 --- a/config/private_ethereum_network.go +++ b/config/private_ethereum_network.go @@ -4,6 +4,7 @@ import ( _ "embed" "errors" "fmt" + "strings" "time" "github.com/pelletier/go-toml/v2" @@ -17,6 +18,7 @@ import ( var ( ErrMissingEthereumVersion = errors.New("ethereum version is required") ErrMissingExecutionLayer = errors.New("execution layer is required") + DefaultNodeLogLevel = "info" ) type EthereumNetworkConfig struct { @@ -31,6 +33,7 @@ type EthereumNetworkConfig struct { ValKeysDir *string `toml:"val_keys_dir"` EthereumChainConfig *EthereumChainConfig `toml:"EthereumChainConfig"` CustomDockerImages map[ContainerType]string `toml:"CustomDockerImages"` + NodeLogLevel *string `toml:"node_log_level,omitempty"` } func (en *EthereumNetworkConfig) Validate() error { @@ -74,6 +77,16 @@ func (en *EthereumNetworkConfig) Validate() error { en.ConsensusLayer = nil } + if en.NodeLogLevel == nil { + en.NodeLogLevel = &DefaultNodeLogLevel + } + + switch strings.ToLower(*en.NodeLogLevel) { + case "trace", "debug", "info", "warn", "error": + default: + return fmt.Errorf("invalid node log level: %s", *en.NodeLogLevel) + } + if en.EthereumChainConfig == nil { return errors.New("ethereum chain config is required") } diff --git a/config/tomls/default_ethereum_env.toml b/config/tomls/default_ethereum_env.toml index f9414ba81..c768749dc 100644 --- a/config/tomls/default_ethereum_env.toml +++ b/config/tomls/default_ethereum_env.toml @@ -3,6 +3,7 @@ ethereum_version="eth2" consensus_layer="prysm" execution_layer="geth" wait_for_finalization=false +node_log_level="info" [PrivateEthereumNetwork.EthereumChainConfig] seconds_per_slot=12 diff --git a/docker/test_env/besu_eth1.go b/docker/test_env/besu_eth1.go index bf5a8cd2e..3e4e33158 100644 --- a/docker/test_env/besu_eth1.go +++ b/docker/test_env/besu_eth1.go @@ -81,7 +81,7 @@ func (g *Besu) getEth1ContainerRequest() (*tc.ContainerRequest, error) { "--miner-enabled=true", "--miner-coinbase", RootFundingAddr, fmt.Sprintf("--network-id=%d", g.chainConfig.ChainID), - "--logging=DEBUG", + fmt.Sprintf("--logging=%s", strings.ToUpper(g.LogLevel)), }, Files: []tc.ContainerFile{ { diff --git a/docker/test_env/besu_eth2.go b/docker/test_env/besu_eth2.go index be24d1e88..270f79986 100644 --- a/docker/test_env/besu_eth2.go +++ b/docker/test_env/besu_eth2.go @@ -80,7 +80,7 @@ func (g *Besu) getEth2ContainerRequest() (*tc.ContainerRequest, error) { fmt.Sprintf("--engine-rpc-port=%s", ETH2_EXECUTION_PORT), "--sync-mode=FULL", "--data-storage-format=BONSAI", - // "--logging=DEBUG", + fmt.Sprintf("--logging=%s", strings.ToUpper(g.LogLevel)), "--rpc-tx-feecap=0", }, Env: map[string]string{ diff --git a/docker/test_env/env_component.go b/docker/test_env/env_component.go index 614459ea3..e40a2d505 100644 --- a/docker/test_env/env_component.go +++ b/docker/test_env/env_component.go @@ -30,6 +30,7 @@ type EnvComponent struct { PostStartsHooks []tc.ContainerHook `json:"-"` PostStopsHooks []tc.ContainerHook `json:"-"` PreTerminatesHooks []tc.ContainerHook `json:"-"` + LogLevel string `json:"-"` } type EnvComponentOption = func(c *EnvComponent) @@ -52,6 +53,14 @@ func WithContainerImageWithVersion(imageWithVersion string) EnvComponentOption { } } +func WithLogLevel(logLevel string) EnvComponentOption { + return func(c *EnvComponent) { + if logLevel != "" { + c.LogLevel = logLevel + } + } +} + func WithLogStream(ls *logstream.LogStream) EnvComponentOption { return func(c *EnvComponent) { c.LogStream = ls diff --git a/docker/test_env/erigon_eth1.go b/docker/test_env/erigon_eth1.go index 176c8c21d..9310c1a22 100644 --- a/docker/test_env/erigon_eth1.go +++ b/docker/test_env/erigon_eth1.go @@ -166,16 +166,18 @@ func (g *Erigon) buildPowInitScript(minerAddr string) (string, error) { echo "Starting Erigon..." erigon --http --http.api=eth,erigon,engine,web3,net,debug,trace,txpool,admin --http.addr=0.0.0.0 --http.corsdomain=* --http.vhosts=* --http.port={{.HttpPort}} --ws \ - --allow-insecure-unlock --nodiscover --networkid={{.ChainID}} --mine --miner.etherbase={{.MinerAddr}} --fakepow` + --allow-insecure-unlock --nodiscover --networkid={{.ChainID}} --mine --miner.etherbase={{.MinerAddr}} --fakepow --verbosity={{.LogLevel}}` data := struct { HttpPort string ChainID int MinerAddr string + LogLevel string }{ HttpPort: DEFAULT_EVM_NODE_HTTP_PORT, ChainID: g.chainConfig.ChainID, MinerAddr: minerAddr, + LogLevel: g.LogLevel, } t, err := template.New("init").Parse(initTemplate) diff --git a/docker/test_env/erigon_eth2.go b/docker/test_env/erigon_eth2.go index 388f04dd0..0badb8a68 100644 --- a/docker/test_env/erigon_eth2.go +++ b/docker/test_env/erigon_eth2.go @@ -112,6 +112,7 @@ func (g *Erigon) buildPosInitScript() (string, error) { } initTemplate := `#!/bin/bash + echo "BAM!" echo "Copied genesis file to {{.ExecutionDir}}" mkdir -p {{.ExecutionDir}} cp {{.GeneratedDataDir}}/genesis.json {{.ExecutionDir}}/genesis.json @@ -124,9 +125,14 @@ func (g *Erigon) buildPosInitScript() (string, error) { fi echo "Starting Erigon..." - erigon --http --http.api=eth,erigon,engine,web3,net,debug,trace,txpool,admin --http.addr=0.0.0.0 --http.corsdomain=* \ - --http.vhosts=* --http.port={{.HttpPort}} --ws --authrpc.vhosts=* --authrpc.addr=0.0.0.0 --authrpc.jwtsecret={{.JwtFileLocation}} \ - --datadir={{.ExecutionDir}} {{.ExtraExecutionFlags}} --allow-insecure-unlock --nodiscover --networkid={{.ChainID}}` + command="erigon --http --http.api=eth,erigon,engine,web3,net,debug,trace,txpool,admin --http.addr=0.0.0.0 --http.corsdomain=* --http.vhosts=* --http.port={{.HttpPort}} --ws --authrpc.vhosts=* --authrpc.addr=0.0.0.0 --authrpc.jwtsecret={{.JwtFileLocation}} --datadir={{.ExecutionDir}} {{.ExtraExecutionFlags}} --allow-insecure-unlock --nodiscover --networkid={{.ChainID}} --log.console.verbosity={{.LogLevel}} --verbosity={{.LogLevel}}" + + if [ "{{.LogLevel}}" == "trace" ]; then + echo "Enabling trace logging for senders: {{.SendersToTrace}}" + command="$command --txpool.trace.senders=\"{{.SendersToTrace}}\"" + fi + + eval $command` data := struct { HttpPort string @@ -135,6 +141,8 @@ func (g *Erigon) buildPosInitScript() (string, error) { JwtFileLocation string ExecutionDir string ExtraExecutionFlags string + SendersToTrace string + LogLevel string }{ HttpPort: DEFAULT_EVM_NODE_HTTP_PORT, ChainID: g.chainConfig.ChainID, @@ -142,6 +150,8 @@ func (g *Erigon) buildPosInitScript() (string, error) { JwtFileLocation: JWT_SECRET_FILE_LOCATION_INSIDE_CONTAINER, ExecutionDir: "/home/erigon/execution-data", ExtraExecutionFlags: extraExecutionFlags, + SendersToTrace: strings.Join(g.chainConfig.AddressesToFund, ","), + LogLevel: g.LogLevel, } t, err := template.New("init").Parse(initTemplate) diff --git a/docker/test_env/ethereum_env.go b/docker/test_env/ethereum_env.go index e419d9eb7..84ef9d2d3 100644 --- a/docker/test_env/ethereum_env.go +++ b/docker/test_env/ethereum_env.go @@ -3,6 +3,7 @@ package test_env import ( "fmt" "os" + "strings" "testing" "time" @@ -20,14 +21,12 @@ import ( ) const ( - CONFIG_ENV_VAR_NAME = "PRIVATE_ETHEREUM_NETWORK_CONFIG_PATH" - EXEC_CLIENT_ENV_VAR_NAME = "ETH2_EL_CLIENT" + CONFIG_ENV_VAR_NAME = "PRIVATE_ETHEREUM_NETWORK_CONFIG_PATH" ) var ( - ErrMissingConsensusLayer = errors.New("consensus layer is required for PoS") - ErrConsensusLayerNotAllowed = errors.New("consensus layer is not allowed for PoW") - ErrTestConfigNotSaved = errors.New("could not save test env config") + ErrMissingConsensusLayer = errors.New("consensus layer is required for PoS") + ErrTestConfigNotSaved = errors.New("could not save test env config") ) var MsgMismatchedExecutionClient = "you provided a custom docker image for %s execution client, but explicitly set a execution client to %s. Make them match or remove one or the other" @@ -711,6 +710,11 @@ func (en *EthereumNetwork) getExecutionLayerEnvComponentOpts() []EnvComponentOpt opts = append(opts, en.getImageOverride(config.ContainerType_ExecutionLayer)...) opts = append(opts, en.setExistingContainerName(config.ContainerType_ExecutionLayer)) opts = append(opts, WithLogStream(en.ls)) + + if en.NodeLogLevel != nil && *en.NodeLogLevel != "" { + opts = append(opts, WithLogLevel(strings.ToLower(*en.NodeLogLevel))) + } + return opts } diff --git a/docker/test_env/ethereum_env_test.go b/docker/test_env/ethereum_env_test.go index 0b1d9a8ed..5d38925af 100644 --- a/docker/test_env/ethereum_env_test.go +++ b/docker/test_env/ethereum_env_test.go @@ -202,6 +202,91 @@ func TestEthEnvCustomDockerImagesFromToml(t *testing.T) { require.Contains(t, fmt.Sprintf(MsgUnsupportedDockerImage, "i-dont-exist"), err.Error(), "Error message is not correct") } +func TestEthNoLogLevelDefaultsToInfo(t *testing.T) { + t.Parallel() + tomlStr := ` + [EthereumNetwork] + consensus_type="pos" + consensus_layer="prysm" + execution_layer="geth" + wait_for_finalization=false + + [EthereumNetwork.EthereumChainConfig] + seconds_per_slot=12 + slots_per_epoch=2 + genesis_delay=20 + validator_count=8 + chain_id=1234 + addresses_to_fund=["0x742d35Cc6634C0532925a3b844Bc454e4438f44e", "0x742d35Cc6634C0532925a3b844Bc454e4438f44f"] + ` + + tomlCfg, err := readEthereumNetworkConfig(tomlStr) + require.NoError(t, err, "Couldn't read config") + + tomlCfg.EthereumChainConfig.GenerateGenesisTimestamp() + + err = tomlCfg.Validate() + require.NoError(t, err, "Failed to validate correct TOML config") + require.Equal(t, config.DefaultNodeLogLevel, *tomlCfg.NodeLogLevel, "Incorrect default log level") +} + +func TestEthLogLevelTrace(t *testing.T) { + t.Parallel() + tomlStr := ` + [EthereumNetwork] + consensus_type="pos" + consensus_layer="prysm" + execution_layer="geth" + wait_for_finalization=false + node_log_level="trace" + + [EthereumNetwork.EthereumChainConfig] + seconds_per_slot=12 + slots_per_epoch=2 + genesis_delay=20 + validator_count=8 + chain_id=1234 + addresses_to_fund=["0x742d35Cc6634C0532925a3b844Bc454e4438f44e", "0x742d35Cc6634C0532925a3b844Bc454e4438f44f"] + ` + + tomlCfg, err := readEthereumNetworkConfig(tomlStr) + require.NoError(t, err, "Couldn't read config") + + tomlCfg.EthereumChainConfig.GenerateGenesisTimestamp() + + err = tomlCfg.Validate() + require.NoError(t, err, "Failed to validate correct TOML config") + require.Equal(t, "trace", *tomlCfg.NodeLogLevel, "Incorrect default log level") +} + +func TestEthInvalidLogLevel(t *testing.T) { + t.Parallel() + tomlStr := ` + [EthereumNetwork] + consensus_type="pos" + consensus_layer="prysm" + execution_layer="geth" + wait_for_finalization=false + node_log_level="random" + + [EthereumNetwork.EthereumChainConfig] + seconds_per_slot=12 + slots_per_epoch=2 + genesis_delay=20 + validator_count=8 + chain_id=1234 + addresses_to_fund=["0x742d35Cc6634C0532925a3b844Bc454e4438f44e", "0x742d35Cc6634C0532925a3b844Bc454e4438f44f"] + ` + + tomlCfg, err := readEthereumNetworkConfig(tomlStr) + require.NoError(t, err, "Couldn't read config") + + tomlCfg.EthereumChainConfig.GenerateGenesisTimestamp() + + err = tomlCfg.Validate() + require.Error(t, err, "Successfully validated incorrect TOML config") +} + type ethereumNetworkWrapper struct { EthereumNetwork *config.EthereumNetworkConfig `toml:"EthereumNetwork"` } diff --git a/docker/test_env/geth_base.go b/docker/test_env/geth_base.go index 3e00e27ed..f2b215797 100644 --- a/docker/test_env/geth_base.go +++ b/docker/test_env/geth_base.go @@ -252,3 +252,22 @@ func (g *Geth) getWebsocketEnabledMessage() (string, error) { return "WebSocket enabled", nil } + +func (g *Geth) logLevelToVerbosity() (int, error) { + switch g.LogLevel { + case "trace": + return 5, nil + case "debug": + return 4, nil + case "info": + return 3, nil + case "warn": + return 2, nil + case "error": + return 1, nil + case "silent": + return 0, nil + default: + return -1, fmt.Errorf("unknown log level: %s", g.LogLevel) + } +} diff --git a/docker/test_env/geth_eth2.go b/docker/test_env/geth_eth2.go index 6b7519640..f8d80448e 100644 --- a/docker/test_env/geth_eth2.go +++ b/docker/test_env/geth_eth2.go @@ -131,7 +131,12 @@ func (g *Geth) buildEth2dInitScript() (string, error) { --authrpc.addr=0.0.0.0 --authrpc.jwtsecret={{.JwtFileLocation}} --datadir={{.ExecutionDir}} \ --rpc.allow-unprotected-txs --rpc.txfeecap=0 --allow-insecure-unlock \ --password={{.PasswordFileLocation}} --nodiscover --syncmode=full --networkid={{.ChainID}} \ - --graphql --graphql.corsdomain=* --unlock=0x123463a4b065722e99115d6c222f267d9cabb524` + --graphql --graphql.corsdomain=* --unlock=0x123463a4b065722e99115d6c222f267d9cabb524 --verbosity={{.Verbosity}}` + + verbosity, err := g.logLevelToVerbosity() + if err != nil { + return "", err + } data := struct { HttpPort string @@ -142,6 +147,7 @@ func (g *Geth) buildEth2dInitScript() (string, error) { PasswordFileLocation string KeystoreDirLocation string ExecutionDir string + Verbosity int }{ HttpPort: DEFAULT_EVM_NODE_HTTP_PORT, WsPort: DEFAULT_EVM_NODE_WS_PORT, @@ -151,6 +157,7 @@ func (g *Geth) buildEth2dInitScript() (string, error) { PasswordFileLocation: ACCOUNT_PASSWORD_FILE_INSIDE_CONTAINER, KeystoreDirLocation: KEYSTORE_DIR_LOCATION_INSIDE_CONTAINER, ExecutionDir: "/execution-data", + Verbosity: verbosity, } t, err := template.New("init").Parse(initTemplate) diff --git a/docker/test_env/nethermind_eth1.go b/docker/test_env/nethermind_eth1.go index 69beca9a2..7dc188cf0 100644 --- a/docker/test_env/nethermind_eth1.go +++ b/docker/test_env/nethermind_eth1.go @@ -137,6 +137,7 @@ func (g *Nethermind) getEth1ContainerRequest() (*tc.ContainerRequest, error) { "--Mining.Enabled=true", "--Init.PeerManagerEnabled=false", "--HealthChecks.Enabled=true", // default slug /health + fmt.Sprintf("--log=%s", strings.ToUpper(g.LogLevel)), }, Files: []tc.ContainerFile{ { diff --git a/docker/test_env/nethermind_eth2.go b/docker/test_env/nethermind_eth2.go index aaf58960e..ee3b99fbb 100644 --- a/docker/test_env/nethermind_eth2.go +++ b/docker/test_env/nethermind_eth2.go @@ -92,6 +92,7 @@ func (g *Nethermind) getEth2ContainerRequest() (*tc.ContainerRequest, error) { "--Network.MaxActivePeers=0", "--Network.OnlyStaticPeers=true", "--HealthChecks.Enabled=true", // default slug /health + fmt.Sprintf("--log=%s", strings.ToUpper(g.LogLevel)), }, Files: []tc.ContainerFile{ { diff --git a/utils/templates/geth.go b/utils/templates/geth.go index 857b7457d..ed6776a88 100644 --- a/utils/templates/geth.go +++ b/utils/templates/geth.go @@ -18,32 +18,6 @@ fi geth "$@" ` -var BootnodeScript = ` -#!/bin/bash - -echo "Starting bootnode" -bootnode --genkey=/root/.ethereum/node.key -echo "Bootnode key generated" - -echo "Bootnode address written to file" -bootnode -writeaddress --nodekey=/root/.ethereum/node.key > /root/.ethereum/bootnodes -cat /root/.ethereum/bootnodes - -echo "Starting Bootnode" -bootnode --nodekey=/root/.ethereum/node.key --verbosity=6 --addr :30301 -` - -var InitNonDevGethScript = ` -#!/bin/bash - -echo "Starting geth" -geth --datadir=/root/.ethereum init /root/genesis.json - -bootnode_enode=$(cat /root/.ethereum/keystore/password.txt) -echo "Bootnode enode: $bootnode_enode" -geth "$@" -` - var GenesisJson = ` { "config": { @@ -90,29 +64,6 @@ var funcMap = template.FuncMap{ }, } -func BuildGenesisJsonForNonDevChain(chainId string, accountAddr []string, extraData string) (string, error) { - data := struct { - AccountAddr []string - ChainId string - ExtraData string - }{ - AccountAddr: accountAddr, - ChainId: chainId, - ExtraData: extraData, - } - - t, err := template.New("genesis-json").Funcs(funcMap).Parse(GenesisJson) - if err != nil { - fmt.Println("Error parsing template:", err) - os.Exit(1) - } - - var buf bytes.Buffer - err = t.Execute(&buf, data) - - return buf.String(), err -} - type GenesisConsensus = string const ( From 6473ed9ab60f155a11e099a6a18dab897e6930cf Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 7 May 2024 17:43:20 +0200 Subject: [PATCH 2/5] validate network config before returning it from the builder --- docker/test_env/ethereum_env.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docker/test_env/ethereum_env.go b/docker/test_env/ethereum_env.go index 84ef9d2d3..9e00ff7f0 100644 --- a/docker/test_env/ethereum_env.go +++ b/docker/test_env/ethereum_env.go @@ -188,7 +188,9 @@ func (b *EthereumNetworkBuilder) Build() (EthereumNetwork, error) { return EthereumNetwork{}, err } - return b.buildNetworkConfig(), nil + network := b.buildNetworkConfig() + + return network, network.Validate() } func (b *EthereumNetworkBuilder) importExistingConfig() bool { From 204dccc95b8d1c6d62a1861b7069481f0bdc6029 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Tue, 7 May 2024 18:40:20 +0200 Subject: [PATCH 3/5] fix log level flag for eth1 Erigon --- docker/test_env/erigon_eth1.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/test_env/erigon_eth1.go b/docker/test_env/erigon_eth1.go index 9310c1a22..de956ab8f 100644 --- a/docker/test_env/erigon_eth1.go +++ b/docker/test_env/erigon_eth1.go @@ -166,7 +166,7 @@ func (g *Erigon) buildPowInitScript(minerAddr string) (string, error) { echo "Starting Erigon..." erigon --http --http.api=eth,erigon,engine,web3,net,debug,trace,txpool,admin --http.addr=0.0.0.0 --http.corsdomain=* --http.vhosts=* --http.port={{.HttpPort}} --ws \ - --allow-insecure-unlock --nodiscover --networkid={{.ChainID}} --mine --miner.etherbase={{.MinerAddr}} --fakepow --verbosity={{.LogLevel}}` + --allow-insecure-unlock --nodiscover --networkid={{.ChainID}} --mine --miner.etherbase={{.MinerAddr}} --fakepow --log.console.verbosity={{.LogLevel}}` data := struct { HttpPort string From bea57e1d76a75166e14a72830e6e9c519663d06c Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Wed, 8 May 2024 11:09:44 +0200 Subject: [PATCH 4/5] a tad more debug options for Nethermind Eth2 --- docker/test_env/ethereum_env.go | 15 +++++++- docker/test_env/nethermind_eth2.go | 58 +++++++++++++++++------------- 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/docker/test_env/ethereum_env.go b/docker/test_env/ethereum_env.go index 9e00ff7f0..2e7396cdf 100644 --- a/docker/test_env/ethereum_env.go +++ b/docker/test_env/ethereum_env.go @@ -44,6 +44,7 @@ type EthereumNetworkBuilder struct { addressesToFund []string waitForFinalization bool existingFromEnvVar bool + nodeLogLevel string } func NewEthereumNetworkBuilder() EthereumNetworkBuilder { @@ -94,6 +95,11 @@ func (b *EthereumNetworkBuilder) WithDockerNetworks(networks []string) *Ethereum return b } +func (b *EthereumNetworkBuilder) WithNodeLogLevel(nodeLogLevel string) *EthereumNetworkBuilder { + b.nodeLogLevel = nodeLogLevel + return b +} + func (b *EthereumNetworkBuilder) WithExistingConfig(config config.EthereumNetworkConfig) *EthereumNetworkBuilder { b.existingConfig = &config return b @@ -144,6 +150,7 @@ func (b *EthereumNetworkBuilder) buildNetworkConfig() EthereumNetwork { n.WaitForFinalization = &b.waitForFinalization n.EthereumNetworkConfig.EthereumChainConfig = b.ethereumChainConfig n.EthereumNetworkConfig.CustomDockerImages = b.customDockerImages + n.NodeLogLevel = &b.nodeLogLevel n.t = b.t n.ls = b.ls @@ -216,6 +223,12 @@ func (b *EthereumNetworkBuilder) importExistingConfig() bool { b.ethereumChainConfig = b.existingConfig.EthereumChainConfig b.customDockerImages = b.existingConfig.CustomDockerImages + if b.existingConfig.NodeLogLevel != nil { + b.nodeLogLevel = *b.existingConfig.NodeLogLevel + } else { + b.nodeLogLevel = config.DefaultNodeLogLevel + } + return true } @@ -417,7 +430,7 @@ func (en *EthereumNetwork) startEth2() (blockchain.EVMNetwork, RpcProvider, erro case config.ExecutionLayer_Geth: client, clientErr = NewGethEth2(dockerNetworks, en.EthereumChainConfig, generatedDataHostDir, config.ConsensusLayer_Prysm, opts...) case config.ExecutionLayer_Nethermind: - client, clientErr = NewNethermindEth2(dockerNetworks, generatedDataHostDir, config.ConsensusLayer_Prysm, opts...) + client, clientErr = NewNethermindEth2(dockerNetworks, en.EthereumChainConfig, generatedDataHostDir, config.ConsensusLayer_Prysm, opts...) case config.ExecutionLayer_Erigon: client, clientErr = NewErigonEth2(dockerNetworks, en.EthereumChainConfig, generatedDataHostDir, config.ConsensusLayer_Prysm, opts...) case config.ExecutionLayer_Besu: diff --git a/docker/test_env/nethermind_eth2.go b/docker/test_env/nethermind_eth2.go index ee3b99fbb..bb13005a9 100644 --- a/docker/test_env/nethermind_eth2.go +++ b/docker/test_env/nethermind_eth2.go @@ -18,7 +18,7 @@ import ( ) // NewNethermindEth2 starts a new Nethermin Eth2 node running in Docker -func NewNethermindEth2(networks []string, generatedDataHostDir string, consensusLayer config.ConsensusLayer, opts ...EnvComponentOption) (*Nethermind, error) { +func NewNethermindEth2(networks []string, chainConfig *config.EthereumChainConfig, generatedDataHostDir string, consensusLayer config.ConsensusLayer, opts ...EnvComponentOption) (*Nethermind, error) { parts := strings.Split(defaultNethermindEth2Image, ":") g := &Nethermind{ EnvComponent: EnvComponent{ @@ -28,6 +28,7 @@ func NewNethermindEth2(networks []string, generatedDataHostDir string, consensus ContainerVersion: parts[1], }, generatedDataHostDir: generatedDataHostDir, + chainConfig: chainConfig, consensusLayer: consensusLayer, l: logging.GetTestLogger(nil), ethereumVersion: config.EthereumVersion_Eth2, @@ -59,6 +60,37 @@ func (g *Nethermind) getEth2ContainerRequest() (*tc.ContainerRequest, error) { return nil, err } + command := []string{ + "--datadir=/nethermind", + "--config=/none.cfg", + fmt.Sprintf("--Init.ChainSpecPath=%s/chainspec.json", GENERATED_DATA_DIR_INSIDE_CONTAINER), + "--Init.DiscoveryEnabled=false", + "--Init.WebSocketsEnabled=true", + fmt.Sprintf("--JsonRpc.WebSocketsPort=%s", DEFAULT_EVM_NODE_WS_PORT), + fmt.Sprintf("--Blocks.SecondsPerSlot=%d", g.chainConfig.SecondsPerSlot), + "--JsonRpc.Enabled=true", + "--JsonRpc.EnabledModules=net,eth,consensus,subscribe,web3,admin,txpool,debug,trace", + "--JsonRpc.Host=0.0.0.0", + fmt.Sprintf("--JsonRpc.Port=%s", DEFAULT_EVM_NODE_HTTP_PORT), + "--JsonRpc.EngineHost=0.0.0.0", + "--JsonRpc.EnginePort=" + ETH2_EXECUTION_PORT, + fmt.Sprintf("--JsonRpc.JwtSecretFile=%s", JWT_SECRET_FILE_LOCATION_INSIDE_CONTAINER), + fmt.Sprintf("--KeyStore.KeyStoreDirectory=%s", KEYSTORE_DIR_LOCATION_INSIDE_CONTAINER), + "--KeyStore.BlockAuthorAccount=0x123463a4b065722e99115d6c222f267d9cabb524", + "--KeyStore.UnlockAccounts=0x123463a4b065722e99115d6c222f267d9cabb524", + fmt.Sprintf("--KeyStore.PasswordFiles=%s", ACCOUNT_PASSWORD_FILE_INSIDE_CONTAINER), + "--Network.MaxActivePeers=0", + "--Network.OnlyStaticPeers=true", + "--HealthChecks.Enabled=true", // default slug /health + fmt.Sprintf("--log=%s", strings.ToUpper(g.LogLevel)), + } + + if g.LogLevel == "trace" { + command = append(command, "--TraceStore.Enabled=true") + command = append(command, "--Network.DiagTracerEnabled=true") + command = append(command, "--TxPool.ReportMinutes=1") + } + return &tc.ContainerRequest{ Name: g.ContainerName, Image: g.GetImageWithVersion(), @@ -71,29 +103,7 @@ func (g *Nethermind) getEth2ContainerRequest() (*tc.ContainerRequest, error) { WithStartupTimeout(120 * time.Second). WithPollInterval(1 * time.Second), ), - Cmd: []string{ - "--datadir=/nethermind", - "--config=/none.cfg", - fmt.Sprintf("--Init.ChainSpecPath=%s/chainspec.json", GENERATED_DATA_DIR_INSIDE_CONTAINER), - "--Init.DiscoveryEnabled=false", - "--Init.WebSocketsEnabled=true", - fmt.Sprintf("--JsonRpc.WebSocketsPort=%s", DEFAULT_EVM_NODE_WS_PORT), - "--JsonRpc.Enabled=true", - "--JsonRpc.EnabledModules=net,eth,consensus,subscribe,web3,admin,txpool,debug,trace", - "--JsonRpc.Host=0.0.0.0", - fmt.Sprintf("--JsonRpc.Port=%s", DEFAULT_EVM_NODE_HTTP_PORT), - "--JsonRpc.EngineHost=0.0.0.0", - "--JsonRpc.EnginePort=" + ETH2_EXECUTION_PORT, - fmt.Sprintf("--JsonRpc.JwtSecretFile=%s", JWT_SECRET_FILE_LOCATION_INSIDE_CONTAINER), - fmt.Sprintf("--KeyStore.KeyStoreDirectory=%s", KEYSTORE_DIR_LOCATION_INSIDE_CONTAINER), - "--KeyStore.BlockAuthorAccount=0x123463a4b065722e99115d6c222f267d9cabb524", - "--KeyStore.UnlockAccounts=0x123463a4b065722e99115d6c222f267d9cabb524", - fmt.Sprintf("--KeyStore.PasswordFiles=%s", ACCOUNT_PASSWORD_FILE_INSIDE_CONTAINER), - "--Network.MaxActivePeers=0", - "--Network.OnlyStaticPeers=true", - "--HealthChecks.Enabled=true", // default slug /health - fmt.Sprintf("--log=%s", strings.ToUpper(g.LogLevel)), - }, + Cmd: command, Files: []tc.ContainerFile{ { HostFilePath: noneCfg.Name(), From 017cac4c88786235b87c5f64c5ddaf11bce6ed51 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Wed, 8 May 2024 11:32:58 +0200 Subject: [PATCH 5/5] autofill node log level --- docker/test_env/ethereum_env.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docker/test_env/ethereum_env.go b/docker/test_env/ethereum_env.go index 2e7396cdf..98561187b 100644 --- a/docker/test_env/ethereum_env.go +++ b/docker/test_env/ethereum_env.go @@ -323,6 +323,10 @@ func (b *EthereumNetworkBuilder) autoFill() error { b.ethereumVersion = config.EthereumVersion_Eth2 } + if b.nodeLogLevel == "" { + b.nodeLogLevel = config.DefaultNodeLogLevel + } + return nil }