From b5b5ee6ed29231648c3bbaf95bab5e2c51c169a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20Dimitroff=20H=C3=B3di?= Date: Wed, 14 Feb 2024 17:50:43 -0300 Subject: [PATCH] Consensus node now can obtain it's public address from an ENV VAR. Also added a endpoint to be able to check config from nodes --- node/tools/src/config.rs | 33 ++++++++++++++++++++----------- node/tools/src/k8s.rs | 10 +++++++++- node/tools/src/main.rs | 8 +++++++- node/tools/src/rpc/methods/mod.rs | 1 + node/tools/src/rpc/server.rs | 20 ++++++++++++++++--- 5 files changed, 56 insertions(+), 16 deletions(-) diff --git a/node/tools/src/config.rs b/node/tools/src/config.rs index 5697febc..69b603ed 100644 --- a/node/tools/src/config.rs +++ b/node/tools/src/config.rs @@ -2,6 +2,7 @@ use crate::{proto, store}; use anyhow::Context as _; use serde_json::{ser::Formatter, Serializer}; +use std::str::FromStr; use std::{ collections::{HashMap, HashSet}, fs, @@ -12,10 +13,7 @@ use zksync_concurrency::ctx; use zksync_consensus_bft as bft; use zksync_consensus_crypto::{read_optional_text, read_required_text, Text, TextFmt}; use zksync_consensus_executor as executor; -use zksync_consensus_roles::{ - node::{self, PublicKey}, - validator, -}; +use zksync_consensus_roles::{node, validator}; use zksync_consensus_storage::{BlockStore, BlockStoreRunner, PersistentBlockStore}; use zksync_protobuf::{required, serde::Serde, ProtoFmt}; @@ -33,10 +31,10 @@ pub fn decode_json(json: &str) -> anyhow::Result /// Encodes a generated proto message to json for arbitrary ProtoFmt. pub(crate) fn encode_json(x: &T) -> String { let s = serde_json::Serializer::pretty(vec![]); - encode_json_with_serializer(x, s) + encode_with_serializer(x, s) } -pub(crate) fn encode_json_with_serializer( +pub(crate) fn encode_with_serializer( x: &T, mut serializer: Serializer, F>, ) -> String { @@ -53,7 +51,7 @@ pub(crate) fn encode_json_with_serializer, - pub gossip_static_outbound: HashMap, + pub gossip_static_inbound: HashSet, + pub gossip_static_outbound: HashMap, +} + +impl AppConfig { + pub fn check_public_addr(&mut self) -> anyhow::Result<()> { + if let Ok(public_addr) = std::env::var("PUBLIC_ADDR") { + self.public_addr = SocketAddr::from_str(&format!("{public_addr}:{NODES_PORT}"))?; + } + Ok(()) + } } impl ProtoFmt for AppConfig { @@ -275,12 +282,16 @@ impl AppConfig { self } - pub fn add_gossip_static_outbound(&mut self, key: PublicKey, addr: SocketAddr) -> &mut Self { + pub fn add_gossip_static_outbound( + &mut self, + key: node::PublicKey, + addr: SocketAddr, + ) -> &mut Self { self.gossip_static_outbound.insert(key, addr); self } - pub fn add_gossip_static_inbound(&mut self, key: PublicKey) -> &mut Self { + pub fn add_gossip_static_inbound(&mut self, key: node::PublicKey) -> &mut Self { self.gossip_static_inbound.insert(key); self } diff --git a/node/tools/src/k8s.rs b/node/tools/src/k8s.rs index e03ee98f..c414b593 100644 --- a/node/tools/src/k8s.rs +++ b/node/tools/src/k8s.rs @@ -105,6 +105,14 @@ pub async fn create_deployment( { "name": "NODE_ID", "value": node_id + }, + { + "name": "PUBLIC_ADDR", + "valueFrom": { + "fieldRef": { + "fieldPath": "status.podIP" + } + } } ], "command": ["./k8s_entrypoint.sh"], @@ -201,7 +209,7 @@ fn get_cli_args(peers: Vec) -> Vec { } else { [ "--add-gossip-static-outbound".to_string(), - config::encode_json_with_serializer( + config::encode_with_serializer( &peers .iter() .map(|e| Serde(e.clone())) diff --git a/node/tools/src/main.rs b/node/tools/src/main.rs index aad9a4cf..428c6c09 100644 --- a/node/tools/src/main.rs +++ b/node/tools/src/main.rs @@ -102,6 +102,9 @@ async fn main() -> anyhow::Result<()> { .load() .context("config_paths().load()")?; + // if `PUBLIC_ADDR` env var is set, use it to override publicAddr in config + configs.app.check_public_addr().context("Public Address")?; + // Add gossipStaticOutbound pairs from cli to config if let Some(addrs) = args.add_gossip_static_outbound { configs @@ -121,7 +124,10 @@ async fn main() -> anyhow::Result<()> { } else { rpc_addr.set_port(rpc_addr.port() + 100); } - let rpc_server = RPCServer::new(rpc_addr); + + // cloning configuration to let RPCServer show it + // TODO this should be queried in real time instead, to reflect any possible change in config + let rpc_server = RPCServer::new(rpc_addr, configs.app.clone()); // Initialize the storage. scope::run!(ctx, |ctx, s| async { diff --git a/node/tools/src/rpc/methods/mod.rs b/node/tools/src/rpc/methods/mod.rs index 2cac6a52..ab8f2fee 100644 --- a/node/tools/src/rpc/methods/mod.rs +++ b/node/tools/src/rpc/methods/mod.rs @@ -10,5 +10,6 @@ pub(crate) trait RPCMethod { fn path() -> &'static str; } +pub(crate) mod config; pub(crate) mod health_check; pub(crate) mod peers; diff --git a/node/tools/src/rpc/server.rs b/node/tools/src/rpc/server.rs index 6d2d5131..3b66dfa0 100644 --- a/node/tools/src/rpc/server.rs +++ b/node/tools/src/rpc/server.rs @@ -1,4 +1,6 @@ -use super::methods::{health_check::HealthCheck, peers::PeersInfo, RPCMethod}; +use crate::AppConfig; + +use super::methods::{config::ConfigInfo, health_check::HealthCheck, peers::PeersInfo, RPCMethod}; use jsonrpsee::server::{middleware::http::ProxyGetRequestLayer, RpcModule, Server}; use std::net::SocketAddr; use zksync_concurrency::{ctx, scope}; @@ -7,11 +9,13 @@ use zksync_concurrency::{ctx, scope}; pub struct RPCServer { /// IP address to bind to. ip_address: SocketAddr, + /// AppConfig + config: AppConfig, } impl RPCServer { - pub fn new(ip_address: SocketAddr) -> Self { - Self { ip_address } + pub fn new(ip_address: SocketAddr, config: AppConfig) -> Self { + Self { ip_address, config } } /// Runs the RPC server. @@ -26,6 +30,10 @@ impl RPCServer { .layer(ProxyGetRequestLayer::new( PeersInfo::path(), PeersInfo::method(), + )?) + .layer(ProxyGetRequestLayer::new( + ConfigInfo::path(), + ConfigInfo::method(), )?); let server = Server::builder() @@ -39,6 +47,12 @@ impl RPCServer { })?; module.register_method(PeersInfo::method(), |params, _| PeersInfo::callback(params))?; + // TODO find a better way to implement this as I had to clone the clone and move it to pass the borrow checker + let config = self.config.clone(); + module.register_method(ConfigInfo::method(), move |_params, _| { + ConfigInfo::info(config.clone()) + })?; + let handle = server.start(module); scope::run!(ctx, |ctx, s| async { s.spawn_bg(async {