diff --git a/chronik/chronik-bridge/src/ffi.rs b/chronik/chronik-bridge/src/ffi.rs --- a/chronik/chronik-bridge/src/ffi.rs +++ b/chronik/chronik-bridge/src/ffi.rs @@ -270,6 +270,14 @@ max_fee: i64, ) -> Result<[u8; 32]>; + /// Calls `AbortNode` from shutdown.h to gracefully shut down the node + /// when an unrecoverable error occured. + fn abort_node(self: &ChronikBridge, msg: &str, user_msg: &str); + + /// Returns true if a shutdown is requested, false otherwise. + /// See `ShutdownRequested` in `shutdown.h`. + fn shutdown_requested(self: &ChronikBridge) -> bool; + /// Bridge CTransaction -> ffi::Tx, using the given spent coins. fn bridge_tx( tx: &CTransaction, @@ -311,14 +319,6 @@ /// Calls `InitError` from `node/ui_interface.h` to report an error to /// the user and then gracefully shut down the node. fn init_error(msg: &str) -> bool; - - /// Calls `AbortNode` from shutdown.h to gracefully shut down the node - /// when an unrecoverable error occured. - fn abort_node(msg: &str, user_msg: &str); - - /// Returns true if a shutdown is requested, false otherwise. - /// See `ShutdownRequested` in `shutdown.h`. - fn shutdown_requested() -> bool; } } diff --git a/chronik/chronik-cpp/chronik_bridge.h b/chronik/chronik-cpp/chronik_bridge.h --- a/chronik/chronik-cpp/chronik_bridge.h +++ b/chronik/chronik-cpp/chronik_bridge.h @@ -79,6 +79,10 @@ std::array broadcast_tx(rust::Slice raw_tx, int64_t max_fee) const; + + void abort_node(const rust::Str msg, const rust::Str user_msg) const; + + bool shutdown_requested() const; }; std::unique_ptr make_bridge(const Config &config, @@ -105,10 +109,6 @@ bool init_error(const rust::Str msg); -void abort_node(const rust::Str msg, const rust::Str user_msg); - -bool shutdown_requested(); - } // namespace chronik_bridge #endif // BITCOIN_CHRONIK_CPP_CHRONIK_BRIDGE_H diff --git a/chronik/chronik-cpp/chronik_bridge.cpp b/chronik/chronik-cpp/chronik_bridge.cpp --- a/chronik/chronik-cpp/chronik_bridge.cpp +++ b/chronik/chronik-cpp/chronik_bridge.cpp @@ -322,6 +322,15 @@ return chronik::util::HashToArray(tx_ref->GetId()); } +void ChronikBridge::abort_node(const rust::Str msg, + const rust::Str user_msg) const { + AbortNode(std::string(msg), Untranslated(std::string(user_msg))); +} + +bool ChronikBridge::shutdown_requested() const { + return ShutdownRequested(); +} + std::unique_ptr make_bridge(const Config &config, const node::NodeContext &node) { return std::make_unique( @@ -382,12 +391,4 @@ return InitError(Untranslated(std::string(msg))); } -void abort_node(const rust::Str msg, const rust::Str user_msg) { - AbortNode(std::string(msg), Untranslated(std::string(user_msg))); -} - -bool shutdown_requested() { - return ShutdownRequested(); -} - } // namespace chronik_bridge diff --git a/chronik/chronik-indexer/src/indexer.rs b/chronik/chronik-indexer/src/indexer.rs --- a/chronik/chronik-indexer/src/indexer.rs +++ b/chronik/chronik-indexer/src/indexer.rs @@ -235,7 +235,7 @@ }; let tip_height = node_tip_info.height; for height in start_height + 1..=tip_height { - if ffi::shutdown_requested() { + if bridge.shutdown_requested() { log!("Stopped re-sync adding blocks\n"); return Ok(()); } @@ -285,7 +285,7 @@ ); log!("Reverting Chronik blocks {revert_height} to {indexer_height}.\n"); for height in (revert_height..indexer_height).rev() { - if ffi::shutdown_requested() { + if bridge.shutdown_requested() { log!("Stopped re-sync rewinding blocks\n"); // return MAX here so we don't add any blocks return Ok(BlockHeight::MAX); @@ -739,6 +739,19 @@ Ok(()) } +impl Node { + /// If `result` is [`Err`], logs and aborts the node. + pub fn ok_or_abort(&self, func_name: &str, result: Result) { + if let Err(report) = result { + log_chronik!("{report:?}\n"); + self.bridge.abort_node( + &format!("ERROR Chronik in {func_name}"), + &format!("{report:#}"), + ); + } + } +} + impl std::fmt::Debug for ChronikIndexerParams { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("ChronikIndexerParams") diff --git a/chronik/chronik-lib/src/bridge.rs b/chronik/chronik-lib/src/bridge.rs --- a/chronik/chronik-lib/src/bridge.rs +++ b/chronik/chronik-lib/src/bridge.rs @@ -26,10 +26,7 @@ use thiserror::Error; use tokio::sync::RwLock; -use crate::{ - error::ok_or_abort_node, - ffi::{self, StartChronikValidationInterface}, -}; +use crate::ffi::{self, StartChronikValidationInterface}; /// Errors for [`Chronik`] and [`setup_chronik`]. #[derive(Debug, Eq, Error, PartialEq)] @@ -83,7 +80,7 @@ enable_perf_stats: params.enable_perf_stats, })?; indexer.resync_indexer(bridge_ref)?; - if chronik_bridge::ffi::shutdown_requested() { + if bridge.shutdown_requested() { // Don't setup Chronik if the user requested shutdown during resync return Ok(()); } @@ -110,8 +107,11 @@ }) } })?; - runtime.spawn(async move { - ok_or_abort_node("ChronikServer::serve", server.serve().await); + runtime.spawn({ + let node = Arc::clone(&node); + async move { + node.ok_or_abort("ChronikServer::serve", server.serve().await); + } }); let chronik = Box::new(Chronik { node: Arc::clone(&node), @@ -154,7 +154,7 @@ time_first_seen: i64, ) { self.block_if_paused(); - ok_or_abort_node( + self.node.ok_or_abort( "handle_tx_added_to_mempool", self.add_tx_to_mempool(ptx, spent_coins, time_first_seen), ); @@ -165,7 +165,7 @@ self.block_if_paused(); let mut indexer = self.indexer.blocking_write(); let txid = TxId::from(txid); - ok_or_abort_node( + self.node.ok_or_abort( "handle_tx_removed_from_mempool", indexer.handle_tx_removed_from_mempool(txid), ); @@ -179,7 +179,7 @@ bindex: &ffi::CBlockIndex, ) { self.block_if_paused(); - ok_or_abort_node( + self.node.ok_or_abort( "handle_block_connected", self.connect_block(block, bindex), ); @@ -192,7 +192,7 @@ bindex: &ffi::CBlockIndex, ) { self.block_if_paused(); - ok_or_abort_node( + self.node.ok_or_abort( "handle_block_disconnected", self.disconnect_block(block, bindex), ); @@ -201,7 +201,8 @@ /// Block finalized with Avalanche pub fn handle_block_finalized(&self, bindex: &ffi::CBlockIndex) { self.block_if_paused(); - ok_or_abort_node("handle_block_finalized", self.finalize_block(bindex)); + self.node + .ok_or_abort("handle_block_finalized", self.finalize_block(bindex)); } fn add_tx_to_mempool( diff --git a/chronik/chronik-lib/src/error.rs b/chronik/chronik-lib/src/error.rs deleted file mode 100644 --- a/chronik/chronik-lib/src/error.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2022 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -use abc_rust_error::Result; -use chronik_bridge::ffi::abort_node; -use chronik_util::log_chronik; - -/// If `result` is [`Err`], logs and aborts the node. -pub(crate) fn ok_or_abort_node(func_name: &str, result: Result) { - if let Err(report) = result { - log_chronik!("{report:?}\n"); - abort_node( - &format!("ERROR Chronik in {func_name}"), - &format!("{report:#}"), - ); - } -} diff --git a/chronik/chronik-lib/src/lib.rs b/chronik/chronik-lib/src/lib.rs --- a/chronik/chronik-lib/src/lib.rs +++ b/chronik/chronik-lib/src/lib.rs @@ -16,6 +16,5 @@ abc_rust_lint::lint! { pub mod bridge; - mod error; pub mod ffi; }