From cde5294bf91567ea76a38184b84fc5f67023029b Mon Sep 17 00:00:00 2001 From: Boog900 <54e72d8a-345f-4599-bd90-c6b9bc7d0ec5@aleeas.com> Date: Tue, 19 Nov 2024 02:11:02 +0000 Subject: [PATCH] add startup code --- Cargo.lock | 32 +++-- Cargo.toml | 7 +- binaries/cuprated/src/blockchain.rs | 1 + binaries/cuprated/src/commands.rs | 58 +++++++++ binaries/cuprated/src/config.rs | 14 ++- .../cuprated/src/config/tracing_config.rs | 2 +- binaries/cuprated/src/main.rs | 116 +++++++++++++++++- 7 files changed, 205 insertions(+), 25 deletions(-) create mode 100644 binaries/cuprated/src/commands.rs diff --git a/Cargo.lock b/Cargo.lock index 4ccf365b..d5a47118 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1117,7 +1117,7 @@ dependencies = [ [[package]] name = "dalek-ff-group" version = "0.4.1" -source = "git+https://github.com/Cuprate/serai.git?rev=d5205ce#d5205ce2319e09414eb91d12cf38e83a08165f79" +source = "git+https://github.com/Cuprate/serai.git?rev=e6fdef6#e6fdef6d0b4481932ac9647796eb3fa56197ed66" dependencies = [ "crypto-bigint", "curve25519-dalek", @@ -1262,7 +1262,7 @@ dependencies = [ [[package]] name = "flexible-transcript" version = "0.3.2" -source = "git+https://github.com/Cuprate/serai.git?rev=d5205ce#d5205ce2319e09414eb91d12cf38e83a08165f79" +source = "git+https://github.com/Cuprate/serai.git?rev=e6fdef6#e6fdef6d0b4481932ac9647796eb3fa56197ed66" dependencies = [ "blake2", "digest", @@ -1823,7 +1823,7 @@ dependencies = [ [[package]] name = "monero-address" version = "0.1.0" -source = "git+https://github.com/Cuprate/serai.git?rev=d5205ce#d5205ce2319e09414eb91d12cf38e83a08165f79" +source = "git+https://github.com/Cuprate/serai.git?rev=e6fdef6#e6fdef6d0b4481932ac9647796eb3fa56197ed66" dependencies = [ "curve25519-dalek", "monero-io", @@ -1836,7 +1836,7 @@ dependencies = [ [[package]] name = "monero-borromean" version = "0.1.0" -source = "git+https://github.com/Cuprate/serai.git?rev=d5205ce#d5205ce2319e09414eb91d12cf38e83a08165f79" +source = "git+https://github.com/Cuprate/serai.git?rev=e6fdef6#e6fdef6d0b4481932ac9647796eb3fa56197ed66" dependencies = [ "curve25519-dalek", "monero-generators", @@ -1849,7 +1849,7 @@ dependencies = [ [[package]] name = "monero-bulletproofs" version = "0.1.0" -source = "git+https://github.com/Cuprate/serai.git?rev=d5205ce#d5205ce2319e09414eb91d12cf38e83a08165f79" +source = "git+https://github.com/Cuprate/serai.git?rev=e6fdef6#e6fdef6d0b4481932ac9647796eb3fa56197ed66" dependencies = [ "curve25519-dalek", "monero-generators", @@ -1864,7 +1864,7 @@ dependencies = [ [[package]] name = "monero-clsag" version = "0.1.0" -source = "git+https://github.com/Cuprate/serai.git?rev=d5205ce#d5205ce2319e09414eb91d12cf38e83a08165f79" +source = "git+https://github.com/Cuprate/serai.git?rev=e6fdef6#e6fdef6d0b4481932ac9647796eb3fa56197ed66" dependencies = [ "curve25519-dalek", "dalek-ff-group", @@ -1884,7 +1884,7 @@ dependencies = [ [[package]] name = "monero-generators" version = "0.4.0" -source = "git+https://github.com/Cuprate/serai.git?rev=d5205ce#d5205ce2319e09414eb91d12cf38e83a08165f79" +source = "git+https://github.com/Cuprate/serai.git?rev=e6fdef6#e6fdef6d0b4481932ac9647796eb3fa56197ed66" dependencies = [ "curve25519-dalek", "dalek-ff-group", @@ -1898,7 +1898,7 @@ dependencies = [ [[package]] name = "monero-io" version = "0.1.0" -source = "git+https://github.com/Cuprate/serai.git?rev=d5205ce#d5205ce2319e09414eb91d12cf38e83a08165f79" +source = "git+https://github.com/Cuprate/serai.git?rev=e6fdef6#e6fdef6d0b4481932ac9647796eb3fa56197ed66" dependencies = [ "curve25519-dalek", "std-shims", @@ -1907,7 +1907,7 @@ dependencies = [ [[package]] name = "monero-mlsag" version = "0.1.0" -source = "git+https://github.com/Cuprate/serai.git?rev=d5205ce#d5205ce2319e09414eb91d12cf38e83a08165f79" +source = "git+https://github.com/Cuprate/serai.git?rev=e6fdef6#e6fdef6d0b4481932ac9647796eb3fa56197ed66" dependencies = [ "curve25519-dalek", "monero-generators", @@ -1921,7 +1921,7 @@ dependencies = [ [[package]] name = "monero-primitives" version = "0.1.0" -source = "git+https://github.com/Cuprate/serai.git?rev=d5205ce#d5205ce2319e09414eb91d12cf38e83a08165f79" +source = "git+https://github.com/Cuprate/serai.git?rev=e6fdef6#e6fdef6d0b4481932ac9647796eb3fa56197ed66" dependencies = [ "curve25519-dalek", "monero-generators", @@ -1934,9 +1934,8 @@ dependencies = [ [[package]] name = "monero-rpc" version = "0.1.0" -source = "git+https://github.com/Cuprate/serai.git?rev=d5205ce#d5205ce2319e09414eb91d12cf38e83a08165f79" +source = "git+https://github.com/Cuprate/serai.git?rev=e6fdef6#e6fdef6d0b4481932ac9647796eb3fa56197ed66" dependencies = [ - "async-trait", "curve25519-dalek", "hex", "monero-address", @@ -1951,7 +1950,7 @@ dependencies = [ [[package]] name = "monero-serai" version = "0.1.4-alpha" -source = "git+https://github.com/Cuprate/serai.git?rev=d5205ce#d5205ce2319e09414eb91d12cf38e83a08165f79" +source = "git+https://github.com/Cuprate/serai.git?rev=e6fdef6#e6fdef6d0b4481932ac9647796eb3fa56197ed66" dependencies = [ "curve25519-dalek", "hex-literal", @@ -1969,9 +1968,8 @@ dependencies = [ [[package]] name = "monero-simple-request-rpc" version = "0.1.0" -source = "git+https://github.com/Cuprate/serai.git?rev=d5205ce#d5205ce2319e09414eb91d12cf38e83a08165f79" +source = "git+https://github.com/Cuprate/serai.git?rev=e6fdef6#e6fdef6d0b4481932ac9647796eb3fa56197ed66" dependencies = [ - "async-trait", "digest_auth", "hex", "monero-rpc", @@ -2688,7 +2686,7 @@ dependencies = [ [[package]] name = "simple-request" version = "0.1.0" -source = "git+https://github.com/Cuprate/serai.git?rev=d5205ce#d5205ce2319e09414eb91d12cf38e83a08165f79" +source = "git+https://github.com/Cuprate/serai.git?rev=e6fdef6#e6fdef6d0b4481932ac9647796eb3fa56197ed66" dependencies = [ "http-body-util", "hyper", @@ -2748,7 +2746,7 @@ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "std-shims" version = "0.1.1" -source = "git+https://github.com/Cuprate/serai.git?rev=d5205ce#d5205ce2319e09414eb91d12cf38e83a08165f79" +source = "git+https://github.com/Cuprate/serai.git?rev=e6fdef6#e6fdef6d0b4481932ac9647796eb3fa56197ed66" dependencies = [ "hashbrown 0.14.5", "spin", diff --git a/Cargo.toml b/Cargo.toml index 7a4b1fc4..c3588190 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,7 @@ codegen-units = 1 # Optimize for binary speed over compile times opt-level = 3 [profile.dev] +panic = "abort" lto = false strip = "none" # Not much slower compile times than opt-level 0, but much faster code. @@ -103,7 +104,7 @@ futures = { version = "0.3", default-features = false } hex = { version = "0.4", default-features = false } hex-literal = { version = "0.4", default-features = false } indexmap = { version = "2", default-features = false } -monero-serai = { git = "https://github.com/Cuprate/serai.git", rev = "d5205ce", default-features = false } +monero-serai = { git = "https://github.com/Cuprate/serai.git", rev = "e6fdef6", default-features = false } paste = { version = "1", default-features = false } pin-project = { version = "1", default-features = false } randomx-rs = { git = "https://github.com/Cuprate/randomx-rs.git", rev = "0028464", default-features = false } @@ -125,8 +126,8 @@ tracing-subscriber = { version = "0.3", default-features = false } tracing = { version = "0.1", default-features = false } ## workspace.dev-dependencies -monero-rpc = { git = "https://github.com/Cuprate/serai.git", rev = "d5205ce" } -monero-simple-request-rpc = { git = "https://github.com/Cuprate/serai.git", rev = "d5205ce" } +monero-rpc = { git = "https://github.com/Cuprate/serai.git", rev = "e6fdef6" } +monero-simple-request-rpc = { git = "https://github.com/Cuprate/serai.git", rev = "e6fdef6" } tempfile = { version = "3" } pretty_assertions = { version = "1" } proptest = { version = "1" } diff --git a/binaries/cuprated/src/blockchain.rs b/binaries/cuprated/src/blockchain.rs index c4b75e4e..63bbded3 100644 --- a/binaries/cuprated/src/blockchain.rs +++ b/binaries/cuprated/src/blockchain.rs @@ -25,6 +25,7 @@ mod manager; mod syncer; mod types; +pub use manager::init_blockchain_manager; pub use types::{ ConcreteBlockVerifierService, ConcreteTxVerifierService, ConsensusBlockchainReadHandle, }; diff --git a/binaries/cuprated/src/commands.rs b/binaries/cuprated/src/commands.rs new file mode 100644 index 00000000..06a42722 --- /dev/null +++ b/binaries/cuprated/src/commands.rs @@ -0,0 +1,58 @@ +use clap::{builder::TypedValueParser, Parser}; +use std::io; +use std::io::Stdin; +use std::iter::once; +use std::thread::sleep; +use std::time::Duration; +use tokio::sync::mpsc; +use tracing::level_filters::LevelFilter; + +// strip out usage +const PARSER_TEMPLATE: &str = "\ + {all-args} + "; +// strip out name/version +const APPLET_TEMPLATE: &str = "\ + {about-with-newline}\n\ + {all-args}\ + "; + +#[derive(Debug, Parser)] +#[command(multicall = true, subcommand_required = true, rename_all = "snake_case", help_template = PARSER_TEMPLATE, arg_required_else_help = true, disable_help_flag = true)] +pub enum Command { + /// Change the log output. + #[command(arg_required_else_help = true, help_template = APPLET_TEMPLATE)] + SetLog { + /// The minimum log level that will be displayed. + #[arg( + short, long, + value_parser = clap::builder::PossibleValuesParser::new(["off", "trace", "debug", "info", "warn", "error"]) + .map(|s| s.parse::().unwrap()), + )] + level: LevelFilter, + }, + /// Print status information on `cuprated`. + #[command(help_template = APPLET_TEMPLATE)] + Status, +} + +pub fn command_listener(incoming_commands: mpsc::Sender) -> ! { + let mut stdin = io::stdin(); + let mut line = String::new(); + + loop { + match stdin.read_line(&mut line) { + Ok(_) => match Command::try_parse_from(line.trim().split(' ')) { + Ok(command) => incoming_commands.blocking_send(command).unwrap(), + Err(err) => err.print().unwrap(), + }, + Err(e) => { + println!("Failed to read from stdin: {e}"); + + sleep(Duration::from_secs(1)); + } + } + + line.clear(); + } +} diff --git a/binaries/cuprated/src/config.rs b/binaries/cuprated/src/config.rs index 6b1229f8..897d4eb0 100644 --- a/binaries/cuprated/src/config.rs +++ b/binaries/cuprated/src/config.rs @@ -72,7 +72,7 @@ pub struct Config { network: Network, /// [`tracing`] config. - tracing: TracingConfig, + pub tracing: TracingConfig, /// The P2P network config. p2p: P2PConfig, @@ -152,6 +152,18 @@ impl Config { .build() } + /// The [`cuprate_txpool`] config. + pub fn txpool_config(&self) -> cuprate_txpool::config::Config { + let txpool = &self.storage.txpool; + + // We don't set reader threads as we manually make the reader threadpool. + cuprate_txpool::config::ConfigBuilder::default() + .network(self.network) + .data_directory(self.fs.data_directory.clone()) + .sync_mode(txpool.shared.sync_mode) + .build() + } + /// The [`BlockDownloaderConfig`]. pub fn block_downloader_config(&self) -> BlockDownloaderConfig { self.p2p.block_downloader.clone().into() diff --git a/binaries/cuprated/src/config/tracing_config.rs b/binaries/cuprated/src/config/tracing_config.rs index 859d516a..8b2f2dcd 100644 --- a/binaries/cuprated/src/config/tracing_config.rs +++ b/binaries/cuprated/src/config/tracing_config.rs @@ -7,7 +7,7 @@ use tracing::level_filters::LevelFilter; pub struct TracingConfig { /// The default minimum log level. #[serde(with = "level_filter_serde")] - level: LevelFilter, + pub level: LevelFilter, } impl Default for TracingConfig { diff --git a/binaries/cuprated/src/main.rs b/binaries/cuprated/src/main.rs index 617c5b61..0d06eced 100644 --- a/binaries/cuprated/src/main.rs +++ b/binaries/cuprated/src/main.rs @@ -16,7 +16,18 @@ reason = "TODO: remove after v1.0.0" )] +use crate::commands::Command; +use crate::config::Config; +use cuprate_helper::time::secs_to_hms; +use tokio::sync::mpsc; +use tracing::level_filters::LevelFilter; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::reload::Handle; +use tracing_subscriber::util::SubscriberInitExt; +use tracing_subscriber::Registry; + mod blockchain; +mod commands; mod config; mod constants; mod p2p; @@ -29,8 +40,107 @@ fn main() { // Initialize global static `LazyLock` data. statics::init_lazylock_statics(); - let _config = config::read_config_and_args(); + let config = config::read_config_and_args(); - // TODO: everything else. - todo!() + let log_level_handle = init_logging(&config); + + let rt = init_tokio_rt(); + + let (mut blockchain_read_handle, mut blockchain_write_handle, _) = + cuprate_blockchain::service::init(config.blockchain_config()).unwrap(); + let (txpool_read_handle, txpool_write_handle, _) = + cuprate_txpool::service::init(config.txpool_config()).unwrap(); + + rt.block_on(async move { + blockchain::check_add_genesis( + &mut blockchain_read_handle, + &mut blockchain_write_handle, + config.network(), + ) + .await; + + let (block_verifier, tx_verifier, context_svc) = + blockchain::init_consensus(blockchain_read_handle.clone(), config.context_config()) + .await + .unwrap(); + + let (clearnet, incoming_tx_handler_tx) = p2p::start_clearnet_p2p( + blockchain_read_handle.clone(), + context_svc.clone(), + txpool_read_handle.clone(), + config.clearnet_p2p_config(), + ) + .await + .unwrap(); + + let tx_handler = txpool::IncomingTxHandler::init( + clearnet.clone(), + txpool_write_handle.clone(), + txpool_read_handle, + context_svc.clone(), + tx_verifier, + ); + if incoming_tx_handler_tx.send(tx_handler).is_err() { + unreachable!() + } + + blockchain::init_blockchain_manager( + clearnet, + blockchain_write_handle, + blockchain_read_handle, + txpool_write_handle, + context_svc, + block_verifier, + config.block_downloader_config(), + ) + .await; + + let (command_tx, command_rx) = mpsc::channel(1); + std::thread::spawn(|| commands::command_listener(command_tx)); + + io_loop(command_rx, log_level_handle).await; + }); +} + +fn init_logging(config: &Config) -> Handle { + let (filter, handle) = tracing_subscriber::reload::Layer::new(config.tracing.level); + + tracing_subscriber::registry() + .with(filter) + .with(tracing_subscriber::fmt::Layer::default().with_target(false)) + .init(); + + handle +} + +fn init_tokio_rt() -> tokio::runtime::Runtime { + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() +} + +async fn io_loop( + mut incoming_commands: mpsc::Receiver, + tracing_level_handle: Handle, +) -> ! { + while let Some(command) = incoming_commands.recv().await { + match command { + Command::SetLog { level } => { + tracing_level_handle + .modify(|filter| *filter = level) + .unwrap(); + + println!("LOG LEVEL CHANGED: {level}"); + } + Command::Status => { + let uptime = statics::START_INSTANT.elapsed().unwrap_or_default(); + let (days, minutes, second) = secs_to_hms(uptime.as_secs()); + + println!("STATUS:\n uptime: {days}d {minutes}m {second}s"); + } + } + } + + unreachable!() }