aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSjors Provoost <sjors@sprovoost.nl>2024-08-26 18:16:08 +0200
committerSjors Provoost <sjors@sprovoost.nl>2024-09-17 09:24:01 +0200
commit7eccdaf16081d6f624c4dc21df75b0474e049d2b (patch)
tree1cce3e012cfc53bad36a8594af27cf43a0860e5e /src
parentebb8215f23644f901c46fd4977b7d4b08fae5104 (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.cpp2
-rw-r--r--src/node/interfaces.cpp2
-rw-r--r--src/node/kernel_notifications.cpp6
-rw-r--r--src/node/kernel_notifications.h12
-rw-r--r--src/rpc/server.cpp8
-rw-r--r--src/rpc/server.h3
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