diff --git a/core/config/config.go b/core/config/config.go index 8fb0278..a5b9a4c 100644 --- a/core/config/config.go +++ b/core/config/config.go @@ -68,12 +68,42 @@ func NewConfig(ctx *cli.Context) (*Config, error) { sdkutils.ReadYamlConfig(configFilePath, &configRaw) } + ethRpcUrl, ok := os.LookupEnv("ETH_RPC_URL") + if ok && ethRpcUrl != "" { + configRaw.EthRpcUrl = ethRpcUrl + } + + EthWsUrl, ok := os.LookupEnv("ETH_WS_URL") + if ok && EthWsUrl != "" { + configRaw.EthWsUrl = EthWsUrl + } + + aggregatorServerIpPortAddress, ok := os.LookupEnv("AGGREGATOR_SERVER_URL") + if ok && aggregatorServerIpPortAddress != "" { + configRaw.AggregatorServerIpPortAddr = aggregatorServerIpPortAddress + } + var deploymentRaw MachAvsDeploymentRaw - deploymentFilePath := ctx.GlobalString(DeploymentFileFlag.Name) - if _, err := os.Stat(deploymentFilePath); errors.Is(err, os.ErrNotExist) { - panic("Path " + deploymentFilePath + " does not exist") + + avsRegistryCoordinatorAddress, rcOk := os.LookupEnv("AVS_REGISTRY_COORDINATOR_ADDRESS") + operatorStateRetrieverAddress, osOk := os.LookupEnv("OPERATOR_STATE_RETRIEVER_ADDRESS") + + if rcOk && osOk && avsRegistryCoordinatorAddress != "" && operatorStateRetrieverAddress != "" { + deploymentRaw.OperatorStateRetrieverAddr = operatorStateRetrieverAddress + deploymentRaw.RegistryCoordinatorAddr = avsRegistryCoordinatorAddress + } else { + deploymentFilePath := ctx.GlobalString(DeploymentFileFlag.Name) + if deploymentFilePath == "" { + panic("If not use env `AVS_REGISTRY_COORDINATOR_ADDRESS` and `OPERATOR_STATE_RETRIEVER_ADDRESS`, should use --avs-deployment to use config for avs contract addresses!") + } + + if _, err := os.Stat(deploymentFilePath); errors.Is(err, os.ErrNotExist) { + panic("Path " + deploymentFilePath + " does not exist") + } + if err := sdkutils.ReadJsonConfig(deploymentFilePath, &deploymentRaw); err != nil { + panic(err) + } } - sdkutils.ReadJsonConfig(deploymentFilePath, &deploymentRaw) logger, err := sdklogging.NewZapLogger(configRaw.Environment) if err != nil { @@ -162,7 +192,7 @@ var ( } DeploymentFileFlag = cli.StringFlag{ Name: "avs-deployment", - Required: true, + Required: false, Usage: "Load avs contract addresses from `FILE`", } EcdsaPrivateKeyFlag = cli.StringFlag{ diff --git a/operator/cmd/main.go b/operator/cmd/main.go index c78100b..cb9e647 100644 --- a/operator/cmd/main.go +++ b/operator/cmd/main.go @@ -41,7 +41,7 @@ func operatorMain(ctx *cli.Context) error { if err != nil { log.Fatalf(err.Error()) } - log.Println("Config:", string(configJson)) + log.Println("Config from file:", string(configJson)) log.Println("initializing operator") operator, err := operator.NewOperatorFromConfig(nodeConfig) diff --git a/operator/operator.go b/operator/operator.go index 129077f..7b84601 100644 --- a/operator/operator.go +++ b/operator/operator.go @@ -2,7 +2,9 @@ package operator import ( "context" + "encoding/json" "fmt" + "log" "os" "strings" @@ -62,12 +64,105 @@ type Operator struct { serviceManagerAddr common.Address } +// use the env config first for some keys +func withEnvConfig(c config.NodeConfig) config.NodeConfig { + // This keys can use the environment: + // + // - `ETH_RPC_URL` : eth_rpc_url + // - `ETH_WS_URL` : eth_ws_url + // - `ECDSA_PRIVATE_KEY_PATH` : ecdsa_private_key_store_path + // - `BLS_PRIVATE_KEY_PATH` : bls_private_key_store_path + // - `AGGREGATOR_SERVER_URL` : eth_rpc_url + // - `EIGEN_METRICS_URL` : eigen_metrics_ip_port_address + // - `NODE_API_URL` : node_api_ip_port_address + // - `ENABLE_METRICS` : enable_metrics + // - `ENABLE_NODE_API` : enable_node_api + // - `AVS_REGISTRY_COORDINATOR_ADDRESS` : avs_registry_coordinator_address + // - `OPERATOR_STATE_RETRIEVER_ADDRESS` : operator_state_retriever_address + // - `OPERATOR_SERVER_URL` : operator_server_ip_port_addr + // - `METADATA_URI` : metadata_uri + + ethRpcUrl, ok := os.LookupEnv("ETH_RPC_URL") + if ok && ethRpcUrl != "" { + c.EthRpcUrl = ethRpcUrl + } + + EthWsUrl, ok := os.LookupEnv("ETH_WS_URL") + if ok && EthWsUrl != "" { + c.EthWsUrl = EthWsUrl + } + + ecdsaPrivateKeyStorePath, ok := os.LookupEnv("ECDSA_PRIVATE_KEY_PATH") + if ok && ecdsaPrivateKeyStorePath != "" { + c.EcdsaPrivateKeyStorePath = ecdsaPrivateKeyStorePath + } + + blsPrivateKeyStorePath, ok := os.LookupEnv("BLS_PRIVATE_KEY_PATH") + if ok && blsPrivateKeyStorePath != "" { + c.BlsPrivateKeyStorePath = blsPrivateKeyStorePath + } + + aggregatorServerIpPortAddress, ok := os.LookupEnv("AGGREGATOR_SERVER_URL") + if ok && aggregatorServerIpPortAddress != "" { + c.AggregatorServerIpPortAddress = aggregatorServerIpPortAddress + } + + eigenMetricsIpPortAddress, ok := os.LookupEnv("EIGEN_METRICS_URL") + if ok && eigenMetricsIpPortAddress != "" { + c.EigenMetricsIpPortAddress = eigenMetricsIpPortAddress + } + + nodeApiIpPortAddress, ok := os.LookupEnv("NODE_API_URL") + if ok && nodeApiIpPortAddress != "" { + c.NodeApiIpPortAddress = nodeApiIpPortAddress + } + + enableMetrics, ok := os.LookupEnv("ENABLE_METRICS") + if ok && enableMetrics != "" { + c.EnableMetrics = enableMetrics == "true" + } + + enableNodeApi, ok := os.LookupEnv("ENABLE_NODE_API") + if ok && enableNodeApi != "" { + c.EnableNodeApi = enableNodeApi == "true" + } + + aVSRegistryCoordinatorAddress, ok := os.LookupEnv("AVS_REGISTRY_COORDINATOR_ADDRESS") + if ok && aVSRegistryCoordinatorAddress != "" { + c.AVSRegistryCoordinatorAddress = aVSRegistryCoordinatorAddress + } + + operatorStateRetrieverAddress, ok := os.LookupEnv("OPERATOR_STATE_RETRIEVER_ADDRESS") + if ok && operatorStateRetrieverAddress != "" { + c.OperatorStateRetrieverAddress = operatorStateRetrieverAddress + } + + operatorServerIpPortAddr, ok := os.LookupEnv("OPERATOR_SERVER_URL") + if ok && operatorServerIpPortAddr != "" { + c.OperatorServerIpPortAddr = operatorServerIpPortAddr + } + + metadataURI, ok := os.LookupEnv("METADATA_URI") + if ok && metadataURI != "" { + c.MetadataURI = metadataURI + } + + configJson, err := json.MarshalIndent(c, "", " ") + if err != nil { + panic(err) + } + + log.Println("Config Env:", string(configJson)) + + return c +} + // TODO(samlaf): config is a mess right now, since the chainio client constructors // // take the config in core (which is shared with aggregator and challenger) -func NewOperatorFromConfig(c config.NodeConfig) (*Operator, error) { +func NewOperatorFromConfig(cfg config.NodeConfig) (*Operator, error) { var logLevel logging.LogLevel - if c.Production { + if cfg.Production { logLevel = sdklogging.Production } else { logLevel = sdklogging.Development @@ -76,6 +171,9 @@ func NewOperatorFromConfig(c config.NodeConfig) (*Operator, error) { if err != nil { return nil, err } + + c := withEnvConfig(cfg) + reg := prometheus.NewRegistry() eigenMetrics := sdkmetrics.NewEigenMetrics(AVS_NAME, c.EigenMetricsIpPortAddress, reg, logger) avsAndEigenMetrics := metrics.NewAvsAndEigenMetrics(AVS_NAME, eigenMetrics, reg)