diff options
author | Sjors Provoost <sjors@sprovoost.nl> | 2024-08-26 18:16:08 +0200 |
---|---|---|
committer | Sjors Provoost <sjors@sprovoost.nl> | 2024-09-17 09:24:01 +0200 |
commit | 7eccdaf16081d6f624c4dc21df75b0474e049d2b (patch) | |
tree | 1cce3e012cfc53bad36a8594af27cf43a0860e5e /src | |
parent | ebb8215f23644f901c46fd4977b7d4b08fae5104 (diff) |
node: Track last block that received a blockTip notification
Also signal m_tip_block_cv when StopRPC is called, for
consistency with g_best_block_cv. This is handled in
StopRPC instead of OnRPCStopped() because the latter
is deleted in a later commit.
Co-authored-by: TheCharlatan <seb.kung@gmail.com>
Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/init.cpp | 2 | ||||
-rw-r--r-- | src/node/interfaces.cpp | 2 | ||||
-rw-r--r-- | src/node/kernel_notifications.cpp | 6 | ||||
-rw-r--r-- | src/node/kernel_notifications.h | 12 | ||||
-rw-r--r-- | src/rpc/server.cpp | 8 | ||||
-rw-r--r-- | src/rpc/server.h | 3 |
6 files changed, 27 insertions, 6 deletions
diff --git a/src/init.cpp b/src/init.cpp index d6c80d8f84..65575f26fc 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -284,7 +284,7 @@ void Shutdown(NodeContext& node) StopHTTPRPC(); StopREST(); - StopRPC(); + StopRPC(&node); StopHTTPServer(); for (const auto& client : node.chain_clients) { client->flush(); diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 60ff6d406a..0b7685aa87 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -139,7 +139,7 @@ public: // Stop RPC for clean shutdown if any of waitfor* commands is executed. if (args().GetBoolArg("-server", false)) { InterruptRPC(); - StopRPC(); + StopRPC(m_context); } } bool shutdownRequested() override { return ShutdownRequested(*Assert(m_context)); }; diff --git a/src/node/kernel_notifications.cpp b/src/node/kernel_notifications.cpp index 9894052a3a..40d45c8c2b 100644 --- a/src/node/kernel_notifications.cpp +++ b/src/node/kernel_notifications.cpp @@ -50,6 +50,12 @@ namespace node { kernel::InterruptResult KernelNotifications::blockTip(SynchronizationState state, CBlockIndex& index) { + { + LOCK(m_tip_block_mutex); + m_tip_block = index.GetBlockHash(); + m_tip_block_cv.notify_all(); + } + uiInterface.NotifyBlockTip(state, &index); if (m_stop_at_height && index.nHeight >= m_stop_at_height) { if (!m_shutdown()) { diff --git a/src/node/kernel_notifications.h b/src/node/kernel_notifications.h index e37f4d4e1e..9ff980ea56 100644 --- a/src/node/kernel_notifications.h +++ b/src/node/kernel_notifications.h @@ -7,6 +7,10 @@ #include <kernel/notifications_interface.h> +#include <sync.h> +#include <threadsafety.h> +#include <uint256.h> + #include <atomic> #include <cstdint> @@ -34,7 +38,7 @@ public: KernelNotifications(util::SignalInterrupt& shutdown, std::atomic<int>& exit_status, node::Warnings& warnings) : m_shutdown(shutdown), m_exit_status{exit_status}, m_warnings{warnings} {} - [[nodiscard]] kernel::InterruptResult blockTip(SynchronizationState state, CBlockIndex& index) override; + [[nodiscard]] kernel::InterruptResult blockTip(SynchronizationState state, CBlockIndex& index) override EXCLUSIVE_LOCKS_REQUIRED(!m_tip_block_mutex); void headerTip(SynchronizationState state, int64_t height, int64_t timestamp, bool presync) override; @@ -52,6 +56,12 @@ public: 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}; + + Mutex m_tip_block_mutex; + std::condition_variable m_tip_block_cv; + //! The block for which the last blockTip notification was received for. + uint256 m_tip_block; + private: util::SignalInterrupt& m_shutdown; std::atomic<int>& m_exit_status; diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 2c07a2ff08..fb50d453fa 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -11,6 +11,7 @@ #include <common/system.h> #include <logging.h> #include <node/context.h> +#include <node/kernel_notifications.h> #include <rpc/server_util.h> #include <rpc/util.h> #include <sync.h> @@ -311,16 +312,19 @@ void InterruptRPC() }); } -void StopRPC() +void StopRPC(const std::any& context) { static std::once_flag g_rpc_stop_flag; // This function could be called twice if the GUI has been started with -server=1. assert(!g_rpc_running); - std::call_once(g_rpc_stop_flag, []() { + std::call_once(g_rpc_stop_flag, [&]() { LogDebug(BCLog::RPC, "Stopping RPC\n"); WITH_LOCK(g_deadline_timers_mutex, deadlineTimers.clear()); DeleteAuthCookie(); g_rpcSignals.Stopped(); + node::NodeContext& node = EnsureAnyNodeContext(context); + // The notifications interface doesn't exist between initialization step 4a and 7. + if (node.notifications) node.notifications->m_tip_block_cv.notify_all(); }); } diff --git a/src/rpc/server.h b/src/rpc/server.h index 56e8a63088..a13ae3b1e5 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -9,6 +9,7 @@ #include <rpc/request.h> #include <rpc/util.h> +#include <any> #include <functional> #include <map> #include <stdint.h> @@ -178,7 +179,7 @@ extern CRPCTable tableRPC; void StartRPC(); void InterruptRPC(); -void StopRPC(); +void StopRPC(const std::any& context); UniValue JSONRPCExec(const JSONRPCRequest& jreq, bool catch_errors); #endif // BITCOIN_RPC_SERVER_H |