Skip to content

Commit

Permalink
Merge pull request #5804 from knst/bp-18152
Browse files Browse the repository at this point in the history
backport: bitcoin#18152
  • Loading branch information
PastaPastaPasta authored Jan 11, 2024
2 parents 95fad52 + 5758a33 commit 6723381
Show file tree
Hide file tree
Showing 14 changed files with 73 additions and 55 deletions.
19 changes: 10 additions & 9 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,12 @@

#include <statsd_client.h>

#include <functional>
#include <set>
#include <stdint.h>
#include <stdio.h>
#include <memory>
#include <optional>
#include <set>
#include <thread>
#include <vector>

Expand Down Expand Up @@ -458,13 +459,13 @@ static void registerSignalHandler(int signal, void(*handler)(int))
static boost::signals2::connection rpc_notify_block_change_connection;
static void OnRPCStarted()
{
rpc_notify_block_change_connection = uiInterface.NotifyBlockTip_connect(&RPCNotifyBlockChange);
rpc_notify_block_change_connection = uiInterface.NotifyBlockTip_connect(std::bind(RPCNotifyBlockChange, std::placeholders::_2));
}

static void OnRPCStopped()
{
rpc_notify_block_change_connection.disconnect();
RPCNotifyBlockChange(false, nullptr);
RPCNotifyBlockChange(nullptr);
g_best_block_cv.notify_all();
LogPrint(BCLog::RPC, "RPC stopped.\n");
}
Expand Down Expand Up @@ -815,7 +816,7 @@ static bool fHaveGenesis = false;
static Mutex g_genesis_wait_mutex;
static std::condition_variable g_genesis_wait_cv;

static void BlockNotifyGenesisWait(bool, const CBlockIndex *pBlockIndex)
static void BlockNotifyGenesisWait(const CBlockIndex* pBlockIndex)
{
if (pBlockIndex != nullptr) {
{
Expand Down Expand Up @@ -2108,8 +2109,8 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
MIN_BLOCKS_TO_KEEP);
}

CBlockIndex* tip = chainstate->m_chain.Tip();
RPCNotifyBlockChange(true, tip);
const CBlockIndex* tip = chainstate->m_chain.Tip();
RPCNotifyBlockChange(tip);
if (tip && tip->nTime > GetAdjustedTime() + 2 * 60 * 60) {
strLoadError = _("The block database contains a block which appears to be from the future. "
"This may be due to your computer's date and time being set incorrectly. "
Expand Down Expand Up @@ -2345,16 +2346,16 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
// No locking, as this happens before any background thread is started.
boost::signals2::connection block_notify_genesis_wait_connection;
if (::ChainActive().Tip() == nullptr) {
block_notify_genesis_wait_connection = uiInterface.NotifyBlockTip_connect(BlockNotifyGenesisWait);
block_notify_genesis_wait_connection = uiInterface.NotifyBlockTip_connect(std::bind(BlockNotifyGenesisWait, std::placeholders::_2));
} else {
fHaveGenesis = true;
}

#if HAVE_SYSTEM
if (args.IsArgSet("-blocknotify")) {
const std::string block_notify = args.GetArg("-blocknotify", "");
const auto BlockNotifyCallback = [block_notify](bool initialSync, const CBlockIndex* pBlockIndex) {
if (initialSync || !pBlockIndex)
const auto BlockNotifyCallback = [block_notify](SynchronizationState sync_state, const CBlockIndex* pBlockIndex) {
if (sync_state != SynchronizationState::POST_INIT || !pBlockIndex)
return;

std::string strCmd = block_notify;
Expand Down
4 changes: 2 additions & 2 deletions src/interfaces/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ class Node

//! Register handler for block tip messages.
using NotifyBlockTipFn =
std::function<void(bool initial_download, interfaces::BlockTip tip, double verification_progress)>;
std::function<void(SynchronizationState, interfaces::BlockTip tip, double verification_progress)>;
virtual std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) = 0;

//! Register handler for chainlock messages.
Expand All @@ -357,7 +357,7 @@ class Node

//! Register handler for header tip messages.
using NotifyHeaderTipFn =
std::function<void(bool initial_download, interfaces::BlockTip tip, double verification_progress)>;
std::function<void(SynchronizationState, interfaces::BlockTip tip, double verification_progress)>;
virtual std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) = 0;

//! Register handler for masternode list update messages.
Expand Down
8 changes: 4 additions & 4 deletions src/node/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,8 +488,8 @@ class NodeImpl : public Node
}
std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) override
{
return MakeHandler(::uiInterface.NotifyBlockTip_connect([fn](bool initial_download, const CBlockIndex* block) {
fn(initial_download, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()},
return MakeHandler(::uiInterface.NotifyBlockTip_connect([fn](SynchronizationState sync_state, const CBlockIndex* block) {
fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()},
GuessVerificationProgress(Params().TxData(), block));
}));
}
Expand All @@ -502,8 +502,8 @@ class NodeImpl : public Node
std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) override
{
return MakeHandler(
::uiInterface.NotifyHeaderTip_connect([fn](bool initial_download, const CBlockIndex* block) {
fn(initial_download, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()},
::uiInterface.NotifyHeaderTip_connect([fn](SynchronizationState sync_state, const CBlockIndex* block) {
fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()},
/* verification progress is unused when a header was received */ 0);
}));
}
Expand Down
4 changes: 2 additions & 2 deletions src/node/ui_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ void CClientUIInterface::NotifyNumConnectionsChanged(int newNumConnections) { re
void CClientUIInterface::NotifyNetworkActiveChanged(bool networkActive) { return g_ui_signals.NotifyNetworkActiveChanged(networkActive); }
void CClientUIInterface::NotifyAlertChanged() { return g_ui_signals.NotifyAlertChanged(); }
void CClientUIInterface::ShowProgress(const std::string& title, int nProgress, bool resume_possible) { return g_ui_signals.ShowProgress(title, nProgress, resume_possible); }
void CClientUIInterface::NotifyBlockTip(bool b, const CBlockIndex* i) { return g_ui_signals.NotifyBlockTip(b, i); }
void CClientUIInterface::NotifyBlockTip(SynchronizationState s, const CBlockIndex* i) { return g_ui_signals.NotifyBlockTip(s, i); }
void CClientUIInterface::NotifyChainLock(const std::string& bestChainLockHash, int bestChainLockHeight) { return g_ui_signals.NotifyChainLock(bestChainLockHash, bestChainLockHeight); }
void CClientUIInterface::NotifyHeaderTip(bool b, const CBlockIndex* i) { return g_ui_signals.NotifyHeaderTip(b, i); }
void CClientUIInterface::NotifyHeaderTip(SynchronizationState s, const CBlockIndex* i) { return g_ui_signals.NotifyHeaderTip(s, i); }
void CClientUIInterface::NotifyMasternodeListChanged(const CDeterministicMNList& list, const CBlockIndex* i) { return g_ui_signals.NotifyMasternodeListChanged(list, i); }
void CClientUIInterface::NotifyAdditionalDataSyncProgressChanged(double nSyncProgress) { return g_ui_signals.NotifyAdditionalDataSyncProgressChanged(nSyncProgress); }
void CClientUIInterface::BannedListChanged() { return g_ui_signals.BannedListChanged(); }
Expand Down
5 changes: 3 additions & 2 deletions src/node/ui_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <string>

class CBlockIndex;
enum class SynchronizationState;
struct bilingual_str;

class CDeterministicMNList;
Expand Down Expand Up @@ -101,13 +102,13 @@ class CClientUIInterface
ADD_SIGNALS_DECL_WRAPPER(ShowProgress, void, const std::string& title, int nProgress, bool resume_possible);

/** New block has been accepted */
ADD_SIGNALS_DECL_WRAPPER(NotifyBlockTip, void, bool, const CBlockIndex*);
ADD_SIGNALS_DECL_WRAPPER(NotifyBlockTip, void, SynchronizationState, const CBlockIndex*);

/** New chainlock block has been accepted */
ADD_SIGNALS_DECL_WRAPPER(NotifyChainLock, void, const std::string& bestChainLockHash, int bestChainLockHeight);

/** Best header has changed */
ADD_SIGNALS_DECL_WRAPPER(NotifyHeaderTip, void, bool, const CBlockIndex*);
ADD_SIGNALS_DECL_WRAPPER(NotifyHeaderTip, void, SynchronizationState, const CBlockIndex*);

/** Masternode list has changed */
ADD_SIGNALS_DECL_WRAPPER(NotifyMasternodeListChanged, void, const CDeterministicMNList&, const CBlockIndex*);
Expand Down
3 changes: 3 additions & 0 deletions src/qt/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <util/system.h>
#include <util/threadnames.h>
#include <util/translation.h>
#include <validation.h>

#include <memory>

Expand Down Expand Up @@ -67,6 +68,7 @@ Q_IMPORT_PLUGIN(QMacStylePlugin);
// Declare meta types used for QMetaObject::invokeMethod
Q_DECLARE_METATYPE(bool*)
Q_DECLARE_METATYPE(CAmount)
Q_DECLARE_METATYPE(SynchronizationState)
Q_DECLARE_METATYPE(uint256)

static QString GetLangTerritory()
Expand Down Expand Up @@ -483,6 +485,7 @@ int GuiMain(int argc, char* argv[])

// Register meta types used for QMetaObject::invokeMethod and Qt::QueuedConnection
qRegisterMetaType<bool*>();
qRegisterMetaType<SynchronizationState>();
#ifdef ENABLE_WALLET
qRegisterMetaType<WalletModel*>();
#endif
Expand Down
11 changes: 6 additions & 5 deletions src/qt/bitcoingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <qt/masternodelist.h>
#include <util/system.h>
#include <util/translation.h>
#include <validation.h>

#include <QAction>
#include <QApplication>
Expand Down Expand Up @@ -809,7 +810,7 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel, interfaces::BlockAndH
connect(_clientModel, &ClientModel::networkActiveChanged, this, &BitcoinGUI::setNetworkActive);

modalOverlay->setKnownBestHeight(tip_info->header_height, QDateTime::fromTime_t(tip_info->header_time));
setNumBlocks(tip_info->block_height, QDateTime::fromTime_t(tip_info->block_time), QString::fromStdString(tip_info->block_hash.ToString()), tip_info->verification_progress, false);
setNumBlocks(tip_info->block_height, QDateTime::fromTime_t(tip_info->block_time), QString::fromStdString(tip_info->block_hash.ToString()), tip_info->verification_progress, false, SynchronizationState::INIT_DOWNLOAD);
connect(_clientModel, &ClientModel::numBlocksChanged, this, &BitcoinGUI::setNumBlocks);

connect(_clientModel, &ClientModel::additionalDataSyncProgressChanged, this, &BitcoinGUI::setAdditionalDataSyncProgress);
Expand Down Expand Up @@ -1254,7 +1255,7 @@ void BitcoinGUI::updateNetworkState()
}

if (fNetworkBecameActive || fNetworkBecameInactive) {
setNumBlocks(m_node.getNumBlocks(), QDateTime::fromTime_t(m_node.getLastBlockTime()), QString::fromStdString(m_node.getLastBlockHash()), m_node.getVerificationProgress(), false);
setNumBlocks(m_node.getNumBlocks(), QDateTime::fromTime_t(m_node.getLastBlockTime()), QString::fromStdString(m_node.getLastBlockHash()), m_node.getVerificationProgress(), false, SynchronizationState::INIT_DOWNLOAD);
}

nCountPrev = count;
Expand Down Expand Up @@ -1372,11 +1373,11 @@ void BitcoinGUI::updateWidth()
resize(nWidth, height());
}

void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, bool header)
void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, bool header, SynchronizationState sync_state)
{
#ifdef Q_OS_MAC
// Disabling macOS App Nap on initial sync, disk, reindex operations and mixing.
bool disableAppNap = !m_node.masternodeSync().isSynced();
bool disableAppNap = !m_node.masternodeSync().isSynced() || sync_state != SynchronizationState::POST_INIT;
#ifdef ENABLE_WALLET
if (enableWallet) {
for (const auto& wallet : m_node.walletLoader().getWallets()) {
Expand Down Expand Up @@ -1495,7 +1496,7 @@ void BitcoinGUI::setAdditionalDataSyncProgress(double nSyncProgress)

// If masternodeSync->Reset() has been called make sure status bar shows the correct information.
if (nSyncProgress == -1) {
setNumBlocks(m_node.getNumBlocks(), QDateTime::fromTime_t(m_node.getLastBlockTime()), QString::fromStdString(m_node.getLastBlockHash()), m_node.getVerificationProgress(), false);
setNumBlocks(m_node.getNumBlocks(), QDateTime::fromTime_t(m_node.getLastBlockTime()), QString::fromStdString(m_node.getLastBlockHash()), m_node.getVerificationProgress(), false, SynchronizationState::INIT_DOWNLOAD);
if (clientModel->getNumConnections()) {
labelBlocksIcon->show();
startSpinner();
Expand Down
3 changes: 2 additions & 1 deletion src/qt/bitcoingui.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class WalletFrame;
class WalletModel;
class HelpMessageDialog;
class ModalOverlay;
enum class SynchronizationState;

namespace interfaces {
class Handler;
Expand Down Expand Up @@ -266,7 +267,7 @@ public Q_SLOTS:
/** Get restart command-line parameters and request restart */
void handleRestart(QStringList args);
/** Set number of blocks and last block date shown in the UI */
void setNumBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, bool headers);
void setNumBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, bool headers, SynchronizationState sync_state);
/** Set additional data sync status shown in the UI */
void setAdditionalDataSyncProgress(double nSyncProgress);

Expand Down
39 changes: 18 additions & 21 deletions src/qt/clientmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <net.h>
#include <netbase.h>
#include <util/system.h>
#include <validation.h>

#include <stdint.h>
#include <functional>
Expand Down Expand Up @@ -293,17 +294,8 @@ static void BannedListChanged(ClientModel *clientmodel)
assert(invoked);
}

static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, interfaces::BlockTip tip, double verificationProgress, bool fHeader)
static void BlockTipChanged(ClientModel* clientmodel, SynchronizationState sync_state, interfaces::BlockTip tip, double verificationProgress, bool fHeader)
{
// lock free async UI updates in case we have a new block tip
// during initial sync, only update the UI if the last update
// was > 250ms (MODEL_UPDATE_DELAY) ago
int64_t now = 0;
if (initialSync)
now = GetTimeMillis();

int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;

if (fHeader) {
// cache best headers time and height to reduce future cs_main locks
clientmodel->cachedBestHeaderHeight = tip.block_height;
Expand All @@ -313,18 +305,23 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, interfac
WITH_LOCK(clientmodel->m_cached_tip_mutex, clientmodel->m_cached_tip_blocks = tip.block_hash;);
}

// During initial sync, block notifications, and header notifications from reindexing are both throttled.
if (!initialSync || (fHeader && !clientmodel->node().getReindex()) || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
//pass an async signal to the UI thread
bool invoked = QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection,
Q_ARG(int, tip.block_height),
Q_ARG(QDateTime, QDateTime::fromTime_t(tip.block_time)),
Q_ARG(QString, QString::fromStdString(tip.block_hash.ToString())),
Q_ARG(double, verificationProgress),
Q_ARG(bool, fHeader));
assert(invoked);
nLastUpdateNotification = now;
// Throttle GUI notifications about (a) blocks during initial sync, and (b) both blocks and headers during reindex.
const bool throttle = (sync_state != SynchronizationState::POST_INIT && !fHeader) || sync_state == SynchronizationState::INIT_REINDEX;
const int64_t now = throttle ? GetTimeMillis() : 0;
int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;
if (throttle && now < nLastUpdateNotification + MODEL_UPDATE_DELAY) {
return;
}

bool invoked = QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection,
Q_ARG(int, tip.block_height),
Q_ARG(QDateTime, QDateTime::fromTime_t(tip.block_time)),
Q_ARG(QString, QString::fromStdString(tip.block_hash.ToString())),
Q_ARG(double, verificationProgress),
Q_ARG(bool, fHeader),
Q_ARG(SynchronizationState, sync_state));
assert(invoked);
nLastUpdateNotification = now;
}

static void NotifyChainLock(ClientModel *clientmodel, const std::string& bestChainLockHash, int bestChainLockHeight)
Expand Down
6 changes: 3 additions & 3 deletions src/qt/clientmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
#include <uint256.h>

class BanTableModel;
class CBlockIndex;
class OptionsModel;
class PeerTableModel;

class CBlockIndex;
enum class SynchronizationState;

QT_BEGIN_NAMESPACE
class QTimer;
Expand Down Expand Up @@ -128,7 +128,7 @@ class ClientModel : public QObject
void numConnectionsChanged(int count);
void masternodeListChanged() const;
void chainLockChanged(const QString& bestChainLockHash, int bestChainLockHeight);
void numBlocksChanged(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, bool header);
void numBlocksChanged(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, bool header, SynchronizationState sync_state);
void additionalDataSyncProgressChanged(double nSyncProgress);
void mempoolSizeChanged(long count, size_t mempoolSizeInBytes);
void islockCountChanged(size_t count);
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ static UniValue getbestchainlock(const JSONRPCRequest& request)
return result;
}

void RPCNotifyBlockChange(bool ibd, const CBlockIndex * pindex)
void RPCNotifyBlockChange(const CBlockIndex* pindex)
{
if(pindex) {
LOCK(cs_blockchange);
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/blockchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ static constexpr int NUM_GETBLOCKSTATS_PERCENTILES = 5;
double GetDifficulty(const CBlockIndex* blockindex);

/** Callback for when block tip changed. */
void RPCNotifyBlockChange(bool ibd, const CBlockIndex *);
void RPCNotifyBlockChange(const CBlockIndex*);

/** Block description to JSON */
UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, llmq::CChainLocksHandler& clhandler, llmq::CInstantSendManager& isman, bool txDetails = false) LOCKS_EXCLUDED(cs_main);
Expand Down
Loading

0 comments on commit 6723381

Please sign in to comment.