Contractless/src/main.rs

85 lines
3.2 KiB
Rust
Raw Normal View History

2026-07-12 22:01:00 +00:00
use contractless::exit;
use contractless::log::{error, logger};
use contractless::startup::daemonize::daemonize_after_wallet_prompt;
use contractless::startup::daemonize::handle_control_command;
use contractless::startup::initialize_startup::obtain_startup_wallet;
use contractless::startup::initialize_startup::prepare_pre_wallet_startup;
use contractless::startup::node_runtime::initialize_node_logging;
use contractless::startup::node_runtime::install_panic_cleanup;
use contractless::startup::node_runtime::run_unlocked_node;
use contractless::startup::windows_service::handle_windows_service_command;
use contractless::startup::windows_service::try_run_as_windows_service;
use contractless::Arc;
use contractless::Runtime;
2026-05-24 17:56:57 +00:00
use tokio::runtime::Builder;
fn main() {
// Linux-specific control commands are handled before any startup work begins.
match handle_control_command() {
2026-08-02 16:40:38 +00:00
Ok(true) => return,
2026-05-24 17:56:57 +00:00
Ok(false) => {}
Err(e) => {
eprintln!("Control command failed: {e}");
exit(1);
}
}
// Windows service management commands are also handled before normal node startup.
match handle_windows_service_command() {
Ok(true) => return,
Ok(false) => {}
Err(e) => {
eprintln!("Windows service command failed: {e}");
exit(1);
}
}
// If the binary was launched by the Windows Service Control Manager, the service
// entrypoint takes over and the normal console path stops here.
match try_run_as_windows_service() {
Ok(true) => return,
Ok(false) => {}
Err(e) => {
eprintln!("Failed to start Windows service path: {e}");
exit(1);
}
}
// The pre-wallet startup work runs in a temporary runtime so Linux can daemonize
// only after the wallet key is obtained, while Windows console launches still use
// the same shared startup sequence.
let startup_runtime = Builder::new_current_thread()
.enable_all()
.build()
.expect("Failed to create startup runtime");
startup_runtime.block_on(prepare_pre_wallet_startup());
let wallet = startup_runtime.block_on(obtain_startup_wallet());
2026-05-24 17:56:57 +00:00
drop(startup_runtime);
// Linux detaches after the wallet prompt unless --foreground is supplied.
if let Err(e) = daemonize_after_wallet_prompt() {
eprintln!("Failed to daemonize: {e}");
exit(1);
}
// Once the platform-specific startup path is settled, the shared node runtime
// takes over for normal unlocked operation.
let runtime = Runtime::new().expect("Failed to create main runtime");
let _log_handle = runtime.block_on(async {
match initialize_node_logging().await {
Ok(handle) => Some(handle),
Err(e) => {
eprintln!("Failed to initialize logging: {e}");
None
}
}
});
install_panic_cleanup();
if let Err(e) = runtime.block_on(run_unlocked_node(Arc::new(wallet), true)) {
2026-05-24 17:56:57 +00:00
error!("Failed to start unlocked node runtime: {e}");
logger().flush();
eprintln!("Failed to start unlocked node runtime: {e}");
exit(1);
}
}