Repository: ssvlabs/ssv
Pull request #2064: refactor: standarize env variable descriptions 
Author: login: kchojn
Created: 2025-03-07T08:44:06Z | Merged: 2025-03-19T10:27:47Z

> [!WARNING]
> Idk, but I think, it its possible to replace two envs: `HostAddress` and `HostDNS` with `Host`. They came from: `network/p2p/config.go`. It would be technically possible to combine them into a single Host variable, the system would need to detect whether the value is an IP address or a DNS name (`net.ParseIP()`). And it can be done in `configureAddrs` method. The question of backward compatibility remains? 


Configs:

- [x] GlobalConfig: cli/config/config.go
- [x] Config: network/p2p/config.go
- [x] ExecutionOptions: eth/executionclient/config.go (renamed -> `Options`)
- [x] Options: storage/basedb/storage.go
- [x] ControllerOptions: operator/validator/controller.go (cannot rename)
- [x] KeyStore/Options: cli/operator/node.go
- [x] Options: operator/node.go
- [x] BootnodeOptions: network/discovery/dv5_bootnode.go (cannot rename) 
- [x] Options: utils/boot_node/node.go
- [x] Options: protocol/v2/blockchain/beacon/client.go


## Changelog

### Added
- Added examples for complex configurations
- Added valid values in parentheses for enum-like options

### Changed
- [filename](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_170) in posix terminology means something else, we should use the correct name, lumberjack.Logger uses the wrong naming, so in `LogFileOptions` I changed `FileName` to `FilePath` (cli config had the correct name)
-  rename `ExecutionOptions` struct to `Options` for consistency and clarity (more consistent with go)
- Removed unnecessary phrases like "Defines", "Flag to", etc.
- Capitalized first words consistently
- Standardized terminology (e.g., "Maximum" instead of "Max", etc.)

### Fixed
- Correct typo in `PubsubValidateThrottle` field name to match the intended name for the environment variable and improve consistency (p2p/config.go)



Diff:
diff --git a/cli/bootnode/boot_node.go b/cli/bootnode/boot_node.go
index 5bcc72dbb5..66302db88b 100644
--- a/cli/bootnode/boot_node.go
+++ b/cli/bootnode/boot_node.go
@@ -42,7 +42,7 @@ var StartBootNodeCmd = &cobra.Command{
 			cfg.LogLevelFormat,
 			cfg.LogFormat,
 			&logging.LogFileOptions{
-				FileName:   cfg.LogFilePath,
+				FilePath:   cfg.LogFilePath,
 				MaxSize:    cfg.LogFileSize,
 				MaxBackups: cfg.LogFileBackups,
 			},
diff --git a/cli/config/config.go b/cli/config/config.go
index 0d074c9361..a550d2ee3f 100644
--- a/cli/config/config.go
+++ b/cli/config/config.go
@@ -13,12 +13,12 @@ type Args struct {
 
 // GlobalConfig expose available global config for cli command
 type GlobalConfig struct {
-	LogLevel       string `yaml:"LogLevel" env:"LOG_LEVEL" env-default:"info" env-description:"Defines logger's log level'"`
-	LogFormat      string `yaml:"LogFormat" env:"LOG_FORMAT" env-default:"console" env-description:"Defines logger's encoding, valid values are 'json' (default) and 'console''"`
-	LogLevelFormat string `yaml:"LogLevelFormat" env:"LOG_LEVEL_FORMAT" env-default:"capitalColor" env-description:"Defines logger's level format, valid values are 'capitalColor' (default), 'capital' or 'lowercase''"`
-	LogFilePath    string `yaml:"LogFilePath" env:"LOG_FILE_PATH" env-default:"./data/debug.log" env-description:"Defines a file path to write logs into"`
-	LogFileSize    int    `yaml:"LogFileSize" env:"LOG_FILE_SIZE" env-default:"500" env-description:"Defines a file size in megabytes to rotate logs"`
-	LogFileBackups int    `yaml:"LogFileBackups" env:"LOG_FILE_BACKUPS" env-default:"3" env-description:"Defines a number of backups to keep when rotating logs"`
+	LogLevel       string `yaml:"LogLevel" env:"LOG_LEVEL" env-default:"info" env-description:"Log level (debug, info, warn, error)"`
+	LogFormat      string `yaml:"LogFormat" env:"LOG_FORMAT" env-default:"console" env-description:"Log encoding format (json, console)"`
+	LogLevelFormat string `yaml:"LogLevelFormat" env:"LOG_LEVEL_FORMAT" env-default:"capitalColor" env-description:"Log level format (capitalColor, capital, lowercase)"`
+	LogFilePath    string `yaml:"LogFilePath" env:"LOG_FILE_PATH" env-default:"./data/debug.log" env-description:"File path to write logs to"`
+	LogFileSize    int    `yaml:"LogFileSize" env:"LOG_FILE_SIZE" env-default:"500" env-description:"Maximum log file size in megabytes before rotation"`
+	LogFileBackups int    `yaml:"LogFileBackups" env:"LOG_FILE_BACKUPS" env-default:"3" env-description:"Number of rotated log files to keep"`
 }
 
 // ProcessArgs processes and handles CLI arguments
diff --git a/cli/operator/node.go b/cli/operator/node.go
index efd50c8dc9..1bbf06398d 100644
--- a/cli/operator/node.go
+++ b/cli/operator/node.go
@@ -72,28 +72,28 @@ import (
 )
 
 type KeyStore struct {
-	PrivateKeyFile string `yaml:"PrivateKeyFile" env:"PRIVATE_KEY_FILE" env-description:"Operator private key file"`
-	PasswordFile   string `yaml:"PasswordFile" env:"PASSWORD_FILE" env-description:"Password for operator private key file decryption"`
+	PrivateKeyFile string `yaml:"PrivateKeyFile" env:"PRIVATE_KEY_FILE" env-description:"Path to operator private key file"`
+	PasswordFile   string `yaml:"PasswordFile" env:"PASSWORD_FILE" env-description:"Path to password file for private key decryption"`
 }
 
 type config struct {
 	global_config.GlobalConfig   `yaml:"global"`
-	DBOptions                    basedb.Options                   `yaml:"db"`
-	SSVOptions                   operator.Options                 `yaml:"ssv"`
-	ExecutionClient              executionclient.ExecutionOptions `yaml:"eth1"` // TODO: execution_client in yaml
-	ConsensusClient              beaconprotocol.Options           `yaml:"eth2"` // TODO: consensus_client in yaml
-	P2pNetworkConfig             p2pv1.Config                     `yaml:"p2p"`
-	KeyStore                     KeyStore                         `yaml:"KeyStore"`
-	Graffiti                     string                           `yaml:"Graffiti" env:"GRAFFITI" env-description:"Custom graffiti for block proposals." env-default:"ssv.network" `
-	OperatorPrivateKey           string                           `yaml:"OperatorPrivateKey" env:"OPERATOR_KEY" env-description:"Operator private key, used to decrypt contract events"`
-	MetricsAPIPort               int                              `yaml:"MetricsAPIPort" env:"METRICS_API_PORT" env-description:"Port to listen on for the metrics API."`
-	EnableProfile                bool                             `yaml:"EnableProfile" env:"ENABLE_PROFILE" env-description:"flag that indicates whether go profiling tools are enabled"`
-	NetworkPrivateKey            string                           `yaml:"NetworkPrivateKey" env:"NETWORK_PRIVATE_KEY" env-description:"private key for network identity"`
-	WsAPIPort                    int                              `yaml:"WebSocketAPIPort" env:"WS_API_PORT" env-description:"Port to listen on for the websocket API."`
-	WithPing                     bool                             `yaml:"WithPing" env:"WITH_PING" env-description:"Whether to send websocket ping messages'"`
-	SSVAPIPort                   int                              `yaml:"SSVAPIPort" env:"SSV_API_PORT" env-description:"Port to listen on for the SSV API."`
-	LocalEventsPath              string                           `yaml:"LocalEventsPath" env:"EVENTS_PATH" env-description:"path to local events"`
-	EnableDoppelgangerProtection bool                             `yaml:"EnableDoppelgangerProtection" env:"ENABLE_DOPPELGANGER_PROTECTION" env-description:"Flag to enable Doppelganger protection for validators."`
+	DBOptions                    basedb.Options          `yaml:"db"`
+	SSVOptions                   operator.Options        `yaml:"ssv"`
+	ExecutionClient              executionclient.Options `yaml:"eth1"` // TODO: execution_client in yaml
+	ConsensusClient              beaconprotocol.Options  `yaml:"eth2"` // TODO: consensus_client in yaml
+	P2pNetworkConfig             p2pv1.Config            `yaml:"p2p"`
+	KeyStore                     KeyStore                `yaml:"KeyStore"`
+	Graffiti                     string                  `yaml:"Graffiti" env:"GRAFFITI" env-description:"Custom graffiti for block proposals" env-default:"ssv.network" `
+	OperatorPrivateKey           string                  `yaml:"OperatorPrivateKey" env:"OPERATOR_KEY" env-description:"Operator private key for contract event decryption"`
+	MetricsAPIPort               int                     `yaml:"MetricsAPIPort" env:"METRICS_API_PORT" env-description:"Port for metrics API server"`
+	EnableProfile                bool                    `yaml:"EnableProfile" env:"ENABLE_PROFILE" env-description:"Enable Go profiling tools"`
+	NetworkPrivateKey            string                  `yaml:"NetworkPrivateKey" env:"NETWORK_PRIVATE_KEY" env-description:"Private key for P2P network identity"`
+	WsAPIPort                    int                     `yaml:"WebSocketAPIPort" env:"WS_API_PORT" env-description:"Port for WebSocket API server"`
+	WithPing                     bool                    `yaml:"WithPing" env:"WITH_PING" env-description:"Enable WebSocket ping messages"`
+	SSVAPIPort                   int                     `yaml:"SSVAPIPort" env:"SSV_API_PORT" env-description:"Port for SSV API server"`
+	LocalEventsPath              string                  `yaml:"LocalEventsPath" env:"EVENTS_PATH" env-description:"Path to local events file"`
+	EnableDoppelgangerProtection bool                    `yaml:"EnableDoppelgangerProtection" env:"ENABLE_DOPPELGANGER_PROTECTION" env-description:"Enable doppelganger protection for validators"`
 }
 
 var cfg config
@@ -540,7 +540,7 @@ func setupGlobal() (*zap.Logger, error) {
 		cfg.LogLevelFormat,
 		cfg.LogFormat,
 		&logging.LogFileOptions{
-			FileName:   cfg.LogFilePath,
+			FilePath:   cfg.LogFilePath,
 			MaxSize:    cfg.LogFileSize,
 			MaxBackups: cfg.LogFileBackups,
 		},
diff --git a/eth/executionclient/config.go b/eth/executionclient/config.go
index ea99a89789..63221935c3 100644
--- a/eth/executionclient/config.go
+++ b/eth/executionclient/config.go
@@ -6,9 +6,9 @@ import (
 
 // TODO: rename eth1, consider combining with consensus client options
 
-// ExecutionOptions contains config configurations related to Ethereum execution client.
-type ExecutionOptions struct {
-	Addr                  string        `yaml:"ETH1Addr" env:"ETH_1_ADDR" env-required:"true" env-description:"Execution client WebSocket address. Supports multiple semicolon separated addresses. ex: ws://localhost:8546;ws://localhost:8547"`
-	ConnectionTimeout     time.Duration `yaml:"ETH1ConnectionTimeout" env:"ETH_1_CONNECTION_TIMEOUT" env-default:"10s" env-description:"Execution client connection timeout"`
-	SyncDistanceTolerance uint64        `yaml:"ETH1SyncDistanceTolerance" env:"ETH_1_SYNC_DISTANCE_TOLERANCE" env-default:"5" env-description:"The number of out-of-sync blocks we can tolerate"`
+// Options contains config configurations related to Ethereum execution client.
+type Options struct {
+	Addr                  string        `yaml:"ETH1Addr" env:"ETH_1_ADDR" env-required:"true" env-description:"Execution client WebSocket URL(s). Multiple clients are supported via semicolon-separated URLs (e.g. 'ws://localhost:8546;ws://localhost:8547')"`
+	ConnectionTimeout     time.Duration `yaml:"ETH1ConnectionTimeout" env:"ETH_1_CONNECTION_TIMEOUT" env-default:"10s" env-description:"Timeout for execution client connections"`
+	SyncDistanceTolerance uint64        `yaml:"ETH1SyncDistanceTolerance" env:"ETH_1_SYNC_DISTANCE_TOLERANCE" env-default:"5" env-description:"Maximum number of blocks behind head considered in-sync"`
 }
diff --git a/logging/global.go b/logging/global.go
index ccc9d23002..5542dae0de 100644
--- a/logging/global.go
+++ b/logging/global.go
@@ -98,14 +98,14 @@ func SetGlobalLogger(levelName string, levelEncoderName string, logFormat string
 }
 
 type LogFileOptions struct {
-	FileName   string
+	FilePath   string
 	MaxSize    int
 	MaxBackups int
 }
 
 func (o LogFileOptions) writer(options *LogFileOptions) io.Writer {
 	return &lumberjack.Logger{
-		Filename:   options.FileName,
+		Filename:   options.FilePath,
 		MaxSize:    options.MaxSize, // megabytes
 		MaxBackups: options.MaxBackups,
 		MaxAge:     28, // days
diff --git a/network/discovery/dv5_bootnode.go b/network/discovery/dv5_bootnode.go
index 7379eb04fc..3831b71299 100644
--- a/network/discovery/dv5_bootnode.go
+++ b/network/discovery/dv5_bootnode.go
@@ -13,9 +13,9 @@ import (
 
 // BootnodeOptions contains options to create the node
 type BootnodeOptions struct {
-	PrivateKey string `yaml:"PrivateKey" env:"BOOTNODE_NETWORK_KEY" env-description:"Bootnode private key (default will generate new)"`
-	ExternalIP string `yaml:"ExternalIP" env:"BOOTNODE_EXTERNAL_IP" env-description:"Override boot node's IP' "`
-	Port       uint16 `yaml:"Port" env:"BOOTNODE_PORT" env-description:"Override boot node's port' "`
+	PrivateKey string `yaml:"PrivateKey" env:"BOOTNODE_NETWORK_KEY" env-description:"Private key for bootnode identity (generated if empty)"`
+	ExternalIP string `yaml:"ExternalIP" env:"BOOTNODE_EXTERNAL_IP" env-description:"Override bootnode's external IP address"`
+	Port       uint16 `yaml:"Port" env:"BOOTNODE_PORT" env-description:"Override bootnode's UDP port"`
 }
 
 // Bootnode represents a bootnode used for tests
diff --git a/network/p2p/config.go b/network/p2p/config.go
index 74149daeba..7924c08708 100644
--- a/network/p2p/config.go
+++ b/network/p2p/config.go
@@ -34,31 +34,31 @@ const (
 // Config holds the configuration options for p2p network
 type Config struct {
 	Ctx          context.Context
-	Bootnodes    string   `yaml:"Bootnodes" env:"BOOTNODES" env-description:"Bootnodes to use to start discovery, seperated with ';'" env-default:""`
-	Discovery    string   `yaml:"Discovery" env:"P2P_DISCOVERY" env-description:"Discovery system to use" env-default:"discv5"`
-	TrustedPeers []string `yaml:"TrustedPeers" env:"TRUSTED_PEERS" env-default:"" env-description:"List of peers to connect to."`
+	Bootnodes    string   `yaml:"Bootnodes" env:"BOOTNODES" env-default:"" env-description:"Bootnodes to use for discovery (semicolon-separated ENRs, e.g. 'enr:-abc123;enr:-def456')" `
+	Discovery    string   `yaml:"Discovery" env:"P2P_DISCOVERY" env-default:"discv5" env-description:"Discovery protocol to use (discv5, mdns)" `
+	TrustedPeers []string `yaml:"TrustedPeers" env:"TRUSTED_PEERS" env-default:"" env-description:"List of peer IDs to always connect to"`
 
-	TCPPort     uint16 `yaml:"TcpPort" env:"TCP_PORT" env-default:"13001" env-description:"TCP port for p2p transport"`
+	TCPPort     uint16 `yaml:"TcpPort" env:"TCP_PORT" env-default:"13001" env-description:"TCP port for P2P transport"`
 	UDPPort     uint16 `yaml:"UdpPort" env:"UDP_PORT" env-default:"12001" env-description:"UDP port for discovery"`
-	HostAddress string `yaml:"HostAddress" env:"HOST_ADDRESS" env-description:"External ip node is exposed for discovery, can be overridden by HostDNS"`
-	HostDNS     string `yaml:"HostDNS" env:"HOST_DNS" env-description:"External DNS node is exposed for discovery, overrides HostAddress if both are specified"`
+	HostAddress string `yaml:"HostAddress" env:"HOST_ADDRESS" env-description:"External IP address for discovery (can be overridden by HostDNS)"`
+	HostDNS     string `yaml:"HostDNS" env:"HOST_DNS" env-description:"External DNS name for discovery (overrides HostAddress if both are specified)"`
 
-	RequestTimeout   time.Duration `yaml:"RequestTimeout" env:"P2P_REQUEST_TIMEOUT"  env-default:"10s"`
-	MaxBatchResponse uint64        `yaml:"MaxBatchResponse" env:"P2P_MAX_BATCH_RESPONSE" env-default:"25" env-description:"Maximum number of returned objects in a batch"`
+	RequestTimeout   time.Duration `yaml:"RequestTimeout" env:"P2P_REQUEST_TIMEOUT"  env-default:"10s" env-description:"Timeout for P2P requests"`
+	MaxBatchResponse uint64        `yaml:"MaxBatchResponse" env:"P2P_MAX_BATCH_RESPONSE" env-default:"25" env-description:"Maximum number of objects returned in a batch response"`
 
-	MaxPeers             int  `yaml:"MaxPeers" env:"P2P_MAX_PEERS" env-default:"60" env-description:"Connected peers limit. At the time being, this may be increased by DynamicMaxPeers until that is phased out."`
-	DynamicMaxPeers      bool `yaml:"DynamicMaxPeers" env:"P2P_DYNAMIC_MAX_PEERS" env-default:"true" env-description:"If true, MaxPeers will grow with the operator's number of committees."`
-	DynamicMaxPeersLimit int  `yaml:"DynamicMaxPeersLimit" env:"P2P_DYNAMIC_MAX_PEERS_LIMIT" env-default:"150" env-description:"Limit for MaxPeers when DynamicMaxPeers is enabled."`
-	TopicMaxPeers        int  `yaml:"TopicMaxPeers" env:"P2P_TOPIC_MAX_PEERS" env-default:"10" env-description:"Connected peers limit per pubsub topic"`
+	MaxPeers             int  `yaml:"MaxPeers" env:"P2P_MAX_PEERS" env-default:"60" env-description:"Maximum number of connected peers"`
+	DynamicMaxPeers      bool `yaml:"DynamicMaxPeers" env:"P2P_DYNAMIC_MAX_PEERS" env-default:"true" env-description:"Automatically adjust MaxPeers based on committee count"`
+	DynamicMaxPeersLimit int  `yaml:"DynamicMaxPeersLimit" env:"P2P_DYNAMIC_MAX_PEERS_LIMIT" env-default:"150" env-description:"Upper limit for MaxPeers when DynamicMaxPeers is enabled"`
+	TopicMaxPeers        int  `yaml:"TopicMaxPeers" env:"P2P_TOPIC_MAX_PEERS" env-default:"10" env-description:"Maximum peers per pubsub topic"`
 
 	// Subnets is a static bit list of subnets that this node will register upon start.
-	Subnets string `yaml:"Subnets" env:"SUBNETS" env-description:"Hex string that represents the subnets that this node will join upon start"`
+	Subnets string `yaml:"Subnets" env:"SUBNETS" env-description:"Hex string (32 characters) representing 128 subnets to join on startup. Each bit corresponds to a subnet - 1 means join, 0 means skip. Examples: '0x0000000000000000000000000000ffff' (join last 16 subnets), '0xffffffffffffffffffffffffffffffff' (join all 128 subnets)"`
 	// PubSubScoring is a flag to turn on/off pubsub scoring
-	PubSubScoring bool `yaml:"PubSubScoring" env:"PUBSUB_SCORING" env-default:"true" env-description:"Flag to turn on/off pubsub scoring"`
+	PubSubScoring bool `yaml:"PubSubScoring" env:"PUBSUB_SCORING" env-default:"true" env-description:"Enable pubsub peer scoring"`
 	// PubSubTrace is a flag to turn on/off pubsub tracing in logs
-	PubSubTrace bool `yaml:"PubSubTrace" env:"PUBSUB_TRACE" env-description:"Flag to turn on/off pubsub tracing in logs"`
+	PubSubTrace bool `yaml:"PubSubTrace" env:"PUBSUB_TRACE" env-description:"Enable pubsub debug tracing in logs"`
 	// DiscoveryTrace is a flag to turn on/off discovery tracing in logs
-	DiscoveryTrace bool `yaml:"DiscoveryTrace" env:"DISCOVERY_TRACE" env-description:"Flag to turn on/off discovery tracing in logs"`
+	DiscoveryTrace bool `yaml:"DiscoveryTrace" env:"DISCOVERY_TRACE" env-description:"Enable discovery debug tracing in logs"`
 	// NetworkPrivateKey is used for network identity, MUST be injected
 	NetworkPrivateKey *ecdsa.PrivateKey
 	// OperatorSigner is used for signing with operator private key, MUST be injected
@@ -78,16 +78,16 @@ type Config struct {
 	// MessageValidator validates incoming messages.
 	MessageValidator validation.MessageValidator
 
-	PubsubMsgCacheTTL         time.Duration `yaml:"PubsubMsgCacheTTL" env:"PUBSUB_MSG_CACHE_TTL" env-description:"How long a message ID will be remembered as seen"`
-	PubsubOutQueueSize        int           `yaml:"PubsubOutQueueSize" env:"PUBSUB_OUT_Q_SIZE" env-description:"The size that we assign to the outbound pubsub message queue"`
-	PubsubValidationQueueSize int           `yaml:"PubsubValidationQueueSize" env:"PUBSUB_VAL_Q_SIZE" env-description:"The size that we assign to the pubsub validation queue"`
-	PubsubValidateThrottle    int           `yaml:"PubsubPubsubValidateThrottle" env:"PUBSUB_VAL_THROTTLE" env-description:"The amount of goroutines used for pubsub msg validation"`
+	PubsubMsgCacheTTL         time.Duration `yaml:"PubsubMsgCacheTTL" env:"PUBSUB_MSG_CACHE_TTL" env-description:"Duration to remember a message ID as seen"`
+	PubsubOutQueueSize        int           `yaml:"PubsubOutQueueSize" env:"PUBSUB_OUT_Q_SIZE" env-description:"Size of the outbound pubsub message queue"`
+	PubsubValidationQueueSize int           `yaml:"PubsubValidationQueueSize" env:"PUBSUB_VAL_Q_SIZE" env-description:"Size of the pubsub validation queue"`
+	PubsubValidateThrottle    int           `yaml:"PubsubValidateThrottle" env:"PUBSUB_VAL_THROTTLE" env-description:"Number of goroutines for pubsub message validation"`
 
 	// FullNode determines whether the network should sync decided history from peers.
 	// If false, SyncDecidedByRange becomes a no-op.
 	FullNode bool
 
-	DisableIPRateLimit bool `yaml:"DisableIPRateLimit" env:"DISABLE_IP_RATE_LIMIT" default:"false" env-description:"Flag to turn on/off IP rate limiting"`
+	DisableIPRateLimit bool `yaml:"DisableIPRateLimit" env:"DISABLE_IP_RATE_LIMIT" default:"false" env-description:"Disable IP-based rate limiting"`
 
 	GetValidatorStats network.GetValidatorStats
 
diff --git a/operator/node.go b/operator/node.go
index 5ebf69dfea..5797eb7e1c 100644
--- a/operator/node.go
+++ b/operator/node.go
@@ -27,8 +27,8 @@ import (
 // Options contains options to create the node
 type Options struct {
 	// NetworkName is the network name of this node
-	NetworkName         string `yaml:"Network" env:"NETWORK" env-default:"mainnet" env-description:"Network is the network of this node"`
-	CustomDomainType    string `yaml:"CustomDomainType" env:"CUSTOM_DOMAIN_TYPE" env-default:"" env-description:"Override the SSV domain type. This is used to isolate the node from the rest of the network. Do not set unless you know what you are doing. This would be incremented by 1 for Alan, for example: 0x01020304 becomes 0x01020305 post-fork."`
+	NetworkName         string `yaml:"Network" env:"NETWORK" env-default:"mainnet" env-description:"Ethereum network to connect to (mainnet, holesky, sepolia, etc.)"`
+	CustomDomainType    string `yaml:"CustomDomainType" env:"CUSTOM_DOMAIN_TYPE" env-default:"" env-description:"Override SSV domain type for network isolation. Warning: Please modify only if you are certain of the implications. This would be incremented by 1 after Alan fork (e.g., 0x01020304 → 0x01020305 post-fork)"`
 	Network             networkconfig.NetworkConfig
 	BeaconNode          beaconprotocol.BeaconNode // TODO: consider renaming to ConsensusClient
 	ExecutionClient     executionclient.Provider
diff --git a/operator/validator/controller.go b/operator/validator/controller.go
index 68890813a1..9edb9b6c16 100644
--- a/operator/validator/controller.go
+++ b/operator/validator/controller.go
@@ -64,14 +64,14 @@ type ControllerOptions struct {
 	Context                    context.Context
 	DB                         basedb.Database
 	SignatureCollectionTimeout time.Duration `yaml:"SignatureCollectionTimeout" env:"SIGNATURE_COLLECTION_TIMEOUT" env-default:"5s" env-description:"Timeout for signature collection after consensus"`
-	MetadataUpdateInterval     time.Duration `yaml:"MetadataUpdateInterval" env:"METADATA_UPDATE_INTERVAL" env-default:"12m" env-description:"Interval for updating metadata"` // used outside of validator controller, left for compatibility
+	MetadataUpdateInterval     time.Duration `yaml:"MetadataUpdateInterval" env:"METADATA_UPDATE_INTERVAL" env-default:"12m" env-description:"Interval for updating validator metadata"` // used outside of validator controller, left for compatibility
 	HistorySyncBatchSize       int           `yaml:"HistorySyncBatchSize" env:"HISTORY_SYNC_BATCH_SIZE" env-default:"25" env-description:"Maximum number of messages to sync in a single batch"`
-	MinPeers                   int           `yaml:"MinimumPeers" env:"MINIMUM_PEERS" env-default:"2" env-description:"The required minimum peers for sync"`
+	MinPeers                   int           `yaml:"MinimumPeers" env:"MINIMUM_PEERS" env-default:"2" env-description:"Minimum number of peers required for sync"`
 	Network                    P2PNetwork
 	Beacon                     beaconprotocol.BeaconNode
-	FullNode                   bool   `yaml:"FullNode" env:"FULLNODE" env-default:"false" env-description:"Save decided history rather than just highest messages"`
-	Exporter                   bool   `yaml:"Exporter" env:"EXPORTER" env-default:"false" env-description:""`
-	ExporterRetainSlots        uint64 `yaml:"ExporterRetainSlots" env:"EXPORTER_RETAIN_SLOTS" env-default:"50400" env-description:"The number of slots to be keep back"`
+	FullNode                   bool   `yaml:"FullNode" env:"FULLNODE" env-default:"false" env-description:"Store complete message history instead of just latest messages"`
+	Exporter                   bool   `yaml:"Exporter" env:"EXPORTER" env-default:"false" env-description:"Enable data export functionality"`
+	ExporterRetainSlots        uint64 `yaml:"ExporterRetainSlots" env:"EXPORTER_RETAIN_SLOTS" env-default:"50400" env-description:"Number of slots to retain in export data"`
 	BeaconSigner               spectypes.BeaconSigner
 	OperatorSigner             ssvtypes.OperatorSigner
 	OperatorDataStore          operatordatastore.OperatorDataStore
@@ -89,9 +89,9 @@ type ControllerOptions struct {
 	Graffiti                   []byte
 
 	// worker flags
-	WorkersCount    int    `yaml:"MsgWorkersCount" env:"MSG_WORKERS_COUNT" env-default:"256" env-description:"Number of goroutines to use for message workers"`
-	QueueBufferSize int    `yaml:"MsgWorkerBufferSize" env:"MSG_WORKER_BUFFER_SIZE" env-default:"65536" env-description:"Buffer size for message workers"`
-	GasLimit        uint64 `yaml:"ExperimentalGasLimit" env:"EXPERIMENTAL_GAS_LIMIT" env-default:"30000000" env-description:"The gas limit for MEV block proposals. All operators in a committee must set the same gas limit, otherwise MEV fails. Do not change unless you know what you're doing"`
+	WorkersCount    int    `yaml:"MsgWorkersCount" env:"MSG_WORKERS_COUNT" env-default:"256" env-description:"Number of message processing workers"`
+	QueueBufferSize int    `yaml:"MsgWorkerBufferSize" env:"MSG_WORKER_BUFFER_SIZE" env-default:"65536" env-description:"Size of message worker queue buffer"`
+	GasLimit        uint64 `yaml:"ExperimentalGasLimit" env:"EXPERIMENTAL_GAS_LIMIT" env-default:"30000000" env-description:"Gas limit for MEV block proposals (must match across committee, otherwise MEV fails). Do not change unless you know what you're doing"`
 }
 
 // Controller represent the validators controller,
diff --git a/protocol/v2/blockchain/beacon/client.go b/protocol/v2/blockchain/beacon/client.go
index a9ce44bcf9..7b7121848a 100644
--- a/protocol/v2/blockchain/beacon/client.go
+++ b/protocol/v2/blockchain/beacon/client.go
@@ -62,9 +62,9 @@ type BeaconNode interface {
 type Options struct {
 	Context                     context.Context
 	Network                     Network
-	BeaconNodeAddr              string `yaml:"BeaconNodeAddr" env:"BEACON_NODE_ADDR" env-required:"true" env-description:"Beacon node address. Supports multiple semicolon separated addresses. ex: http://localhost:5052;http://localhost:5053"`
-	SyncDistanceTolerance       uint64 `yaml:"SyncDistanceTolerance" env:"BEACON_SYNC_DISTANCE_TOLERANCE" env-default:"4" env-description:"The number of out-of-sync slots we can tolerate"`
-	WithWeightedAttestationData bool   `yaml:"WithWeightedAttestationData" env:"WITH_WEIGHTED_ATTESTATION_DATA" env-default:"false" env-description:"Enables Attestation Data fetching & scoring using multiple Beacon nodes simultaneously (as opposed to fetching Attestation Data from just one Beacon node)"`
+	BeaconNodeAddr              string `yaml:"BeaconNodeAddr" env:"BEACON_NODE_ADDR" env-required:"true" env-description:"Beacon node URL(s). Multiple nodes are supported via semicolon-separated URLs (e.g. 'http://localhost:5052;http://localhost:5053')"`
+	SyncDistanceTolerance       uint64 `yaml:"SyncDistanceTolerance" env:"BEACON_SYNC_DISTANCE_TOLERANCE" env-default:"4" env-description:"Maximum number of slots behind head considered in-sync"`
+	WithWeightedAttestationData bool   `yaml:"WithWeightedAttestationData" env:"WITH_WEIGHTED_ATTESTATION_DATA" env-default:"false" env-description:"Enable attestation data scoring across multiple beacon nodes"`
 
 	CommonTimeout time.Duration // Optional.
 	LongTimeout   time.Duration // Optional.
diff --git a/storage/basedb/storage.go b/storage/basedb/storage.go
index 66daa80356..da6deb6c7c 100644
--- a/storage/basedb/storage.go
+++ b/storage/basedb/storage.go
@@ -8,9 +8,9 @@ import (
 // Options for creating all db type
 type Options struct {
 	Ctx        context.Context
-	Path       string        `yaml:"Path" env:"DB_PATH" env-default:"./data/db" env-description:"Path for storage"`
-	Reporting  bool          `yaml:"Reporting" env:"DB_REPORTING" env-default:"false" env-description:"Flag to run on-off db size reporting"`
-	GCInterval time.Duration `yaml:"GCInterval" env:"DB_GC_INTERVAL" env-default:"6m" env-description:"Interval between garbage collection cycles. Set to 0 to disable."`
+	Path       string        `yaml:"Path" env:"DB_PATH" env-default:"./data/db" env-description:"Database storage directory path"`
+	Reporting  bool          `yaml:"Reporting" env:"DB_REPORTING" env-default:"false" env-description:"Enable database size reporting"`
+	GCInterval time.Duration `yaml:"GCInterval" env:"DB_GC_INTERVAL" env-default:"6m" env-description:"Interval between garbage collection runs (0 to disable)"`
 }
 
 // Reader is a read-only accessor to the database.
@@ -20,7 +20,7 @@ type Reader interface {
 	GetAll(prefix []byte, handler func(int, Obj) error) error
 }
 
-// ReadWrite is a read-write accessor to the database.
+// ReadWriter is a read-write accessor to the database.
 type ReadWriter interface {
 	Reader
 	Set(prefix []byte, key []byte, value []byte) error
diff --git a/utils/boot_node/node.go b/utils/boot_node/node.go
index a0c10df823..b36c13c311 100644
--- a/utils/boot_node/node.go
+++ b/utils/boot_node/node.go
@@ -27,12 +27,12 @@ import (
 
 // Options contains options to create the node
 type Options struct {
-	PrivateKey string `yaml:"PrivateKey" env:"BOOT_NODE_PRIVATE_KEY" env-description:"boot node private key (default will generate new)"`
-	ExternalIP string `yaml:"ExternalIP" env:"BOOT_NODE_EXTERNAL_IP" env-description:"Override boot node's external IP"`
-	TCPPort    uint16 `yaml:"TcpPort" env:"TCP_PORT" env-default:"5000" env-description:"TCP port for p2p transport"`
+	PrivateKey string `yaml:"PrivateKey" env:"BOOT_NODE_PRIVATE_KEY" env-description:"Private key for bootnode identity (generated if empty)"`
+	ExternalIP string `yaml:"ExternalIP" env:"BOOT_NODE_EXTERNAL_IP" env-description:"Override bootnode's external IP address"`
+	TCPPort    uint16 `yaml:"TcpPort" env:"TCP_PORT" env-default:"5000" env-description:"TCP port for P2P transport"`
 	UDPPort    uint16 `yaml:"UdpPort" env:"UDP_PORT" env-default:"4000" env-description:"UDP port for discovery"`
-	DbPath     string `yaml:"DbPath" env:"BOOT_NODE_DB_PATH" env-default:"/data/bootnode" env-description:"Path to the boot node's database"`
-	Network    string `yaml:"Network" env:"NETWORK" env-default:"mainnet"`
+	DbPath     string `yaml:"DbPath" env:"BOOT_NODE_DB_PATH" env-default:"/data/bootnode" env-description:"Path to bootnode database directory"`
+	Network    string `yaml:"Network" env:"NETWORK" env-default:"mainnet" env-description:"Ethereum network to connect to"`
 }
 
 // Node represents the behavior of boot node


Reviews:
user: login: copilot-pull-request-reviewer[bot]
body: ## PR Overview

This PR refactors configuration files to standardize environment variable descriptions, field naming, and documentation across multiple modules. Key changes include improved and consistent descriptions for network, logging, and database configurations; renaming of some structs (e.g. from ExecutionOptions to Options) for clarity; and minor revisions to YAML tags and comments.

### Reviewed Changes

| File                                       | Description                                                             |
| ------------------------------------------ | ----------------------------------------------------------------------- |
| network/p2p/config.go                      | Updated env variable descriptions, capitalization, and phrasing         |
| operator/node.go                           | Revised descriptions for network and custom domain options              |
| utils/boot_node/node.go                    | Refined bootnode options descriptions                                   |
| eth/executionclient/config.go              | Renamed struct to Options and enhanced field descriptions               |
| cli/config/config.go                       | Standardized logging configuration descriptions                         |
| protocol/v2/blockchain/beacon/client.go    | Clarified beacon node config descriptions                               |
| storage/basedb/storage.go                  | Updated database config descriptions and interface comment wording      |
| network/discovery/dv5_bootnode.go          | Improved bootnode options descriptions                                  |
| operator/validator/controller.go           | Streamlined metadata and worker options descriptions                    |
| cli/operator/node.go                       | Standardized operator node config descriptions and updated logging field  |
| cli/bootnode/boot_node.go                  | Updated logging configuration descriptions                              |
| logging/global.go                          | Renamed LogFileOptions field from FileName to FilePath for consistency    |

Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.

<details>
<summary>Comments suppressed due to low confidence (1)</summary>

**network/p2p/config.go:84**
* The YAML tag 'PubsubPubsubValidateThrottle' appears to contain a duplicate 'Pubsub' prefix; consider renaming it to 'PubsubValidateThrottle' for consistency with other fields.
```
PubsubValidateThrottle    int           `yaml:"PubsubPubsubValidateThrottle" env:"PUBSUB_VAL_THROTTLE" env-description:"Number of goroutines for pubsub message validation"`
```
</details>


state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T16:41:36Z
user: login: copilot-pull-request-reviewer[bot]
body: ## PR Overview

This PR refactors configuration descriptions and naming conventions across multiple modules to standardize environment variable documentation. Key changes include updating env-description texts for clarity, renaming structs (e.g., ExecutionOptions to Options), and aligning terminology across configuration files.

### Reviewed Changes

| File                                  | Description                                                                          |
| ------------------------------------- | ------------------------------------------------------------------------------------ |
| network/p2p/config.go                 | Standardized env-description messages and updated field terminology for P2P configs.   |
| operator/node.go                      | Revised option descriptions for network and custom domains.                          |
| utils/boot_node/node.go               | Updated bootnode configuration descriptions for clarity.                             |
| eth/executionclient/config.go         | Renamed ExecutionOptions to Options and improved execution client config descriptions. |
| cli/config/config.go                  | Updated logging configuration descriptions.                                            |
| protocol/v2/blockchain/beacon/client.go| Improved beacon node config descriptions for URL formatting and sync tolerance.        |
| operator/validator/controller.go      | Adjusted descriptions for metadata updates, export functionality, and worker settings. |
| storage/basedb/storage.go             | Revised storage option descriptions and renamed ReadWrite to ReadWriter.              |
| network/discovery/dv5_bootnode.go       | Standardized bootnode option descriptions.                                             |
| cli/operator/node.go                  | Updated configuration field descriptions and standardized log file option naming.       |
| cli/bootnode/boot_node.go             | Updated logging option field name for consistency.                                     |
| logging/global.go                     | Renamed LogFileOptions field from FileName to FilePath in logger configuration.          |

Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.



state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T16:57:59Z
user: login: nkryuchkov
body: Now it looks much better! Just a few requests
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T14:38:43Z
user: login: kchojn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T19:15:03Z
user: login: nkryuchkov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T19:21:22Z
user: login: nkryuchkov
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T19:21:31Z
user: login: oleg-ssvlabs
body: awesome changes. Left few minor suggestions
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-12T09:49:24Z
user: login: kchojn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-12T11:19:39Z
user: login: oleg-ssvlabs
body: 🔥 
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-12T12:13:43Z
user: login: y0sher
body: lgtm 
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-12T14:37:56Z
user: login: iurii-ssv
body: Nice!
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T10:13:00Z
user: login: moshe-blox
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T10:26:41Z

Review comments:
diff_hunk: @@ -34,31 +34,31 @@ const (
 // Config holds the configuration options for p2p network
 type Config struct {
 	Ctx          context.Context
-	Bootnodes    string   `yaml:"Bootnodes" env:"BOOTNODES" env-description:"Bootnodes to use to start discovery, seperated with ';'" env-default:""`
-	Discovery    string   `yaml:"Discovery" env:"P2P_DISCOVERY" env-description:"Discovery system to use" env-default:"discv5"`
-	TrustedPeers []string `yaml:"TrustedPeers" env:"TRUSTED_PEERS" env-default:"" env-description:"List of peers to connect to."`
+	Bootnodes    string   `yaml:"Bootnodes" env:"BOOTNODES" env-default:"" env-description:"Bootnodes to use for discovery (semicolon-separated ENRs, e.g. 'enr:-abc123;enr:-def456')" `
+	Discovery    string   `yaml:"Discovery" env:"P2P_DISCOVERY" env-default:"discv5" env-description:"Discovery protocol to use (discv5, mdns)" `
+	TrustedPeers []string `yaml:"TrustedPeers" env:"TRUSTED_PEERS" env-default:"" env-description:"List of peer IDs to always connect to"`
 
-	TCPPort     uint16 `yaml:"TcpPort" env:"TCP_PORT" env-default:"13001" env-description:"TCP port for p2p transport"`
+	TCPPort     uint16 `yaml:"TcpPort" env:"TCP_PORT" env-default:"13001" env-description:"TCP port for P2P transport"`
 	UDPPort     uint16 `yaml:"UdpPort" env:"UDP_PORT" env-default:"12001" env-description:"UDP port for discovery"`
-	HostAddress string `yaml:"HostAddress" env:"HOST_ADDRESS" env-description:"External ip node is exposed for discovery, can be overridden by HostDNS"`
-	HostDNS     string `yaml:"HostDNS" env:"HOST_DNS" env-description:"External DNS node is exposed for discovery, overrides HostAddress if both are specified"`
+	HostAddress string `yaml:"HostAddress" env:"HOST_ADDRESS" env-description:"External IP address for discovery (can be overridden by HostDNS)"`
+	HostDNS     string `yaml:"HostDNS" env:"HOST_DNS" env-description:"External DNS name for discovery (overrides HostAddress if both are specified)"`
 
-	RequestTimeout   time.Duration `yaml:"RequestTimeout" env:"P2P_REQUEST_TIMEOUT"  env-default:"10s"`
-	MaxBatchResponse uint64        `yaml:"MaxBatchResponse" env:"P2P_MAX_BATCH_RESPONSE" env-default:"25" env-description:"Maximum number of returned objects in a batch"`
+	RequestTimeout   time.Duration `yaml:"RequestTimeout" env:"P2P_REQUEST_TIMEOUT"  env-default:"10s" env-description:"Timeout for P2P requests"`
+	MaxBatchResponse uint64        `yaml:"MaxBatchResponse" env:"P2P_MAX_BATCH_RESPONSE" env-default:"25" env-description:"Maximum number of objects returned in a batch response"`
 
-	MaxPeers             int  `yaml:"MaxPeers" env:"P2P_MAX_PEERS" env-default:"60" env-description:"Connected peers limit. At the time being, this may be increased by DynamicMaxPeers until that is phased out."`
-	DynamicMaxPeers      bool `yaml:"DynamicMaxPeers" env:"P2P_DYNAMIC_MAX_PEERS" env-default:"true" env-description:"If true, MaxPeers will grow with the operator's number of committees."`
-	DynamicMaxPeersLimit int  `yaml:"DynamicMaxPeersLimit" env:"P2P_DYNAMIC_MAX_PEERS_LIMIT" env-default:"150" env-description:"Limit for MaxPeers when DynamicMaxPeers is enabled."`
-	TopicMaxPeers        int  `yaml:"TopicMaxPeers" env:"P2P_TOPIC_MAX_PEERS" env-default:"10" env-description:"Connected peers limit per pubsub topic"`
+	MaxPeers             int  `yaml:"MaxPeers" env:"P2P_MAX_PEERS" env-default:"60" env-description:"Maximum number of connected peers"`
+	DynamicMaxPeers      bool `yaml:"DynamicMaxPeers" env:"P2P_DYNAMIC_MAX_PEERS" env-default:"true" env-description:"Automatically adjust MaxPeers based on committee count"`
+	DynamicMaxPeersLimit int  `yaml:"DynamicMaxPeersLimit" env:"P2P_DYNAMIC_MAX_PEERS_LIMIT" env-default:"150" env-description:"Upper limit for MaxPeers when DynamicMaxPeers is enabled"`
+	TopicMaxPeers        int  `yaml:"TopicMaxPeers" env:"P2P_TOPIC_MAX_PEERS" env-default:"10" env-description:"Maximum peers per pubsub topic"`
 
 	// Subnets is a static bit list of subnets that this node will register upon start.
-	Subnets string `yaml:"Subnets" env:"SUBNETS" env-description:"Hex string that represents the subnets that this node will join upon start"`
+	Subnets string `yaml:"Subnets" env:"SUBNETS" env-description:"Hex string representing subnets to join on startup (e.g. '0x01ff')"`
path: network/p2p/config.go
user: login: nkryuchkov
body: We have a 128 subnet count, so we use a 32-letter string here. I'm afraid the example might be a bit confusing. So, IMO, while we are touching it, we also need to add a short description of the format and a real example
created_at: 2025-03-10T14:30:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -27,8 +27,8 @@ import (
 // Options contains options to create the node
 type Options struct {
 	// NetworkName is the network name of this node
-	NetworkName         string `yaml:"Network" env:"NETWORK" env-default:"mainnet" env-description:"Network is the network of this node"`
-	CustomDomainType    string `yaml:"CustomDomainType" env:"CUSTOM_DOMAIN_TYPE" env-default:"" env-description:"Override the SSV domain type. This is used to isolate the node from the rest of the network. Do not set unless you know what you are doing. This would be incremented by 1 for Alan, for example: 0x01020304 becomes 0x01020305 post-fork."`
+	NetworkName         string `yaml:"Network" env:"NETWORK" env-default:"mainnet" env-description:"Ethereum network to connect to (mainnet, goerli, etc.)"`
+	CustomDomainType    string `yaml:"CustomDomainType" env:"CUSTOM_DOMAIN_TYPE" env-default:"" env-description:"Override SSV domain type for network isolation (e.g., 0x01020304 → 0x01020305 post-fork). Only modify if you know what you're doing."`
path: operator/node.go
user: login: nkryuchkov
body: We need to keep `This would be incremented by 1 for Alan` because it's an Alan fork workaround, we didn't increment it before the Alan fork. Now we increment everything passed here by 1, e.g. custom domain type `0x12345678` will in fact be converted to `0x12345679`

```suggestion
	CustomDomainType    string `yaml:"CustomDomainType" env:"CUSTOM_DOMAIN_TYPE" env-default:"" env-description:"Override SSV domain type for network isolation. Only modify if you know what you're doing. This would be incremented by 1 after Alan fork (e.g., 0x01020304 → 0x01020305 post-fork). "`
```
created_at: 2025-03-10T14:34:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -64,14 +64,14 @@ type ControllerOptions struct {
 	Context                    context.Context
 	DB                         basedb.Database
 	SignatureCollectionTimeout time.Duration `yaml:"SignatureCollectionTimeout" env:"SIGNATURE_COLLECTION_TIMEOUT" env-default:"5s" env-description:"Timeout for signature collection after consensus"`
-	MetadataUpdateInterval     time.Duration `yaml:"MetadataUpdateInterval" env:"METADATA_UPDATE_INTERVAL" env-default:"12m" env-description:"Interval for updating metadata"` // used outside of validator controller, left for compatibility
+	MetadataUpdateInterval     time.Duration `yaml:"MetadataUpdateInterval" env:"METADATA_UPDATE_INTERVAL" env-default:"12m" env-description:"Interval for updating validator metadata"`
path: operator/validator/controller.go
user: login: nkryuchkov
body: I'd keep the comment to reduce possible confusion and to keep in mind that we need to refactor this
```suggestion
	MetadataUpdateInterval     time.Duration `yaml:"MetadataUpdateInterval" env:"METADATA_UPDATE_INTERVAL" env-default:"12m" env-description:"Interval for updating validator metadata"` // used outside of validator controller, left for compatibility
```
created_at: 2025-03-10T14:36:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -89,9 +89,9 @@ type ControllerOptions struct {
 	Graffiti                   []byte
 
 	// worker flags
-	WorkersCount    int    `yaml:"MsgWorkersCount" env:"MSG_WORKERS_COUNT" env-default:"256" env-description:"Number of goroutines to use for message workers"`
-	QueueBufferSize int    `yaml:"MsgWorkerBufferSize" env:"MSG_WORKER_BUFFER_SIZE" env-default:"65536" env-description:"Buffer size for message workers"`
-	GasLimit        uint64 `yaml:"ExperimentalGasLimit" env:"EXPERIMENTAL_GAS_LIMIT" env-default:"30000000" env-description:"The gas limit for MEV block proposals. All operators in a committee must set the same gas limit, otherwise MEV fails. Do not change unless you know what you're doing"`
+	WorkersCount    int    `yaml:"MsgWorkersCount" env:"MSG_WORKERS_COUNT" env-default:"256" env-description:"Number of message processing workers"`
+	QueueBufferSize int    `yaml:"MsgWorkerBufferSize" env:"MSG_WORKER_BUFFER_SIZE" env-default:"65536" env-description:"Size of message worker queue buffer"`
+	GasLimit        uint64 `yaml:"ExperimentalGasLimit" env:"EXPERIMENTAL_GAS_LIMIT" env-default:"30000000" env-description:"Gas limit for MEV block proposals (must match across committee)"`
path: operator/validator/controller.go
user: login: nkryuchkov
body: I'd keep the warning

```suggestion
	GasLimit        uint64 `yaml:"ExperimentalGasLimit" env:"EXPERIMENTAL_GAS_LIMIT" env-default:"30000000" env-description:"Gas limit for MEV block proposals (must match across committee, otherwise MEV fails). Do not change unless you know what you're doing"`
```
created_at: 2025-03-10T14:37:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -34,31 +34,31 @@ const (
 // Config holds the configuration options for p2p network
 type Config struct {
 	Ctx          context.Context
-	Bootnodes    string   `yaml:"Bootnodes" env:"BOOTNODES" env-description:"Bootnodes to use to start discovery, seperated with ';'" env-default:""`
-	Discovery    string   `yaml:"Discovery" env:"P2P_DISCOVERY" env-description:"Discovery system to use" env-default:"discv5"`
-	TrustedPeers []string `yaml:"TrustedPeers" env:"TRUSTED_PEERS" env-default:"" env-description:"List of peers to connect to."`
+	Bootnodes    string   `yaml:"Bootnodes" env:"BOOTNODES" env-default:"" env-description:"Bootnodes to use for discovery (semicolon-separated ENRs, e.g. 'enr:-abc123;enr:-def456')" `
+	Discovery    string   `yaml:"Discovery" env:"P2P_DISCOVERY" env-default:"discv5" env-description:"Discovery protocol to use (discv5, mdns)" `
+	TrustedPeers []string `yaml:"TrustedPeers" env:"TRUSTED_PEERS" env-default:"" env-description:"List of peer IDs to always connect to"`
 
-	TCPPort     uint16 `yaml:"TcpPort" env:"TCP_PORT" env-default:"13001" env-description:"TCP port for p2p transport"`
+	TCPPort     uint16 `yaml:"TcpPort" env:"TCP_PORT" env-default:"13001" env-description:"TCP port for P2P transport"`
 	UDPPort     uint16 `yaml:"UdpPort" env:"UDP_PORT" env-default:"12001" env-description:"UDP port for discovery"`
-	HostAddress string `yaml:"HostAddress" env:"HOST_ADDRESS" env-description:"External ip node is exposed for discovery, can be overridden by HostDNS"`
-	HostDNS     string `yaml:"HostDNS" env:"HOST_DNS" env-description:"External DNS node is exposed for discovery, overrides HostAddress if both are specified"`
+	HostAddress string `yaml:"HostAddress" env:"HOST_ADDRESS" env-description:"External IP address for discovery (can be overridden by HostDNS)"`
+	HostDNS     string `yaml:"HostDNS" env:"HOST_DNS" env-description:"External DNS name for discovery (overrides HostAddress if both are specified)"`
 
-	RequestTimeout   time.Duration `yaml:"RequestTimeout" env:"P2P_REQUEST_TIMEOUT"  env-default:"10s"`
-	MaxBatchResponse uint64        `yaml:"MaxBatchResponse" env:"P2P_MAX_BATCH_RESPONSE" env-default:"25" env-description:"Maximum number of returned objects in a batch"`
+	RequestTimeout   time.Duration `yaml:"RequestTimeout" env:"P2P_REQUEST_TIMEOUT"  env-default:"10s" env-description:"Timeout for P2P requests"`
+	MaxBatchResponse uint64        `yaml:"MaxBatchResponse" env:"P2P_MAX_BATCH_RESPONSE" env-default:"25" env-description:"Maximum number of objects returned in a batch response"`
 
-	MaxPeers             int  `yaml:"MaxPeers" env:"P2P_MAX_PEERS" env-default:"60" env-description:"Connected peers limit. At the time being, this may be increased by DynamicMaxPeers until that is phased out."`
-	DynamicMaxPeers      bool `yaml:"DynamicMaxPeers" env:"P2P_DYNAMIC_MAX_PEERS" env-default:"true" env-description:"If true, MaxPeers will grow with the operator's number of committees."`
-	DynamicMaxPeersLimit int  `yaml:"DynamicMaxPeersLimit" env:"P2P_DYNAMIC_MAX_PEERS_LIMIT" env-default:"150" env-description:"Limit for MaxPeers when DynamicMaxPeers is enabled."`
-	TopicMaxPeers        int  `yaml:"TopicMaxPeers" env:"P2P_TOPIC_MAX_PEERS" env-default:"10" env-description:"Connected peers limit per pubsub topic"`
+	MaxPeers             int  `yaml:"MaxPeers" env:"P2P_MAX_PEERS" env-default:"60" env-description:"Maximum number of connected peers"`
+	DynamicMaxPeers      bool `yaml:"DynamicMaxPeers" env:"P2P_DYNAMIC_MAX_PEERS" env-default:"true" env-description:"Automatically adjust MaxPeers based on committee count"`
+	DynamicMaxPeersLimit int  `yaml:"DynamicMaxPeersLimit" env:"P2P_DYNAMIC_MAX_PEERS_LIMIT" env-default:"150" env-description:"Upper limit for MaxPeers when DynamicMaxPeers is enabled"`
+	TopicMaxPeers        int  `yaml:"TopicMaxPeers" env:"P2P_TOPIC_MAX_PEERS" env-default:"10" env-description:"Maximum peers per pubsub topic"`
 
 	// Subnets is a static bit list of subnets that this node will register upon start.
-	Subnets string `yaml:"Subnets" env:"SUBNETS" env-description:"Hex string that represents the subnets that this node will join upon start"`
+	Subnets string `yaml:"Subnets" env:"SUBNETS" env-description:"Hex string representing subnets to join on startup (e.g. '0x01ff')"`
path: network/p2p/config.go
user: login: kchojn
body: I added a more detailed description, thanks!
created_at: 2025-03-10T19:15:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -34,31 +34,31 @@ const (
 // Config holds the configuration options for p2p network
 type Config struct {
 	Ctx          context.Context
-	Bootnodes    string   `yaml:"Bootnodes" env:"BOOTNODES" env-description:"Bootnodes to use to start discovery, seperated with ';'" env-default:""`
-	Discovery    string   `yaml:"Discovery" env:"P2P_DISCOVERY" env-description:"Discovery system to use" env-default:"discv5"`
-	TrustedPeers []string `yaml:"TrustedPeers" env:"TRUSTED_PEERS" env-default:"" env-description:"List of peers to connect to."`
+	Bootnodes    string   `yaml:"Bootnodes" env:"BOOTNODES" env-default:"" env-description:"Bootnodes to use for discovery (semicolon-separated ENRs, e.g. 'enr:-abc123;enr:-def456')" `
+	Discovery    string   `yaml:"Discovery" env:"P2P_DISCOVERY" env-default:"discv5" env-description:"Discovery protocol to use (discv5, mdns)" `
+	TrustedPeers []string `yaml:"TrustedPeers" env:"TRUSTED_PEERS" env-default:"" env-description:"List of peer IDs to always connect to"`
 
-	TCPPort     uint16 `yaml:"TcpPort" env:"TCP_PORT" env-default:"13001" env-description:"TCP port for p2p transport"`
+	TCPPort     uint16 `yaml:"TcpPort" env:"TCP_PORT" env-default:"13001" env-description:"TCP port for P2P transport"`
 	UDPPort     uint16 `yaml:"UdpPort" env:"UDP_PORT" env-default:"12001" env-description:"UDP port for discovery"`
-	HostAddress string `yaml:"HostAddress" env:"HOST_ADDRESS" env-description:"External ip node is exposed for discovery, can be overridden by HostDNS"`
-	HostDNS     string `yaml:"HostDNS" env:"HOST_DNS" env-description:"External DNS node is exposed for discovery, overrides HostAddress if both are specified"`
+	HostAddress string `yaml:"HostAddress" env:"HOST_ADDRESS" env-description:"External IP address for discovery (can be overridden by HostDNS)"`
+	HostDNS     string `yaml:"HostDNS" env:"HOST_DNS" env-description:"External DNS name for discovery (overrides HostAddress if both are specified)"`
 
-	RequestTimeout   time.Duration `yaml:"RequestTimeout" env:"P2P_REQUEST_TIMEOUT"  env-default:"10s"`
-	MaxBatchResponse uint64        `yaml:"MaxBatchResponse" env:"P2P_MAX_BATCH_RESPONSE" env-default:"25" env-description:"Maximum number of returned objects in a batch"`
+	RequestTimeout   time.Duration `yaml:"RequestTimeout" env:"P2P_REQUEST_TIMEOUT"  env-default:"10s" env-description:"Timeout for P2P requests"`
+	MaxBatchResponse uint64        `yaml:"MaxBatchResponse" env:"P2P_MAX_BATCH_RESPONSE" env-default:"25" env-description:"Maximum number of objects returned in a batch response"`
 
-	MaxPeers             int  `yaml:"MaxPeers" env:"P2P_MAX_PEERS" env-default:"60" env-description:"Connected peers limit. At the time being, this may be increased by DynamicMaxPeers until that is phased out."`
-	DynamicMaxPeers      bool `yaml:"DynamicMaxPeers" env:"P2P_DYNAMIC_MAX_PEERS" env-default:"true" env-description:"If true, MaxPeers will grow with the operator's number of committees."`
-	DynamicMaxPeersLimit int  `yaml:"DynamicMaxPeersLimit" env:"P2P_DYNAMIC_MAX_PEERS_LIMIT" env-default:"150" env-description:"Limit for MaxPeers when DynamicMaxPeers is enabled."`
-	TopicMaxPeers        int  `yaml:"TopicMaxPeers" env:"P2P_TOPIC_MAX_PEERS" env-default:"10" env-description:"Connected peers limit per pubsub topic"`
+	MaxPeers             int  `yaml:"MaxPeers" env:"P2P_MAX_PEERS" env-default:"60" env-description:"Maximum number of connected peers"`
+	DynamicMaxPeers      bool `yaml:"DynamicMaxPeers" env:"P2P_DYNAMIC_MAX_PEERS" env-default:"true" env-description:"Automatically adjust MaxPeers based on committee count"`
+	DynamicMaxPeersLimit int  `yaml:"DynamicMaxPeersLimit" env:"P2P_DYNAMIC_MAX_PEERS_LIMIT" env-default:"150" env-description:"Upper limit for MaxPeers when DynamicMaxPeers is enabled"`
+	TopicMaxPeers        int  `yaml:"TopicMaxPeers" env:"P2P_TOPIC_MAX_PEERS" env-default:"10" env-description:"Maximum peers per pubsub topic"`
 
 	// Subnets is a static bit list of subnets that this node will register upon start.
-	Subnets string `yaml:"Subnets" env:"SUBNETS" env-description:"Hex string that represents the subnets that this node will join upon start"`
+	Subnets string `yaml:"Subnets" env:"SUBNETS" env-description:"Hex string representing subnets to join on startup (e.g. '0x01ff')"`
path: network/p2p/config.go
user: login: nkryuchkov
body: Thanks! LGTM
created_at: 2025-03-10T19:21:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -6,9 +6,9 @@ import (
 
 // TODO: rename eth1, consider combining with consensus client options
 
-// ExecutionOptions contains config configurations related to Ethereum execution client.
-type ExecutionOptions struct {
-	Addr                  string        `yaml:"ETH1Addr" env:"ETH_1_ADDR" env-required:"true" env-description:"Execution client WebSocket address. Supports multiple semicolon separated addresses. ex: ws://localhost:8546;ws://localhost:8547"`
-	ConnectionTimeout     time.Duration `yaml:"ETH1ConnectionTimeout" env:"ETH_1_CONNECTION_TIMEOUT" env-default:"10s" env-description:"Execution client connection timeout"`
-	SyncDistanceTolerance uint64        `yaml:"ETH1SyncDistanceTolerance" env:"ETH_1_SYNC_DISTANCE_TOLERANCE" env-default:"5" env-description:"The number of out-of-sync blocks we can tolerate"`
+// Options contains config configurations related to Ethereum execution client.
+type Options struct {
+	Addr                  string        `yaml:"ETH1Addr" env:"ETH_1_ADDR" env-required:"true" env-description:"Execution client WebSocket URLs (semicolon-separated, e.g. 'ws://localhost:8546;ws://localhost:8547')"`
path: eth/executionclient/config.go
user: login: oleg-ssvlabs
body: I would slightly rephrase it to emphasize support for **one** or **multiple** execution clients. Otherwise, it may appear that multiple URLs are always expected
created_at: 2025-03-12T09:28:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -6,9 +6,9 @@ import (
 
 // TODO: rename eth1, consider combining with consensus client options
 
-// ExecutionOptions contains config configurations related to Ethereum execution client.
-type ExecutionOptions struct {
path: eth/executionclient/config.go
user: login: oleg-ssvlabs
body: nice!
created_at: 2025-03-12T09:29:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -27,8 +27,8 @@ import (
 // Options contains options to create the node
 type Options struct {
 	// NetworkName is the network name of this node
-	NetworkName         string `yaml:"Network" env:"NETWORK" env-default:"mainnet" env-description:"Network is the network of this node"`
-	CustomDomainType    string `yaml:"CustomDomainType" env:"CUSTOM_DOMAIN_TYPE" env-default:"" env-description:"Override the SSV domain type. This is used to isolate the node from the rest of the network. Do not set unless you know what you are doing. This would be incremented by 1 for Alan, for example: 0x01020304 becomes 0x01020305 post-fork."`
+	NetworkName         string `yaml:"Network" env:"NETWORK" env-default:"mainnet" env-description:"Ethereum network to connect to (mainnet, goerli, etc.)"`
path: operator/node.go
user: login: oleg-ssvlabs
body: nitpick: to my knowledge, goerli testnet was deprecated, so maybe we could provide some other example ? :)
created_at: 2025-03-12T09:38:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -27,8 +27,8 @@ import (
 // Options contains options to create the node
 type Options struct {
 	// NetworkName is the network name of this node
-	NetworkName         string `yaml:"Network" env:"NETWORK" env-default:"mainnet" env-description:"Network is the network of this node"`
-	CustomDomainType    string `yaml:"CustomDomainType" env:"CUSTOM_DOMAIN_TYPE" env-default:"" env-description:"Override the SSV domain type. This is used to isolate the node from the rest of the network. Do not set unless you know what you are doing. This would be incremented by 1 for Alan, for example: 0x01020304 becomes 0x01020305 post-fork."`
+	NetworkName         string `yaml:"Network" env:"NETWORK" env-default:"mainnet" env-description:"Ethereum network to connect to (mainnet, goerli, etc.)"`
+	CustomDomainType    string `yaml:"CustomDomainType" env:"CUSTOM_DOMAIN_TYPE" env-default:"" env-description:"Override SSV domain type for network isolation. Only modify if you know what you're doing. This would be incremented by 1 after Alan fork (e.g., 0x01020304 → 0x01020305 post-fork). "`
path: operator/node.go
user: login: oleg-ssvlabs
body: > Only modify if you know what you're doing

Could be more polite? For example: _Warning: Please modify only if you are certain of the implications_
created_at: 2025-03-12T09:40:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -62,9 +62,9 @@ type BeaconNode interface {
 type Options struct {
 	Context                     context.Context
 	Network                     Network
-	BeaconNodeAddr              string `yaml:"BeaconNodeAddr" env:"BEACON_NODE_ADDR" env-required:"true" env-description:"Beacon node address. Supports multiple semicolon separated addresses. ex: http://localhost:5052;http://localhost:5053"`
-	SyncDistanceTolerance       uint64 `yaml:"SyncDistanceTolerance" env:"BEACON_SYNC_DISTANCE_TOLERANCE" env-default:"4" env-description:"The number of out-of-sync slots we can tolerate"`
-	WithWeightedAttestationData bool   `yaml:"WithWeightedAttestationData" env:"WITH_WEIGHTED_ATTESTATION_DATA" env-default:"false" env-description:"Enables Attestation Data fetching & scoring using multiple Beacon nodes simultaneously (as opposed to fetching Attestation Data from just one Beacon node)"`
+	BeaconNodeAddr              string `yaml:"BeaconNodeAddr" env:"BEACON_NODE_ADDR" env-required:"true" env-description:"Beacon node URLs (semicolon-separated, e.g. 'http://localhost:5052;http://localhost:5053')"`
path: protocol/v2/blockchain/beacon/client.go
user: login: oleg-ssvlabs
body: Same as with Execution Nodes. It's worth mentioning that it could be one or multiple addresses
created_at: 2025-03-12T09:41:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -27,8 +27,8 @@ import (
 // Options contains options to create the node
 type Options struct {
 	// NetworkName is the network name of this node
-	NetworkName         string `yaml:"Network" env:"NETWORK" env-default:"mainnet" env-description:"Network is the network of this node"`
-	CustomDomainType    string `yaml:"CustomDomainType" env:"CUSTOM_DOMAIN_TYPE" env-default:"" env-description:"Override the SSV domain type. This is used to isolate the node from the rest of the network. Do not set unless you know what you are doing. This would be incremented by 1 for Alan, for example: 0x01020304 becomes 0x01020305 post-fork."`
+	NetworkName         string `yaml:"Network" env:"NETWORK" env-default:"mainnet" env-description:"Ethereum network to connect to (mainnet, goerli, etc.)"`
path: operator/node.go
user: login: kchojn
body: ahah yes! sorry about that, fixed!
created_at: 2025-03-12T11:19:39Z
author_association: CONTRIBUTOR

PR comments:
user: login: codecov[bot]
created_at: 2025-03-07T08:50:19Z
body: ## [Codecov](https://app.codecov.io/gh/ssvlabs/ssv/pull/2064?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ssvlabs) Report
Attention: Patch coverage is `0%` with `3 lines` in your changes missing coverage. Please review.
> Project coverage is 48.3%. Comparing base [(`79bd142`)](https://app.codecov.io/gh/ssvlabs/ssv/commit/79bd142e6c8e04d80b03e51a870eec7c2cde9481?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ssvlabs) to head [(`27321ba`)](https://app.codecov.io/gh/ssvlabs/ssv/commit/27321ba35481bdff2f1adc68e6b071103682f132?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ssvlabs).
> Report is 11 commits behind head on stage.

| [Files with missing lines](https://app.codecov.io/gh/ssvlabs/ssv/pull/2064?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ssvlabs) | Patch % | Lines |
|---|---|---|
| [cli/bootnode/boot\_node.go](https://app.codecov.io/gh/ssvlabs/ssv/pull/2064?src=pr&el=tree&filepath=cli%2Fbootnode%2Fboot_node.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ssvlabs#diff-Y2xpL2Jvb3Rub2RlL2Jvb3Rfbm9kZS5nbw==) | 0.0% | [1 Missing :warning: ](https://app.codecov.io/gh/ssvlabs/ssv/pull/2064?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ssvlabs) |
| [cli/operator/node.go](https://app.codecov.io/gh/ssvlabs/ssv/pull/2064?src=pr&el=tree&filepath=cli%2Foperator%2Fnode.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ssvlabs#diff-Y2xpL29wZXJhdG9yL25vZGUuZ28=) | 0.0% | [1 Missing :warning: ](https://app.codecov.io/gh/ssvlabs/ssv/pull/2064?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ssvlabs) |
| [logging/global.go](https://app.codecov.io/gh/ssvlabs/ssv/pull/2064?src=pr&el=tree&filepath=logging%2Fglobal.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ssvlabs#diff-bG9nZ2luZy9nbG9iYWwuZ28=) | 0.0% | [1 Missing :warning: ](https://app.codecov.io/gh/ssvlabs/ssv/pull/2064?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ssvlabs) |


[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/ssvlabs/ssv/pull/2064?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ssvlabs).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ssvlabs).

<details><summary>🚀 New features to boost your workflow: </summary>

- ❄ [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- 📦 [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
author_association: NONE
user: login: moshe-blox
created_at: 2025-03-19T10:36:57Z
body: well done @kchojn 
author_association: CONTRIBUTOR