/ alphaos / main.rs
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  }