mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-19 09:53:47 +01:00
Replace RPCNotifyBlockChange with waitTipChanged()
This refactoring commit uses the newly introduced waitTipChanged mining interface method to replace the RPCNotifyBlockChange mechanism.
This commit is contained in:
parent
2a40ee1121
commit
dca923150e
@ -429,16 +429,12 @@ static void registerSignalHandler(int signal, void(*handler)(int))
|
||||
}
|
||||
#endif
|
||||
|
||||
static boost::signals2::connection rpc_notify_block_change_connection;
|
||||
static void OnRPCStarted()
|
||||
{
|
||||
rpc_notify_block_change_connection = uiInterface.NotifyBlockTip_connect(std::bind(RPCNotifyBlockChange, std::placeholders::_2));
|
||||
}
|
||||
|
||||
static void OnRPCStopped()
|
||||
{
|
||||
rpc_notify_block_change_connection.disconnect();
|
||||
RPCNotifyBlockChange(nullptr);
|
||||
g_best_block_cv.notify_all();
|
||||
LogDebug(BCLog::RPC, "RPC stopped.\n");
|
||||
}
|
||||
@ -2011,11 +2007,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||
// cannot yet be called. Before we make it callable, we need to make sure
|
||||
// that the RPC's view of the best block is valid and consistent with
|
||||
// ChainstateManager's active tip.
|
||||
//
|
||||
// If we do not do this, RPC's view of the best block will be height=0 and
|
||||
// hash=0x0. This will lead to erroroneous responses for things like
|
||||
// waitforblockheight.
|
||||
RPCNotifyBlockChange(WITH_LOCK(chainman.GetMutex(), return chainman.ActiveTip()));
|
||||
SetRPCWarmupFinished();
|
||||
|
||||
uiInterface.InitMessage(_("Done loading").translated);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <hash.h>
|
||||
#include <index/blockfilterindex.h>
|
||||
#include <index/coinstatsindex.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <kernel/coinstats.h>
|
||||
#include <logging/timer.h>
|
||||
#include <net.h>
|
||||
@ -61,21 +62,12 @@
|
||||
using kernel::CCoinsStats;
|
||||
using kernel::CoinStatsHashType;
|
||||
|
||||
using interfaces::Mining;
|
||||
using node::BlockManager;
|
||||
using node::NodeContext;
|
||||
using node::SnapshotMetadata;
|
||||
using util::MakeUnorderedList;
|
||||
|
||||
struct CUpdatedBlock
|
||||
{
|
||||
uint256 hash;
|
||||
int height;
|
||||
};
|
||||
|
||||
static GlobalMutex cs_blockchange;
|
||||
static std::condition_variable cond_blockchange;
|
||||
static CUpdatedBlock latestblock GUARDED_BY(cs_blockchange);
|
||||
|
||||
std::tuple<std::unique_ptr<CCoinsViewCursor>, CCoinsStats, const CBlockIndex*>
|
||||
PrepareUTXOSnapshot(
|
||||
Chainstate& chainstate,
|
||||
@ -262,16 +254,6 @@ static RPCHelpMan getbestblockhash()
|
||||
};
|
||||
}
|
||||
|
||||
void RPCNotifyBlockChange(const CBlockIndex* pindex)
|
||||
{
|
||||
if(pindex) {
|
||||
LOCK(cs_blockchange);
|
||||
latestblock.hash = pindex->GetBlockHash();
|
||||
latestblock.height = pindex->nHeight;
|
||||
}
|
||||
cond_blockchange.notify_all();
|
||||
}
|
||||
|
||||
static RPCHelpMan waitfornewblock()
|
||||
{
|
||||
return RPCHelpMan{"waitfornewblock",
|
||||
@ -298,16 +280,14 @@ static RPCHelpMan waitfornewblock()
|
||||
timeout = request.params[0].getInt<int>();
|
||||
if (timeout < 0) throw JSONRPCError(RPC_MISC_ERROR, "Negative timeout");
|
||||
|
||||
CUpdatedBlock block;
|
||||
{
|
||||
WAIT_LOCK(cs_blockchange, lock);
|
||||
block = latestblock;
|
||||
if(timeout)
|
||||
cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&block]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
|
||||
else
|
||||
cond_blockchange.wait(lock, [&block]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
|
||||
block = latestblock;
|
||||
NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||
Mining& miner = EnsureMining(node);
|
||||
|
||||
auto block{CHECK_NONFATAL(miner.getTip()).value()};
|
||||
if (IsRPCRunning()) {
|
||||
block = timeout ? miner.waitTipChanged(block.hash, std::chrono::milliseconds(timeout)) : miner.waitTipChanged(block.hash);
|
||||
}
|
||||
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
ret.pushKV("hash", block.hash.GetHex());
|
||||
ret.pushKV("height", block.height);
|
||||
@ -346,14 +326,20 @@ static RPCHelpMan waitforblock()
|
||||
timeout = request.params[1].getInt<int>();
|
||||
if (timeout < 0) throw JSONRPCError(RPC_MISC_ERROR, "Negative timeout");
|
||||
|
||||
CUpdatedBlock block;
|
||||
{
|
||||
WAIT_LOCK(cs_blockchange, lock);
|
||||
if(timeout)
|
||||
cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&hash]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.hash == hash || !IsRPCRunning();});
|
||||
else
|
||||
cond_blockchange.wait(lock, [&hash]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.hash == hash || !IsRPCRunning(); });
|
||||
block = latestblock;
|
||||
NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||
Mining& miner = EnsureMining(node);
|
||||
|
||||
auto block{CHECK_NONFATAL(miner.getTip()).value()};
|
||||
const auto deadline{std::chrono::steady_clock::now() + 1ms * timeout};
|
||||
while (IsRPCRunning() && block.hash != hash) {
|
||||
if (timeout) {
|
||||
auto now{std::chrono::steady_clock::now()};
|
||||
if (now >= deadline) break;
|
||||
const MillisecondsDouble remaining{deadline - now};
|
||||
block = miner.waitTipChanged(block.hash, remaining);
|
||||
} else {
|
||||
block = miner.waitTipChanged(block.hash);
|
||||
}
|
||||
}
|
||||
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
@ -395,15 +381,23 @@ static RPCHelpMan waitforblockheight()
|
||||
timeout = request.params[1].getInt<int>();
|
||||
if (timeout < 0) throw JSONRPCError(RPC_MISC_ERROR, "Negative timeout");
|
||||
|
||||
CUpdatedBlock block;
|
||||
{
|
||||
WAIT_LOCK(cs_blockchange, lock);
|
||||
if(timeout)
|
||||
cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&height]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.height >= height || !IsRPCRunning();});
|
||||
else
|
||||
cond_blockchange.wait(lock, [&height]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.height >= height || !IsRPCRunning(); });
|
||||
block = latestblock;
|
||||
NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||
Mining& miner = EnsureMining(node);
|
||||
|
||||
auto block{CHECK_NONFATAL(miner.getTip()).value()};
|
||||
const auto deadline{std::chrono::steady_clock::now() + 1ms * timeout};
|
||||
|
||||
while (IsRPCRunning() && block.height < height) {
|
||||
if (timeout) {
|
||||
auto now{std::chrono::steady_clock::now()};
|
||||
if (now >= deadline) break;
|
||||
const MillisecondsDouble remaining{deadline - now};
|
||||
block = miner.waitTipChanged(block.hash, remaining);
|
||||
} else {
|
||||
block = miner.waitTipChanged(block.hash);
|
||||
}
|
||||
}
|
||||
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
ret.pushKV("hash", block.hash.GetHex());
|
||||
ret.pushKV("height", block.height);
|
||||
|
@ -35,9 +35,6 @@ static constexpr int NUM_GETBLOCKSTATS_PERCENTILES = 5;
|
||||
*/
|
||||
double GetDifficulty(const CBlockIndex& blockindex);
|
||||
|
||||
/** Callback for when block tip changed. */
|
||||
void RPCNotifyBlockChange(const CBlockIndex*);
|
||||
|
||||
/** Block description to JSON */
|
||||
UniValue blockToJSON(node::BlockManager& blockman, const CBlock& block, const CBlockIndex& tip, const CBlockIndex& blockindex, TxVerbosity verbosity) LOCKS_EXCLUDED(cs_main);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user