mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -04: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
3 changed files with 39 additions and 57 deletions
|
@ -429,16 +429,12 @@ static void registerSignalHandler(int signal, void(*handler)(int))
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static boost::signals2::connection rpc_notify_block_change_connection;
|
|
||||||
static void OnRPCStarted()
|
static void OnRPCStarted()
|
||||||
{
|
{
|
||||||
rpc_notify_block_change_connection = uiInterface.NotifyBlockTip_connect(std::bind(RPCNotifyBlockChange, std::placeholders::_2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnRPCStopped()
|
static void OnRPCStopped()
|
||||||
{
|
{
|
||||||
rpc_notify_block_change_connection.disconnect();
|
|
||||||
RPCNotifyBlockChange(nullptr);
|
|
||||||
g_best_block_cv.notify_all();
|
g_best_block_cv.notify_all();
|
||||||
LogDebug(BCLog::RPC, "RPC stopped.\n");
|
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
|
// 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
|
// that the RPC's view of the best block is valid and consistent with
|
||||||
// ChainstateManager's active tip.
|
// 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();
|
SetRPCWarmupFinished();
|
||||||
|
|
||||||
uiInterface.InitMessage(_("Done loading").translated);
|
uiInterface.InitMessage(_("Done loading").translated);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include <index/blockfilterindex.h>
|
#include <index/blockfilterindex.h>
|
||||||
#include <index/coinstatsindex.h>
|
#include <index/coinstatsindex.h>
|
||||||
|
#include <interfaces/mining.h>
|
||||||
#include <kernel/coinstats.h>
|
#include <kernel/coinstats.h>
|
||||||
#include <logging/timer.h>
|
#include <logging/timer.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
|
@ -61,21 +62,12 @@
|
||||||
using kernel::CCoinsStats;
|
using kernel::CCoinsStats;
|
||||||
using kernel::CoinStatsHashType;
|
using kernel::CoinStatsHashType;
|
||||||
|
|
||||||
|
using interfaces::Mining;
|
||||||
using node::BlockManager;
|
using node::BlockManager;
|
||||||
using node::NodeContext;
|
using node::NodeContext;
|
||||||
using node::SnapshotMetadata;
|
using node::SnapshotMetadata;
|
||||||
using util::MakeUnorderedList;
|
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*>
|
std::tuple<std::unique_ptr<CCoinsViewCursor>, CCoinsStats, const CBlockIndex*>
|
||||||
PrepareUTXOSnapshot(
|
PrepareUTXOSnapshot(
|
||||||
Chainstate& chainstate,
|
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()
|
static RPCHelpMan waitfornewblock()
|
||||||
{
|
{
|
||||||
return RPCHelpMan{"waitfornewblock",
|
return RPCHelpMan{"waitfornewblock",
|
||||||
|
@ -298,16 +280,14 @@ static RPCHelpMan waitfornewblock()
|
||||||
timeout = request.params[0].getInt<int>();
|
timeout = request.params[0].getInt<int>();
|
||||||
if (timeout < 0) throw JSONRPCError(RPC_MISC_ERROR, "Negative timeout");
|
if (timeout < 0) throw JSONRPCError(RPC_MISC_ERROR, "Negative timeout");
|
||||||
|
|
||||||
CUpdatedBlock block;
|
NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
{
|
Mining& miner = EnsureMining(node);
|
||||||
WAIT_LOCK(cs_blockchange, lock);
|
|
||||||
block = latestblock;
|
auto block{CHECK_NONFATAL(miner.getTip()).value()};
|
||||||
if(timeout)
|
if (IsRPCRunning()) {
|
||||||
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(); });
|
block = timeout ? miner.waitTipChanged(block.hash, std::chrono::milliseconds(timeout)) : miner.waitTipChanged(block.hash);
|
||||||
else
|
|
||||||
cond_blockchange.wait(lock, [&block]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); });
|
|
||||||
block = latestblock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue ret(UniValue::VOBJ);
|
UniValue ret(UniValue::VOBJ);
|
||||||
ret.pushKV("hash", block.hash.GetHex());
|
ret.pushKV("hash", block.hash.GetHex());
|
||||||
ret.pushKV("height", block.height);
|
ret.pushKV("height", block.height);
|
||||||
|
@ -346,14 +326,20 @@ static RPCHelpMan waitforblock()
|
||||||
timeout = request.params[1].getInt<int>();
|
timeout = request.params[1].getInt<int>();
|
||||||
if (timeout < 0) throw JSONRPCError(RPC_MISC_ERROR, "Negative timeout");
|
if (timeout < 0) throw JSONRPCError(RPC_MISC_ERROR, "Negative timeout");
|
||||||
|
|
||||||
CUpdatedBlock block;
|
NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
{
|
Mining& miner = EnsureMining(node);
|
||||||
WAIT_LOCK(cs_blockchange, lock);
|
|
||||||
if(timeout)
|
auto block{CHECK_NONFATAL(miner.getTip()).value()};
|
||||||
cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&hash]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.hash == hash || !IsRPCRunning();});
|
const auto deadline{std::chrono::steady_clock::now() + 1ms * timeout};
|
||||||
else
|
while (IsRPCRunning() && block.hash != hash) {
|
||||||
cond_blockchange.wait(lock, [&hash]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.hash == hash || !IsRPCRunning(); });
|
if (timeout) {
|
||||||
block = latestblock;
|
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);
|
UniValue ret(UniValue::VOBJ);
|
||||||
|
@ -395,15 +381,23 @@ static RPCHelpMan waitforblockheight()
|
||||||
timeout = request.params[1].getInt<int>();
|
timeout = request.params[1].getInt<int>();
|
||||||
if (timeout < 0) throw JSONRPCError(RPC_MISC_ERROR, "Negative timeout");
|
if (timeout < 0) throw JSONRPCError(RPC_MISC_ERROR, "Negative timeout");
|
||||||
|
|
||||||
CUpdatedBlock block;
|
NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
{
|
Mining& miner = EnsureMining(node);
|
||||||
WAIT_LOCK(cs_blockchange, lock);
|
|
||||||
if(timeout)
|
auto block{CHECK_NONFATAL(miner.getTip()).value()};
|
||||||
cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&height]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.height >= height || !IsRPCRunning();});
|
const auto deadline{std::chrono::steady_clock::now() + 1ms * timeout};
|
||||||
else
|
|
||||||
cond_blockchange.wait(lock, [&height]() EXCLUSIVE_LOCKS_REQUIRED(cs_blockchange) {return latestblock.height >= height || !IsRPCRunning(); });
|
while (IsRPCRunning() && block.height < height) {
|
||||||
block = latestblock;
|
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);
|
UniValue ret(UniValue::VOBJ);
|
||||||
ret.pushKV("hash", block.hash.GetHex());
|
ret.pushKV("hash", block.hash.GetHex());
|
||||||
ret.pushKV("height", block.height);
|
ret.pushKV("height", block.height);
|
||||||
|
|
|
@ -35,9 +35,6 @@ static constexpr int NUM_GETBLOCKSTATS_PERCENTILES = 5;
|
||||||
*/
|
*/
|
||||||
double GetDifficulty(const CBlockIndex& blockindex);
|
double GetDifficulty(const CBlockIndex& blockindex);
|
||||||
|
|
||||||
/** Callback for when block tip changed. */
|
|
||||||
void RPCNotifyBlockChange(const CBlockIndex*);
|
|
||||||
|
|
||||||
/** Block description to JSON */
|
/** Block description to JSON */
|
||||||
UniValue blockToJSON(node::BlockManager& blockman, const CBlock& block, const CBlockIndex& tip, const CBlockIndex& blockindex, TxVerbosity verbosity) LOCKS_EXCLUDED(cs_main);
|
UniValue blockToJSON(node::BlockManager& blockman, const CBlock& block, const CBlockIndex& tip, const CBlockIndex& blockindex, TxVerbosity verbosity) LOCKS_EXCLUDED(cs_main);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue