diff --git a/Cargo.lock b/Cargo.lock index 7356db3d480..1b0cf63e6ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3628,6 +3628,7 @@ dependencies = [ "async-trait", "axum 0.7.5", "displaydoc 0.2.4 (git+https://github.com/akonradi-signal/displaydoc.git?branch=anonymous-const)", + "error-stack", "eyre", "futures", "iroha_config", diff --git a/cli/src/lib.rs b/cli/src/lib.rs index bc71f8f4027..9af4915a37d 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -391,13 +391,12 @@ impl Iroha { metrics_reporter, ); - tokio::spawn(async move { - torii - .start() - .await - .into_report() - .map_err(|report| report.change_context(StartError::StartTorii)) - }); + let run_torii = torii + .start() + .await + .map_err(|report| report.change_context(StartError::StartTorii))?; + + tokio::spawn(run_torii); Self::spawn_config_updates_broadcasting(kiso.clone(), logger.clone()); diff --git a/torii/Cargo.toml b/torii/Cargo.toml index 08811df2224..16b72092419 100644 --- a/torii/Cargo.toml +++ b/torii/Cargo.toml @@ -46,6 +46,7 @@ axum = { workspace = true, features = ["multipart", "ws", "query", "json", "toki tower-http = { version = "0.5.0", features = ["trace", "timeout"] } tokio = { workspace = true, features = ["sync", "time", "macros"] } eyre = { workspace = true } +error-stack = { workspace = true, features = ["eyre"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true, optional = true } async-trait = { workspace = true } diff --git a/torii/src/lib.rs b/torii/src/lib.rs index 62f6f7bc47b..d1eae9df246 100644 --- a/torii/src/lib.rs +++ b/torii/src/lib.rs @@ -14,8 +14,12 @@ use axum::{ routing::{get, post}, Router, }; -use futures::{stream::FuturesUnordered, StreamExt, TryFutureExt}; -use iroha_config::{base::util::Bytes, parameters::actual::Torii as Config}; +use error_stack::IntoReportCompat; +use futures::{stream::FuturesUnordered, StreamExt, TryStreamExt}; +use iroha_config::{ + base::{util::Bytes, WithOrigin}, + parameters::actual::Torii as Config, +}; #[cfg(feature = "telemetry")] use iroha_core::metrics::MetricsReporter; use iroha_core::{ @@ -58,7 +62,7 @@ pub struct Torii { query_service: LiveQueryStoreHandle, kura: Arc, transaction_max_content_len: Bytes, - address: SocketAddr, + address: WithOrigin, state: Arc, #[cfg(feature = "telemetry")] metrics_reporter: MetricsReporter, @@ -90,7 +94,7 @@ impl Torii { state, #[cfg(feature = "telemetry")] metrics_reporter, - address: config.address.into_value(), + address: config.address, transaction_max_content_len: config.max_content_len, } } @@ -244,25 +248,29 @@ impl Torii { /// /// # Errors /// Can fail due to listening to network or if http server fails - fn start_api(self: Arc) -> eyre::Result>>> { - let torii_address = &self.address; + async fn start_api(self: Arc) -> eyre::Result>>> { + let torii_address = self.address.value(); let handles = torii_address .to_socket_addrs()? - .map(|addr| { + .map(TcpListener::bind) + .collect::>() + .try_collect::>() + .await? + .into_iter() + .map(|listener| { let torii = Arc::clone(&self); let api_router = torii.create_api_router(); let signal = async move { torii.notify_shutdown.notified().await }; let serve_fut = async move { - let listener = TcpListener::bind(addr).await?; axum::serve(listener, api_router) .with_graceful_shutdown(signal) .await + .map_err(eyre::Report::from) }; - - task::spawn(serve_fut.map_err(eyre::Report::from)) + task::spawn(serve_fut) }) .collect(); @@ -274,13 +282,21 @@ impl Torii { /// # Errors /// Can fail due to listening to network or if http server fails #[iroha_futures::telemetry_future] - pub async fn start(self) -> eyre::Result<()> { + pub async fn start( + self, + ) -> error_stack::Result, eyre::Report> { let torii = Arc::new(self); let mut handles = vec![]; - handles.extend(Arc::clone(&torii).start_api()?); + handles.extend( + Arc::clone(&torii) + .start_api() + .await + .into_report() + .map_err(|err| err.attach_printable(torii.address.clone().into_attachment()))?, + ); - handles + let run = handles .into_iter() .collect::>() .for_each(|handle| { @@ -294,10 +310,9 @@ impl Torii { _ => {} } futures::future::ready(()) - }) - .await; + }); - Ok(()) + Ok(run) } }