diff --git a/Cargo.lock b/Cargo.lock index 87accc2f..f3c3e9ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1349,6 +1349,7 @@ dependencies = [ "color-eyre", "eyre", "tokio", + "tracing", "tree_hash 0.8.0", "tree_hash_derive", ] diff --git a/bin/Cargo.toml b/bin/Cargo.toml index ed7493c5..79258d76 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -18,6 +18,9 @@ tokio.workspace = true tree_hash.workspace = true tree_hash_derive.workspace = true +# telemetry +tracing.workspace = true + # misc clap.workspace = true eyre.workspace = true diff --git a/bin/pbs.rs b/bin/pbs.rs index caa72ab7..b8039bec 100644 --- a/bin/pbs.rs +++ b/bin/pbs.rs @@ -1,6 +1,10 @@ -use cb_common::{config::load_pbs_config, utils::initialize_pbs_tracing_log}; +use cb_common::{ + config::load_pbs_config, + utils::{initialize_pbs_tracing_log, wait_for_signal}, +}; use cb_pbs::{DefaultBuilderApi, PbsService, PbsState}; use eyre::Result; +use tracing::{error, info}; #[tokio::main] async fn main() -> Result<()> { @@ -13,7 +17,21 @@ async fn main() -> Result<()> { let pbs_config = load_pbs_config()?; let _guard = initialize_pbs_tracing_log(); + let state = PbsState::new(pbs_config); PbsService::init_metrics()?; - PbsService::run::<_, DefaultBuilderApi>(state).await + let server = PbsService::run::<_, DefaultBuilderApi>(state); + + tokio::select! { + maybe_err = server => { + if let Err(err) = maybe_err { + error!(%err, "PBS service unexpectedly stopped"); + } + }, + _ = wait_for_signal() => { + info!("shutting down"); + } + } + + Ok(()) } diff --git a/bin/signer.rs b/bin/signer.rs index ca838e59..cd9480ad 100644 --- a/bin/signer.rs +++ b/bin/signer.rs @@ -1,9 +1,10 @@ use cb_common::{ config::{StartSignerConfig, SIGNER_MODULE_NAME}, - utils::initialize_tracing_log, + utils::{initialize_tracing_log, wait_for_signal}, }; use cb_signer::service::SigningService; use eyre::Result; +use tracing::{error, info}; #[tokio::main] async fn main() -> Result<()> { @@ -16,5 +17,18 @@ async fn main() -> Result<()> { let config = StartSignerConfig::load_from_env()?; let _guard = initialize_tracing_log(SIGNER_MODULE_NAME); - SigningService::run(config).await + let server = SigningService::run(config); + + tokio::select! { + maybe_err = server => { + if let Err(err) = maybe_err { + error!(%err, "signing server unexpectedly stopped"); + } + }, + _ = wait_for_signal() => { + info!("shutting down"); + } + } + + Ok(()) } diff --git a/bin/src/lib.rs b/bin/src/lib.rs index 44cf8552..e4f566b2 100644 --- a/bin/src/lib.rs +++ b/bin/src/lib.rs @@ -21,7 +21,7 @@ pub mod prelude { get_header, get_status, register_validator, submit_block, BuilderApi, BuilderApiState, DefaultBuilderApi, PbsService, PbsState, }; - // The TreeHash derive macro requires tree_hash:: as import + // The TreeHash derive macro requires tree_hash as import pub mod tree_hash { pub use tree_hash::*; } diff --git a/crates/common/src/utils.rs b/crates/common/src/utils.rs index d2c26ed6..6e1ae273 100644 --- a/crates/common/src/utils.rs +++ b/crates/common/src/utils.rs @@ -246,3 +246,24 @@ pub fn get_user_agent_with_version(req_headers: &HeaderMap) -> eyre::Result eyre::Result<()> { + use tokio::signal::unix::{signal, SignalKind}; + + let mut sigint = signal(SignalKind::interrupt())?; + let mut sigterm = signal(SignalKind::terminate())?; + + tokio::select! { + _ = sigint.recv() => {} + _ = sigterm.recv() => {} + } + + Ok(()) +} + +#[cfg(windows)] +pub async fn wait_for_signal() -> eyre::Result<()> { + tokio::signal::ctrl_c().await?; + Ok(()) +} diff --git a/crates/pbs/src/service.rs b/crates/pbs/src/service.rs index 7b47a179..cd36b5cf 100644 --- a/crates/pbs/src/service.rs +++ b/crates/pbs/src/service.rs @@ -21,10 +21,10 @@ impl PbsService { let address = SocketAddr::from(([0, 0, 0, 0], state.config.pbs_config.port)); let events_subs = state.config.event_publisher.as_ref().map(|e| e.n_subscribers()).unwrap_or_default(); - info!(version = COMMIT_BOOST_VERSION, ?address, events_subs, chain =? state.config.chain, "Starting PBS service"); + info!(version = COMMIT_BOOST_VERSION, ?address, events_subs, chain =? state.config.chain, "starting PBS service"); let app = create_app_router::(state); - let listener = TcpListener::bind(address).await.expect("failed tcp binding"); + let listener = TcpListener::bind(address).await?; axum::serve(listener, app).await.wrap_err("PBS server exited") } diff --git a/crates/signer/src/service.rs b/crates/signer/src/service.rs index 754dda92..be5ad6c4 100644 --- a/crates/signer/src/service.rs +++ b/crates/signer/src/service.rs @@ -22,7 +22,7 @@ use cb_common::{ constants::COMMIT_BOOST_VERSION, types::{Jwt, ModuleId}, }; -use eyre::{Result, WrapErr}; +use eyre::{Context, Result}; use headers::{authorization::Bearer, Authorization}; use tokio::{net::TcpListener, sync::RwLock}; use tracing::{debug, error, info, warn}; @@ -71,12 +71,9 @@ impl SigningService { .route_layer(middleware::from_fn_with_state(state.clone(), jwt_auth)); let address = SocketAddr::from(([0, 0, 0, 0], config.server_port)); - let listener = TcpListener::bind(address).await.wrap_err("failed tcp binding")?; + let listener = TcpListener::bind(address).await?; - if let Err(err) = axum::serve(listener, app).await { - error!(%err, "Signing server exited") - } - Ok(()) + axum::serve(listener, app).await.wrap_err("signer server exited") } }