diff --git a/src/Makefile.am b/src/Makefile.am index 4e9c161c57d..e1ae049b15a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -956,7 +956,6 @@ libbitcoinkernel_la_SOURCES = \ script/script_error.cpp \ script/sigcache.cpp \ script/standard.cpp \ - shutdown.cpp \ signet.cpp \ support/cleanse.cpp \ support/lockedpool.cpp \ diff --git a/src/bitcoin-chainstate.cpp b/src/bitcoin-chainstate.cpp index 45fd239e20f..580a6badd65 100644 --- a/src/bitcoin-chainstate.cpp +++ b/src/bitcoin-chainstate.cpp @@ -81,9 +81,10 @@ int main(int argc, char* argv[]) class KernelNotifications : public kernel::Notifications { public: - void blockTip(SynchronizationState, CBlockIndex&) override + kernel::InterruptResult blockTip(SynchronizationState, CBlockIndex&) override { std::cout << "Block tip changed" << std::endl; + return {}; } void headerTip(SynchronizationState, int64_t height, int64_t timestamp, bool presync) override { diff --git a/src/init.cpp b/src/init.cpp index 2f4eec060b6..f726fe54cae 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -123,6 +123,7 @@ using node::CacheSizes; using node::CalculateCacheSizes; using node::DEFAULT_PERSIST_MEMPOOL; using node::DEFAULT_PRINTPRIORITY; +using node::DEFAULT_STOPATHEIGHT; using node::fReindex; using node::KernelNotifications; using node::LoadChainstate; @@ -1408,6 +1409,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) // ********************************************************* Step 7: load block chain node.notifications = std::make_unique(node.exit_status); + ReadNotificationArgs(args, *node.notifications); fReindex = args.GetBoolArg("-reindex", false); bool fReindexChainState = args.GetBoolArg("-reindex-chainstate", false); ChainstateManager::Options chainman_opts{ diff --git a/src/kernel/chainstatemanager_opts.h b/src/kernel/chainstatemanager_opts.h index 035a913d104..917f7d226c5 100644 --- a/src/kernel/chainstatemanager_opts.h +++ b/src/kernel/chainstatemanager_opts.h @@ -21,7 +21,6 @@ class CChainParams; static constexpr bool DEFAULT_CHECKPOINTS_ENABLED{true}; static constexpr auto DEFAULT_MAX_TIP_AGE{24h}; -static constexpr int DEFAULT_STOPATHEIGHT{0}; namespace kernel { @@ -46,7 +45,6 @@ struct ChainstateManagerOpts { DBOptions coins_db{}; CoinsViewOptions coins_view{}; Notifications& notifications; - int stop_at_height{DEFAULT_STOPATHEIGHT}; }; } // namespace kernel diff --git a/src/kernel/notifications_interface.h b/src/kernel/notifications_interface.h index e596a144a88..c5e77b0df90 100644 --- a/src/kernel/notifications_interface.h +++ b/src/kernel/notifications_interface.h @@ -9,12 +9,25 @@ #include #include +#include class CBlockIndex; enum class SynchronizationState; namespace kernel { +//! Result type for use with std::variant to indicate that an operation should be interrupted. +struct Interrupted{}; + +//! Simple result type for functions that need to propagate an interrupt status and don't have other return values. +using InterruptResult = std::variant; + +template +bool IsInterrupted(const T& result) +{ + return std::holds_alternative(result); +} + /** * A base class defining functions for notifying about certain kernel * events. @@ -24,7 +37,7 @@ class Notifications public: virtual ~Notifications(){}; - virtual void blockTip(SynchronizationState state, CBlockIndex& index) {} + [[nodiscard]] virtual InterruptResult blockTip(SynchronizationState state, CBlockIndex& index) { return {}; } virtual void headerTip(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) {} virtual void progress(const bilingual_str& title, int progress_percent, bool resume_possible) {} virtual void warning(const bilingual_str& warning) {} diff --git a/src/node/chainstatemanager_args.cpp b/src/node/chainstatemanager_args.cpp index a7f7303348d..87d9238c180 100644 --- a/src/node/chainstatemanager_args.cpp +++ b/src/node/chainstatemanager_args.cpp @@ -37,8 +37,6 @@ util::Result ApplyArgsManOptions(const ArgsManager& args, ChainstateManage if (auto value{args.GetIntArg("-maxtipage")}) opts.max_tip_age = std::chrono::seconds{*value}; - if (auto value{args.GetIntArg("-stopatheight")}) opts.stop_at_height = *value; - ReadDatabaseArgs(args, opts.block_tree_db); ReadDatabaseArgs(args, opts.coins_db); ReadCoinsViewArgs(args, opts.coins_view); diff --git a/src/node/kernel_notifications.cpp b/src/node/kernel_notifications.cpp index 0be7d51afbe..7224127c727 100644 --- a/src/node/kernel_notifications.cpp +++ b/src/node/kernel_notifications.cpp @@ -8,6 +8,7 @@ #include #endif +#include #include #include #include @@ -57,9 +58,14 @@ static void DoWarning(const bilingual_str& warning) namespace node { -void KernelNotifications::blockTip(SynchronizationState state, CBlockIndex& index) +kernel::InterruptResult KernelNotifications::blockTip(SynchronizationState state, CBlockIndex& index) { uiInterface.NotifyBlockTip(state, &index); + if (m_stop_at_height && index.nHeight >= m_stop_at_height) { + StartShutdown(); + return kernel::Interrupted{}; + } + return {}; } void KernelNotifications::headerTip(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) @@ -87,4 +93,9 @@ void KernelNotifications::fatalError(const std::string& debug_message, const bil node::AbortNode(m_exit_status, debug_message, user_message, m_shutdown_on_fatal_error); } +void ReadNotificationArgs(const ArgsManager& args, KernelNotifications& notifications) +{ + if (auto value{args.GetIntArg("-stopatheight")}) notifications.m_stop_at_height = *value; +} + } // namespace node diff --git a/src/node/kernel_notifications.h b/src/node/kernel_notifications.h index d35b6ecca5c..b2dfc033989 100644 --- a/src/node/kernel_notifications.h +++ b/src/node/kernel_notifications.h @@ -11,17 +11,21 @@ #include #include +class ArgsManager; class CBlockIndex; enum class SynchronizationState; struct bilingual_str; namespace node { + +static constexpr int DEFAULT_STOPATHEIGHT{0}; + class KernelNotifications : public kernel::Notifications { public: KernelNotifications(std::atomic& exit_status) : m_exit_status{exit_status} {} - void blockTip(SynchronizationState state, CBlockIndex& index) override; + [[nodiscard]] kernel::InterruptResult blockTip(SynchronizationState state, CBlockIndex& index) override; void headerTip(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) override; @@ -33,11 +37,16 @@ public: void fatalError(const std::string& debug_message, const bilingual_str& user_message = {}) override; + //! Block height after which blockTip notification will return Interrupted{}, if >0. + int m_stop_at_height{DEFAULT_STOPATHEIGHT}; //! Useful for tests, can be set to false to avoid shutdown on fatal error. bool m_shutdown_on_fatal_error{true}; private: std::atomic& m_exit_status; }; + +void ReadNotificationArgs(const ArgsManager& args, KernelNotifications& notifications); + } // namespace node #endif // BITCOIN_NODE_KERNEL_NOTIFICATIONS_H diff --git a/src/validation.cpp b/src/validation.cpp index be6afbd3208..5bf8bd70e27 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -37,7 +37,6 @@ #include #include