aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSjors Provoost <sjors@sprovoost.nl>2024-08-26 11:30:24 +0200
committerSjors Provoost <sjors@sprovoost.nl>2024-09-17 09:27:42 +0200
commitb94b27cf05c709674117e308e441a8d1efddcd0a (patch)
tree081c2adc04da954b47cc74b875c913757eb96692 /src
parent7eccdaf16081d6f624c4dc21df75b0474e049d2b (diff)
downloadbitcoin-b94b27cf05c709674117e308e441a8d1efddcd0a.tar.xz
Add waitTipChanged to Mining interface
Co-authored-by: TheCharlatan <seb.kung@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/mining.h12
-rw-r--r--src/node/interfaces.cpp23
2 files changed, 35 insertions, 0 deletions
diff --git a/src/interfaces/mining.h b/src/interfaces/mining.h
index ebda49bcc9..421c5ba762 100644
--- a/src/interfaces/mining.h
+++ b/src/interfaces/mining.h
@@ -12,6 +12,7 @@
#include <primitives/transaction.h> // for CTransactionRef
#include <stdint.h> // for int64_t
#include <uint256.h> // for uint256
+#include <util/time.h> // for MillisecondsDouble
#include <memory> // for unique_ptr, shared_ptr
#include <optional> // for optional
@@ -60,6 +61,17 @@ public:
virtual std::optional<BlockRef> getTip() = 0;
/**
+ * Waits for the tip to change
+ *
+ * @param[in] current_tip block hash of the current chain tip. Function waits
+ * for the chain tip to change if this matches, otherwise
+ * it returns right away.
+ * @param[in] timeout how long to wait for a new tip
+ * @returns Hash and height of the current chain tip after this call.
+ */
+ virtual BlockRef waitTipChanged(uint256 current_tip, MillisecondsDouble timeout = MillisecondsDouble::max()) = 0;
+
+ /**
* Construct a new block template
*
* @param[in] script_pub_key the coinbase output
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index 0b7685aa87..8d32ff5c2c 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -34,6 +34,7 @@
#include <node/interface_ui.h>
#include <node/mini_miner.h>
#include <node/miner.h>
+#include <node/kernel_notifications.h>
#include <node/transaction.h>
#include <node/types.h>
#include <node/warnings.h>
@@ -935,6 +936,27 @@ public:
return BlockRef{tip->GetBlockHash(), tip->nHeight};
}
+ BlockRef waitTipChanged(uint256 current_tip, MillisecondsDouble timeout) override
+ {
+ // Interrupt check interval
+ const MillisecondsDouble tick{1000};
+ auto now{std::chrono::steady_clock::now()};
+ auto deadline = now + timeout;
+ // std::chrono does not check against overflow
+ if (deadline < now) deadline = std::chrono::steady_clock::time_point::max();
+ {
+ WAIT_LOCK(notifications().m_tip_block_mutex, lock);
+ while ((notifications().m_tip_block == uint256() || notifications().m_tip_block == current_tip) && !chainman().m_interrupt) {
+ now = std::chrono::steady_clock::now();
+ if (now >= deadline) break;
+ notifications().m_tip_block_cv.wait_until(lock, std::min(deadline, now + tick));
+ }
+ }
+ // Must release m_tip_block_mutex before locking cs_main, to avoid deadlocks.
+ LOCK(::cs_main);
+ return BlockRef{chainman().ActiveChain().Tip()->GetBlockHash(), chainman().ActiveChain().Tip()->nHeight};
+ }
+
bool processNewBlock(const std::shared_ptr<const CBlock>& block, bool* new_block) override
{
return chainman().ProcessNewBlock(block, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/new_block);
@@ -967,6 +989,7 @@ public:
NodeContext* context() override { return &m_node; }
ChainstateManager& chainman() { return *Assert(m_node.chainman); }
+ KernelNotifications& notifications() { return *Assert(m_node.notifications); }
NodeContext& m_node;
};
} // namespace