Skip to content

Commit

Permalink
feat: Add support for health check endpoint (#410)
Browse files Browse the repository at this point in the history
  • Loading branch information
popzxc authored Nov 22, 2024
1 parent de9ce0f commit 2b7b45c
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 9 deletions.
2 changes: 0 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ zksync_utils = { git = "https://github.com/matter-labs/zksync-era.git", rev = "6
zksync_web3_decl = { git = "https://github.com/matter-labs/zksync-era.git", rev = "6c034f6e180cc92e99766f14c8840c90efa56cec", features = [
"server",
] }
sha3 = "0.10.6"

# alloy
alloy-signer-local = { version = "0.5.4", features = ["mnemonic"] }
Expand Down Expand Up @@ -59,7 +58,6 @@ rustc-hash = "1.1.0"
indexmap = "2.0.1"
chrono = { version = "0.4.31", default-features = false }
time = "0.3.36"
toml = "0.8.13"
rand = "0.8"

[dev-dependencies]
Expand Down
13 changes: 12 additions & 1 deletion src/config/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ pub struct Cli {
/// Run in offline mode (disables all network requests).
pub offline: bool,

#[arg(long, help_heading = "General Options")]
/// Enable health check endpoint.
/// It will be available for GET requests at /health.
/// The endpoint will return 200 OK if the node is healthy.
pub health_check_endpoint: bool,

/// Writes output of `era-test-node` as json to user-specified file.
#[arg(long, value_name = "OUT_FILE", help_heading = "General Options")]
pub config_out: Option<String>,
Expand Down Expand Up @@ -293,7 +299,12 @@ impl Cli {
}))
.with_chain_id(self.chain_id)
.set_config_out(self.config_out)
.with_evm_emulator(if self.emulate_evm { Some(true) } else { None });
.with_evm_emulator(if self.emulate_evm { Some(true) } else { None })
.with_health_check_endpoint(if self.health_check_endpoint {
Some(true)
} else {
None
});

if self.emulate_evm && self.dev_system_contracts != Some(SystemContractsOptions::Local) {
return Err(eyre::eyre!(
Expand Down
25 changes: 25 additions & 0 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ pub struct TestNodeConfig {
pub signer_accounts: Vec<PrivateKeySigner>,
/// Whether the node operates in offline mode
pub offline: bool,
/// Whether we need to enable the health check endpoint.
pub health_check_endpoint: bool,
}

impl Default for TestNodeConfig {
Expand Down Expand Up @@ -143,6 +145,7 @@ impl Default for TestNodeConfig {

// Offline mode disabled by default
offline: false,
health_check_endpoint: false,
}
}
}
Expand Down Expand Up @@ -287,6 +290,14 @@ impl TestNodeConfig {
"Disabled".red()
}
);
tracing::info!(
"Health Check Endpoint: {}",
if self.health_check_endpoint {
"Enabled".green()
} else {
"Disabled".red()
}
);
println!("\n");
tracing::info!("========================================");
tracing::info!(
Expand Down Expand Up @@ -623,6 +634,20 @@ impl TestNodeConfig {
pub fn is_offline(&self) -> bool {
self.offline
}

/// Set the health check endpoint mode
#[must_use]
pub fn with_health_check_endpoint(mut self, health_check_endpoint: Option<bool>) -> Self {
if let Some(health_check_endpoint) = health_check_endpoint {
self.health_check_endpoint = health_check_endpoint;
}
self
}

/// Get the health check endpoint mode status
pub fn is_health_check_endpoint_endpoint_enabled(&self) -> bool {
self.health_check_endpoint
}
}

/// Account Generator
Expand Down
14 changes: 10 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ async fn build_json_http<
addr: SocketAddr,
log_level_filter: LevelFilter,
node: InMemoryNode<S>,
enable_health_api: bool,
) -> tokio::task::JoinHandle<()> {
let (sender, recv) = oneshot::channel::<()>();

Expand All @@ -88,11 +89,15 @@ async fn build_json_http<
.build()
.unwrap();

let server = jsonrpc_http_server::ServerBuilder::new(io_handler)
let mut builder = jsonrpc_http_server::ServerBuilder::new(io_handler)
.threads(1)
.event_loop_executor(runtime.handle().clone())
.start_http(&addr)
.unwrap();
.event_loop_executor(runtime.handle().clone());

if enable_health_api {
builder = builder.health_api(("/health", "web3_clientVersion"));
}

let server = builder.start_http(&addr).unwrap();

server.wait();
let _ = sender;
Expand Down Expand Up @@ -293,6 +298,7 @@ async fn main() -> anyhow::Result<()> {
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), config.port),
log_level_filter,
node,
config.health_check_endpoint,
)
.await;

Expand Down

0 comments on commit 2b7b45c

Please sign in to comment.