main.rs
1 // Copyright (c) 2025-2026 ACDC Network 2 // This file is part of the alphaos library. 3 // 4 // Alpha Chain | Delta Chain Protocol 5 // International Monetary Graphite. 6 // 7 // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com). 8 // They built world-class ZK infrastructure. We installed the EASY button. 9 // Their cryptography: elegant. Our modifications: bureaucracy-compatible. 10 // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours. 11 // 12 // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0 13 // All modifications and new work: CC0 1.0 Universal Public Domain Dedication. 14 // No rights reserved. No permission required. No warranty. No refunds. 15 // 16 // https://creativecommons.org/publicdomain/zero/1.0/ 17 // SPDX-License-Identifier: CC0-1.0 18 19 use alphaos_cli::{commands::CLI, helpers::Updater}; 20 use alphavm::utilities::display_error; 21 22 use clap::Parser; 23 #[cfg(feature = "locktick")] 24 use locktick::lock_snapshots; 25 #[cfg(feature = "locktick")] 26 use std::time::Instant; 27 use std::{backtrace::Backtrace, env, panic::catch_unwind}; 28 use tracing::log::logger; 29 30 #[cfg(all(target_os = "linux", target_arch = "x86_64"))] 31 use tikv_jemallocator::Jemalloc; 32 33 #[cfg(all(target_os = "linux", target_arch = "x86_64"))] 34 #[global_allocator] 35 static GLOBAL: Jemalloc = Jemalloc; 36 37 // Obtain information on the build. 38 include!(concat!(env!("OUT_DIR"), "/built.rs")); 39 40 /// Prints a message using `tracing::error` if logging is enabled, otherwise uses `eprintln`. 41 macro_rules! print_error { 42 ($($arg:tt)*) => { 43 if tracing::log::log_enabled!(tracing::log::Level::Error) { 44 tracing::error!($($arg)*); 45 } else { 46 eprintln!($($arg)*); 47 } 48 }; 49 } 50 51 /// Stops the process with the given exit code. 52 fn exit(exitcode: i32) -> ! { 53 tracing::debug!("Stopping process with exitcode {exitcode}"); 54 55 // Ensure all log messages are written before the process terminates. 56 logger().flush(); 57 58 // Perform the system call to exit the process. 59 std::process::exit(exitcode); 60 } 61 62 fn main() { 63 // A hack to avoid having to go through clap to display advanced version information. 64 check_for_version(); 65 66 #[cfg(feature = "locktick")] 67 std::thread::spawn(|| loop { 68 tracing::info!("[locktick] checking for active lock guards"); 69 let ts = Instant::now(); 70 let mut infos = lock_snapshots(); 71 infos.sort_unstable_by(|l1, l2| l1.location.cmp(&l2.location)); 72 73 for lock in infos { 74 let mut guards = lock.known_guards.values().collect::<Vec<_>>(); 75 guards.sort_unstable_by(|g1, g2| g1.location.cmp(&g2.location)); 76 77 for guard in guards.iter().filter(|g| g.num_active_uses() != 0) { 78 let location = &guard.location; 79 let kind = guard.kind; 80 let num_uses = guard.num_uses; 81 let active_users = guard.num_active_uses(); 82 let avg_duration = guard.avg_duration(); 83 let avg_wait_time = guard.avg_wait_time(); 84 tracing::info!( 85 "[locktick] {location} ({:?}): {num_uses}; {active_users} active; avg d: {:?}; avg w: {:?}", 86 kind, 87 avg_duration, 88 avg_wait_time 89 ); 90 } 91 } 92 tracing::debug!("[locktick] finished the check in {:?}", ts.elapsed()); 93 std::thread::sleep(std::time::Duration::from_secs(3)); 94 }); 95 96 // Set a custom hook here to show "pretty" errors when panicking. 97 std::panic::set_hook(Box::new(|err| { 98 print_error!("⚠️ {}\n", err.to_string().replace("panicked at", "alphaos encountered an unexpected error at")); 99 100 // Always show backtraces. 101 let backtrace = Backtrace::force_capture().to_string(); 102 103 let mut msg = "Backtrace:\n".to_string(); 104 msg.push_str(" [...]\n"); 105 106 // Remove all the low level frames. 107 // This can be done more cleanly once the `backtrace_frames` feature is stabilized. 108 let lines = backtrace.lines().skip_while(|line| !line.contains("core::panicking")); 109 110 for line in lines { 111 // Stop printing once we hit the panic handler. 112 if line.contains("alphaos::main") { 113 break; 114 } 115 116 msg.push_str(&format!("{line}\n")); 117 } 118 119 // Print the entire backtrace as a single log message. 120 print_error!("{msg}"); 121 })); 122 123 // Run the CLI. 124 // We use `catch_unwind` here to ensure a panic stops execution and not just a single thread. 125 // Note: `catch_unwind` can be nested without problems. 126 let result = catch_unwind(|| { 127 // Parse the given arguments. 128 let cli = CLI::parse(); 129 130 // Run the updater. 131 if !cli.noupdater { 132 if let Some(msg) = Updater::print_cli() { 133 println!("{msg}"); 134 } 135 } 136 137 // Run the CLI. 138 cli.command.parse() 139 }); 140 141 // Process any errors (including panics). 142 match result { 143 Ok(Ok(output)) => { 144 println!("{output}\n"); 145 exit(0); 146 } 147 Ok(Err(err)) => { 148 // A regular error occurred. 149 display_error(&err); 150 eprintln!(); 151 eprintln!("Use `--help` for instructions on how to use this command"); 152 153 exit(1); 154 } 155 Err(_) => { 156 print_error!( 157 "This is most likely a bug!\n\ 158 Please report it to the alphaos developers: https://github.com/ProvableHQ/alphaos/issues/new?template=bug.md" 159 ); 160 161 exit(1); 162 } 163 } 164 } 165 166 /// Checks whether the version information was requested and - if so - display it and exit. 167 fn check_for_version() { 168 if let Some(first_arg) = env::args().nth(1) { 169 if ["--version", "-V"].contains(&&*first_arg) { 170 let branch = GIT_HEAD_REF.unwrap_or("unknown_branch"); 171 let commit = GIT_COMMIT_HASH.unwrap_or("unknown_commit"); 172 let mut features = FEATURES_LOWERCASE_STR.to_owned(); 173 features.retain(|c| c != ' '); 174 175 println!("alphaos {branch} {commit} features=[{features}]"); 176 177 exit(0); 178 } 179 } 180 }