#[macro_use] extern crate tracing; mod cli; mod client; mod config; mod log; use crate::config::ZgsConfig; use client::{Client, ClientBuilder, RuntimeContext}; use std::error::Error; async fn start_node(context: RuntimeContext, config: ZgsConfig) -> Result { let network_config = config.network_config().await?; let storage_config = config.storage_config()?; let log_sync_config = config.log_sync_config()?; let chunk_pool_config = config.chunk_pool_config()?; let miner_config = config.mine_config()?; let router_config = config.router_config(&network_config)?; let pruner_config = config.pruner_config()?; let shard_config = config.shard_config()?; ClientBuilder::default() .with_runtime_context(context) .with_rocksdb_store(&storage_config)? .with_log_sync(log_sync_config) .await? .with_file_location_cache(config.file_location_cache) .with_network(&network_config) .await? .with_chunk_pool(chunk_pool_config) .await? .with_sync(config.sync) .await? .with_miner(miner_config) .await? .with_shard(shard_config) .await? .with_pruner(pruner_config) .await? .with_rpc(config.rpc) .await? .with_router(router_config)? .build() } fn main() -> Result<(), Box> { // Only allow 64-bit targets for compilation, since there are many // type conversions between `usize` and `u64`, or even use `usize` // as file size or chunk index. #[cfg(not(target_pointer_width = "64"))] compile_error!("compilation is only allowed for 64-bit targets"); // enable backtraces std::env::set_var("RUST_BACKTRACE", "1"); // runtime environment let mut environment = client::EnvironmentBuilder::new() .multi_threaded_tokio_runtime()? .build()?; let context = environment.core_context(); let executor = context.executor.clone(); // CLI, config, and logs let matches = cli::cli_app().get_matches(); let config = ZgsConfig::parse(&matches)?; metrics::initialize(config.metrics.clone()); log::configure( &config.log_config_file, &config.log_directory, executor.clone(), ); // start services executor.clone().spawn( async move { info!("Starting services..."); if let Err(e) = start_node(context.clone(), config).await { error!(reason = %e, "Failed to start zgs node"); // Ignore the error since it always occurs during normal operation when // shutting down. let _ = executor .shutdown_sender() .try_send(task_executor::ShutdownReason::Failure( "Failed to start zgs node", )); } else { info!("Services started"); } }, "zgs_node", ); // Block this thread until we get a ctrl-c or a task sends a shutdown signal. let shutdown_reason = environment.block_until_shutdown_requested()?; info!(reason = ?shutdown_reason, "Shutting down..."); environment.fire_signal(); // Shutdown the environment once all tasks have completed. environment.shutdown_on_idle(); match shutdown_reason { task_executor::ShutdownReason::Success(_) => Ok(()), task_executor::ShutdownReason::Failure(msg) => Err(msg.to_string().into()), } }