use std::{net::SocketAddr, time::Duration};
use color_eyre::Report;
use tokio::task::JoinHandle;
use tower::ServiceBuilder;
use tracing::Instrument;
use zebra_chain::{diagnostic::task::WaitForPanics, parameters::Network};
use zebra_state::ChainTipChange;
use crate::{scan, service::ScanService, storage::Storage, Config};
pub const SCAN_SERVICE_TIMEOUT: Duration = Duration::from_secs(30);
pub async fn init_with_server(
listen_addr: SocketAddr,
config: Config,
network: Network,
state: scan::State,
chain_tip_change: ChainTipChange,
) -> Result<(), Report> {
info!(?config, "starting scan service");
let scan_service = ServiceBuilder::new()
.buffer(10)
.timeout(SCAN_SERVICE_TIMEOUT)
.service(ScanService::new(&config, &network, state, chain_tip_change).await);
info!(?listen_addr, "starting scan gRPC server");
let (server_task, _listen_addr) = zebra_grpc::server::init(listen_addr, scan_service).await?;
server_task.await??;
Ok(())
}
pub fn spawn_init(
config: Config,
network: Network,
state: scan::State,
chain_tip_change: ChainTipChange,
) -> JoinHandle<Result<(), Report>> {
if let Some(listen_addr) = config.listen_addr {
tokio::spawn(
init_with_server(listen_addr, config, network, state, chain_tip_change)
.in_current_span(),
)
} else {
tokio::spawn(
async move {
let storage =
tokio::task::spawn_blocking(move || Storage::new(&config, &network, false))
.wait_for_panics()
.await;
let (_cmd_sender, cmd_receiver) = tokio::sync::mpsc::channel(1);
scan::start(state, chain_tip_change, storage, cmd_receiver).await
}
.in_current_span(),
)
}
}