2026-05-24 17:56:57 +00:00
|
|
|
use blockchain::exit;
|
|
|
|
|
use blockchain::log::{error, logger};
|
|
|
|
|
use blockchain::startup::daemonize::daemonize_after_wallet_prompt;
|
|
|
|
|
use blockchain::startup::daemonize::handle_control_command;
|
2026-06-01 14:29:11 +00:00
|
|
|
use blockchain::startup::initialize_startup::obtain_startup_wallet;
|
2026-05-24 17:56:57 +00:00
|
|
|
use blockchain::startup::initialize_startup::prepare_pre_wallet_startup;
|
|
|
|
|
use blockchain::startup::node_runtime::initialize_node_logging;
|
|
|
|
|
use blockchain::startup::node_runtime::install_panic_cleanup;
|
|
|
|
|
use blockchain::startup::node_runtime::run_unlocked_node;
|
|
|
|
|
use blockchain::startup::windows_service::handle_windows_service_command;
|
|
|
|
|
use blockchain::startup::windows_service::try_run_as_windows_service;
|
2026-06-01 14:29:11 +00:00
|
|
|
use blockchain::Arc;
|
2026-05-24 17:56:57 +00:00
|
|
|
use blockchain::Runtime;
|
|
|
|
|
use tokio::runtime::Builder;
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
// Linux-specific control commands are handled before any startup work begins.
|
|
|
|
|
match handle_control_command() {
|
|
|
|
|
Ok(true) => return,
|
|
|
|
|
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());
|
2026-06-01 14:29:11 +00:00
|
|
|
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();
|
2026-06-01 14:29:11 +00:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|