diff --git a/src/chain.cpp b/src/chain.cpp index 765c4d55a6ba..d0982742fd1a 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -29,32 +29,33 @@ void CChain::SetTip(CBlockIndex& block) } } -CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const { - int nStep = 1; - std::vector vHave; - vHave.reserve(32); - - if (!pindex) - pindex = Tip(); - while (pindex) { - vHave.push_back(pindex->GetBlockHash()); - // Stop when we have added the genesis block. - if (pindex->nHeight == 0) - break; +std::vector LocatorEntries(const CBlockIndex* index) +{ + int step = 1; + std::vector have; + if (index == nullptr) return have; + + have.reserve(32); + while (index) { + have.emplace_back(index->GetBlockHash()); + if (index->nHeight == 0) break; // Exponentially larger steps back, plus the genesis block. - int nHeight = std::max(pindex->nHeight - nStep, 0); - if (Contains(pindex)) { - // Use O(1) CChain index if possible. - pindex = (*this)[nHeight]; - } else { - // Otherwise, use O(log n) skiplist. - pindex = pindex->GetAncestor(nHeight); - } - if (vHave.size() > 10) - nStep *= 2; + int height = std::max(index->nHeight - step, 0); + // Use skiplist. + index = index->GetAncestor(height); + if (have.size() > 10) step *= 2; } + return have; +} - return CBlockLocator(vHave); +CBlockLocator GetLocator(const CBlockIndex* index) +{ + return CBlockLocator{LocatorEntries(index)}; +} + +CBlockLocator CChain::GetLocator() const +{ + return ::GetLocator(Tip()); } const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { diff --git a/src/chain.h b/src/chain.h index 9dfb5e86aba6..b4022f2a95d4 100644 --- a/src/chain.h +++ b/src/chain.h @@ -478,8 +478,8 @@ class CChain /** Set/initialize a chain with a given tip. */ void SetTip(CBlockIndex& block); - /** Return a CBlockLocator that refers to a block in this chain (by default the tip). */ - CBlockLocator GetLocator(const CBlockIndex* pindex = nullptr) const; + /** Return a CBlockLocator that refers to the tip in of this chain. */ + CBlockLocator GetLocator() const; /** Find the last common block between this chain and a block index entry. */ const CBlockIndex* FindFork(const CBlockIndex* pindex) const; @@ -488,4 +488,10 @@ class CChain CBlockIndex* FindEarliestAtLeast(int64_t nTime, int height) const; }; +/** Get a locator for a block index entry. */ +CBlockLocator GetLocator(const CBlockIndex* index); + +/** Construct a list of hash entries to put in a locator. */ +std::vector LocatorEntries(const CBlockIndex* index); + #endif // BITCOIN_CHAIN_H diff --git a/src/index/base.cpp b/src/index/base.cpp index 139deb129f2d..04096e705707 100644 --- a/src/index/base.cpp +++ b/src/index/base.cpp @@ -222,7 +222,7 @@ bool BaseIndex::Commit() CDBBatch batch(GetDB()); ok = CustomCommit(batch); if (ok) { - GetDB().WriteBestBlock(batch, GetLocator(*m_chain, m_best_block_index.load()->GetBlockHash())); + GetDB().WriteBestBlock(batch, GetLocator(m_best_block_index)); ok = GetDB().WriteBatch(batch); } } diff --git a/src/interfaces/node.h b/src/interfaces/node.h index ae968124f039..ba85809416be 100644 --- a/src/interfaces/node.h +++ b/src/interfaces/node.h @@ -516,7 +516,7 @@ class Node //! Register handler for header tip messages. using NotifyHeaderTipFn = - std::function; + std::function; virtual std::unique_ptr handleNotifyHeaderTip(NotifyHeaderTipFn fn) = 0; //! Register handler for InstantSend data messages. diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 9e5df50aeece..371d9fcb4103 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -3054,7 +3054,7 @@ void PeerManagerImpl::HandleFewUnconnectingHeaders(CNode& pfrom, Peer& peer, nodestate->nUnconnectingHeaders++; // Try to fill in the missing headers. std::string msg_type = UsesCompressedHeaders(peer) ? NetMsgType::GETHEADERS2 : NetMsgType::GETHEADERS; - if (MaybeSendGetHeaders(pfrom, msg_type, m_chainman.ActiveChain().GetLocator(m_chainman.m_best_header), peer)) { + if (MaybeSendGetHeaders(pfrom, msg_type, GetLocator(m_chainman.m_best_header), peer)) { LogPrint(BCLog::NET, "received header %s: missing prev block %s, sending %s (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n", headers[0].GetHash().ToString(), headers[0].hashPrevBlock.ToString(), @@ -3281,7 +3281,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer, const std::string msg_type = uses_compressed ? NetMsgType::GETHEADERS2 : NetMsgType::GETHEADERS; if (nCount == GetHeadersLimit(pfrom, uses_compressed)) { // Headers message had its maximum size; the peer may have more headers. - if (MaybeSendGetHeaders(pfrom, msg_type, WITH_LOCK(m_chainman.GetMutex(), return m_chainman.ActiveChain().GetLocator(pindexLast)), peer)) { + if (MaybeSendGetHeaders(pfrom, msg_type, GetLocator(pindexLast), peer)) { LogPrint(BCLog::NET, "more %s (%d) to end to peer=%d (startheight:%d)\n", msg_type, pindexLast->nHeight, pfrom.GetId(), peer.m_starting_height); } @@ -4451,7 +4451,7 @@ void PeerManagerImpl::ProcessMessage( CNodeState& state{*Assert(State(pfrom.GetId()))}; if (state.fSyncStarted || (!peer->m_inv_triggered_getheaders_before_sync && *best_block != m_last_block_inv_triggering_headers_sync)) { std::string msg_type = UsesCompressedHeaders(*peer) ? NetMsgType::GETHEADERS2 : NetMsgType::GETHEADERS; - if (MaybeSendGetHeaders(pfrom, msg_type, m_chainman.ActiveChain().GetLocator(m_chainman.m_best_header), *peer)) { + if (MaybeSendGetHeaders(pfrom, msg_type, GetLocator(m_chainman.m_best_header), *peer)) { LogPrint(BCLog::NET, "%s (%d) %s to peer=%d\n", msg_type, m_chainman.m_best_header->nHeight, best_block->ToString(), pfrom.GetId()); @@ -4914,7 +4914,7 @@ void PeerManagerImpl::ProcessMessage( // Doesn't connect (or is genesis), instead of DoSing in AcceptBlockHeader, request deeper headers if (!m_chainman.ActiveChainstate().IsInitialBlockDownload()) { std::string ret_val = UsesCompressedHeaders(*peer) ? NetMsgType::GETHEADERS2 : NetMsgType::GETHEADERS; - MaybeSendGetHeaders(pfrom, ret_val, m_chainman.ActiveChain().GetLocator(m_chainman.m_best_header), *peer); + MaybeSendGetHeaders(pfrom, ret_val, GetLocator(m_chainman.m_best_header), *peer); } return; } @@ -5810,7 +5810,7 @@ void PeerManagerImpl::ConsiderEviction(CNode& pto, Peer& peer, std::chrono::seco // still respond to us with a sufficiently high work chain tip. std::string msg_type = UsesCompressedHeaders(peer) ? NetMsgType::GETHEADERS2 : NetMsgType::GETHEADERS; MaybeSendGetHeaders(pto, - msg_type, m_chainman.ActiveChain().GetLocator(state.m_chain_sync.m_work_header->pprev), + msg_type, GetLocator(state.m_chain_sync.m_work_header->pprev), peer); LogPrint(BCLog::NET, "sending %s to outbound peer=%d to verify chain work (current best known block:%s, benchmark blockhash: %s)\n", msg_type, pto.GetId(), state.pindexBestKnownBlock != nullptr ? state.pindexBestKnownBlock->GetBlockHash().ToString() : "", state.m_chain_sync.m_work_header->GetBlockHash().ToString()); state.m_chain_sync.m_sent_getheaders = true; @@ -6201,7 +6201,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto) if (pindexStart->pprev) pindexStart = pindexStart->pprev; std::string msg_type = UsesCompressedHeaders(*peer) ? NetMsgType::GETHEADERS2 : NetMsgType::GETHEADERS; - if (MaybeSendGetHeaders(*pto, msg_type, m_chainman.ActiveChain().GetLocator(pindexStart), *peer)) { + if (MaybeSendGetHeaders(*pto, msg_type, GetLocator(pindexStart), *peer)) { LogPrint(BCLog::NET, "initial %s (%d) to peer=%d (startheight:%d)\n", msg_type, pindexStart->nHeight, pto->GetId(), peer->m_starting_height); state.fSyncStarted = true; diff --git a/src/node/interface_ui.cpp b/src/node/interface_ui.cpp index 18d16a4654cb..61a5b3bb756e 100644 --- a/src/node/interface_ui.cpp +++ b/src/node/interface_ui.cpp @@ -65,7 +65,7 @@ void CClientUIInterface::NotifyAlertChanged() { return g_ui_signals.NotifyAlertC void CClientUIInterface::ShowProgress(const std::string& title, int nProgress, bool resume_possible) { return g_ui_signals.ShowProgress(title, nProgress, resume_possible); } 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(SynchronizationState s, const CBlockIndex* i) { return g_ui_signals.NotifyHeaderTip(s, i); } +void CClientUIInterface::NotifyHeaderTip(SynchronizationState s, int64_t height, int64_t timestamp) { return g_ui_signals.NotifyHeaderTip(s, height, timestamp); } void CClientUIInterface::NotifyGovernanceChanged() { return g_ui_signals.NotifyGovernanceChanged(); } void CClientUIInterface::NotifyInstantSendChanged() { return g_ui_signals.NotifyInstantSendChanged(); } void CClientUIInterface::NotifyMasternodeListChanged(const CDeterministicMNList& list, const CBlockIndex* i) { return g_ui_signals.NotifyMasternodeListChanged(list, i); } diff --git a/src/node/interface_ui.h b/src/node/interface_ui.h index 07a7c230ce96..49f0469918ee 100644 --- a/src/node/interface_ui.h +++ b/src/node/interface_ui.h @@ -111,7 +111,7 @@ class CClientUIInterface ADD_SIGNALS_DECL_WRAPPER(NotifyChainLock, void, const std::string& bestChainLockHash, int bestChainLockHeight); /** Best header has changed */ - ADD_SIGNALS_DECL_WRAPPER(NotifyHeaderTip, void, SynchronizationState, const CBlockIndex*); + ADD_SIGNALS_DECL_WRAPPER(NotifyHeaderTip, void, SynchronizationState, int64_t height, int64_t timestamp); /** Masternode list has changed */ ADD_SIGNALS_DECL_WRAPPER(NotifyMasternodeListChanged, void, const CDeterministicMNList&, const CBlockIndex*); diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index c89bc48ec61b..795e54f4cc90 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -1037,9 +1037,8 @@ class NodeImpl : public Node std::unique_ptr handleNotifyHeaderTip(NotifyHeaderTipFn fn) override { return MakeHandler( - ::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); + ::uiInterface.NotifyHeaderTip_connect([fn](SynchronizationState sync_state, int64_t height, int64_t timestamp) { + fn(sync_state, BlockTip{(int)height, timestamp, uint256{}}); })); } std::unique_ptr handleNotifyInstantSendChanged(NotifyInstantSendChangedFn fn) override @@ -1085,7 +1084,7 @@ bool FillBlock(const CBlockIndex* index, const FoundBlock& block, UniqueLockGetBlockTimeMax(); if (block.m_mtp_time) *block.m_mtp_time = index->GetMedianTimePast(); if (block.m_in_active_chain) *block.m_in_active_chain = active[index->nHeight] == index; - if (block.m_locator) { *block.m_locator = active.GetLocator(index); } + if (block.m_locator) { *block.m_locator = GetLocator(index); } if (block.m_next_block) FillBlock(active[index->nHeight] == index ? active[index->nHeight + 1] : nullptr, *block.m_next_block, lock, active); if (block.m_data) { REVERSE_LOCK(lock); @@ -1249,8 +1248,7 @@ class ChainImpl : public Chain { LOCK(::cs_main); const CBlockIndex* index = chainman().m_blockman.LookupBlockIndex(block_hash); - if (!index) return {}; - return chainman().ActiveChain().GetLocator(index); + return GetLocator(index); } std::optional findLocatorFork(const CBlockLocator& locator) override { diff --git a/src/primitives/block.h b/src/primitives/block.h index 0d91fc041cd8..eaecdccc32eb 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -250,7 +250,7 @@ struct CBlockLocator CBlockLocator() {} - explicit CBlockLocator(const std::vector& vHaveIn) : vHave(vHaveIn) {} + explicit CBlockLocator(std::vector&& have) : vHave(std::move(have)) {} SERIALIZE_METHODS(CBlockLocator, obj) { diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 90d092c15706..0a9af7535697 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -80,6 +80,7 @@ Q_IMPORT_PLUGIN(QAndroidPlatformIntegrationPlugin) Q_DECLARE_METATYPE(bool*) Q_DECLARE_METATYPE(CAmount) Q_DECLARE_METATYPE(SynchronizationState) +Q_DECLARE_METATYPE(SyncType) Q_DECLARE_METATYPE(uint256) static void RegisterMetaTypes() @@ -87,6 +88,7 @@ static void RegisterMetaTypes() // Register meta types used for QMetaObject::invokeMethod and Qt::QueuedConnection qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType(); #ifdef ENABLE_WALLET qRegisterMetaType(); #endif diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index cfffa69ce2c4..7ae1f757f86b 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -883,7 +883,7 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel, interfaces::BlockAndH connect(_clientModel, &ClientModel::networkActiveChanged, this, &BitcoinGUI::setNetworkActive); modalOverlay->setKnownBestHeight(tip_info->header_height, QDateTime::fromSecsSinceEpoch(tip_info->header_time)); - setNumBlocks(tip_info->block_height, QDateTime::fromSecsSinceEpoch(tip_info->block_time), QString::fromStdString(tip_info->block_hash.ToString()), tip_info->verification_progress, false, SynchronizationState::INIT_DOWNLOAD); + setNumBlocks(tip_info->block_height, QDateTime::fromSecsSinceEpoch(tip_info->block_time), QString::fromStdString(tip_info->block_hash.ToString()), tip_info->verification_progress, SyncType::BLOCK_SYNC, SynchronizationState::INIT_DOWNLOAD); connect(_clientModel, &ClientModel::numBlocksChanged, this, &BitcoinGUI::setNumBlocks); connect(_clientModel, &ClientModel::additionalDataSyncProgressChanged, this, &BitcoinGUI::setAdditionalDataSyncProgress); @@ -1399,7 +1399,7 @@ void BitcoinGUI::updateNetworkState() } if (fNetworkBecameActive || fNetworkBecameInactive) { - setNumBlocks(m_node.getNumBlocks(), QDateTime::fromSecsSinceEpoch(m_node.getLastBlockTime()), QString::fromStdString(m_node.getLastBlockHash()), m_node.getVerificationProgress(), false, SynchronizationState::INIT_DOWNLOAD); + setNumBlocks(m_node.getNumBlocks(), QDateTime::fromSecsSinceEpoch(m_node.getLastBlockTime()), QString::fromStdString(m_node.getLastBlockHash()), m_node.getVerificationProgress(), SyncType::BLOCK_SYNC, SynchronizationState::INIT_DOWNLOAD); } nCountPrev = count; @@ -1589,7 +1589,7 @@ void BitcoinGUI::updateWidth() resize(std::max(width(), nWidth), height()); } -void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, bool header, SynchronizationState sync_state) +void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, SyncType synctype, SynchronizationState sync_state) { #ifdef Q_OS_MACOS // Disabling macOS App Nap on initial sync, disk, reindex operations and mixing. @@ -1610,7 +1610,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, const QStri if (modalOverlay) { - if (header) + if (synctype != SyncType::BLOCK_SYNC) modalOverlay->setKnownBestHeight(count, blockDate); else modalOverlay->tipUpdate(count, blockDate, nVerificationProgress); @@ -1628,7 +1628,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, const QStri BlockSource blockSource{clientModel->getBlockSource()}; switch (blockSource) { case BlockSource::NETWORK: - if (header) { + if (synctype == SyncType::HEADER_SYNC) { updateHeadersSyncProgressLabel(); return; } @@ -1636,14 +1636,14 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, const QStri updateHeadersSyncProgressLabel(); break; case BlockSource::DISK: - if (header) { + if (synctype != SyncType::BLOCK_SYNC) { progressBarLabel->setText(tr("Indexing blocks on disk…")); } else { progressBarLabel->setText(tr("Processing blocks on disk…")); } break; case BlockSource::NONE: - if (header) { + if (synctype != SyncType::BLOCK_SYNC) { return; } progressBarLabel->setText(tr("Connecting to peers…")); @@ -1710,7 +1710,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::fromSecsSinceEpoch(m_node.getLastBlockTime()), QString::fromStdString(m_node.getLastBlockHash()), m_node.getVerificationProgress(), false, SynchronizationState::INIT_DOWNLOAD); + setNumBlocks(m_node.getNumBlocks(), QDateTime::fromSecsSinceEpoch(m_node.getLastBlockTime()), QString::fromStdString(m_node.getLastBlockHash()), m_node.getVerificationProgress(), SyncType::BLOCK_SYNC, SynchronizationState::INIT_DOWNLOAD); if (clientModel->getNumConnections()) { labelBlocksIcon->show(); startSpinner(); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 333ef538d412..4aa69f99ab0c 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -10,6 +10,7 @@ #endif #include +#include #include #include @@ -30,7 +31,6 @@ #include #endif -class ClientModel; class NetworkStyle; class Notificator; class OptionsModel; @@ -297,7 +297,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, SynchronizationState sync_state); + void setNumBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, SyncType synctype, SynchronizationState sync_state); /** Set additional data sync status shown in the UI */ void setAdditionalDataSyncProgress(double nSyncProgress); diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 8398921dde33..426f21f545d3 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -89,8 +89,8 @@ ClientModel::ClientModel(interfaces::Node& node, OptionsModel *_optionsModel, QO // Update sync state to decide delay param, trigger refreshes connect(this, &ClientModel::numBlocksChanged, this, - [this](int, const QDateTime&, const QString&, double, bool header, SynchronizationState sync_state) { - if (header) return; + [this](int, const QDateTime&, const QString&, double, SyncType synctype, SynchronizationState sync_state) { + if (synctype != SyncType::BLOCK_SYNC) return; m_feeds->setSyncing(sync_state != SynchronizationState::POST_INIT); if (m_feed_creditpool) m_feed_creditpool->requestRefresh(); if (m_feed_masternode) m_feed_masternode->requestRefresh(); @@ -262,26 +262,26 @@ QString ClientModel::blocksDir() const return GUIUtil::PathToQString(gArgs.GetBlocksDirPath()); } -void ClientModel::TipChanged(SynchronizationState sync_state, interfaces::BlockTip tip, double verification_progress, bool header) +void ClientModel::TipChanged(SynchronizationState sync_state, interfaces::BlockTip tip, double verification_progress, SyncType synctype) { - if (header) { + if (synctype == SyncType::HEADER_SYNC) { // cache best headers time and height to reduce future cs_main locks cachedBestHeaderHeight = tip.block_height; cachedBestHeaderTime = tip.block_time; - } else { + } else if (synctype == SyncType::BLOCK_SYNC) { m_cached_num_blocks = tip.block_height; WITH_LOCK(m_cached_tip_mutex, m_cached_tip_blocks = tip.block_hash;); } // 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 && !header) || sync_state == SynchronizationState::INIT_REINDEX; + const bool throttle = (sync_state != SynchronizationState::POST_INIT && synctype == SyncType::BLOCK_SYNC) || sync_state == SynchronizationState::INIT_REINDEX; const auto now{throttle ? SteadyClock::now() : SteadyClock::time_point{}}; - auto& nLastUpdateNotification = header ? g_last_header_tip_update_notification : g_last_block_tip_update_notification; + auto& nLastUpdateNotification = synctype != SyncType::BLOCK_SYNC ? g_last_header_tip_update_notification : g_last_block_tip_update_notification; if (throttle && now < nLastUpdateNotification + MODEL_UPDATE_DELAY) { return; } - Q_EMIT numBlocksChanged(tip.block_height, QDateTime::fromSecsSinceEpoch(tip.block_time), QString::fromStdString(tip.block_hash.ToString()), verification_progress, header, sync_state); + Q_EMIT numBlocksChanged(tip.block_height, QDateTime::fromSecsSinceEpoch(tip.block_time), QString::fromStdString(tip.block_hash.ToString()), verification_progress, synctype, sync_state); nLastUpdateNotification = now; } @@ -311,11 +311,11 @@ void ClientModel::subscribeToCoreSignals() })); m_event_handlers.emplace_back(m_node.handleNotifyBlockTip( [this](SynchronizationState sync_state, interfaces::BlockTip tip, double verification_progress) { - TipChanged(sync_state, tip, verification_progress, /*header=*/false); + TipChanged(sync_state, tip, verification_progress, SyncType::BLOCK_SYNC); })); m_event_handlers.emplace_back(m_node.handleNotifyHeaderTip( - [this](SynchronizationState sync_state, interfaces::BlockTip tip, double verification_progress) { - TipChanged(sync_state, tip, verification_progress, /*header=*/true); + [this](SynchronizationState sync_state, interfaces::BlockTip tip) { + TipChanged(sync_state, tip, /*verification_progress=*/0.0, SyncType::HEADER_SYNC); })); m_event_handlers.emplace_back(m_node.handleNotifyAdditionalDataSyncProgressChanged( [this](double nSyncProgress) { diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 72ff9a7b3d80..883ff7b78e74 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -40,6 +40,11 @@ enum class BlockSource { NETWORK, }; +enum class SyncType { + HEADER_SYNC, + BLOCK_SYNC +}; + enum NumConnections { CONNECTIONS_NONE = 0, CONNECTIONS_IN = (1U << 0), @@ -127,7 +132,7 @@ class ClientModel : public QObject QuorumFeed* m_feed_quorum{nullptr}; std::unique_ptr m_feeds{nullptr}; - void TipChanged(SynchronizationState sync_state, interfaces::BlockTip tip, double verification_progress, bool header) EXCLUSIVE_LOCKS_REQUIRED(!m_cached_tip_mutex); + void TipChanged(SynchronizationState sync_state, interfaces::BlockTip tip, double verification_progress, SyncType synctype) EXCLUSIVE_LOCKS_REQUIRED(!m_cached_tip_mutex); void subscribeToCoreSignals(); void unsubscribeFromCoreSignals(); @@ -136,7 +141,7 @@ class ClientModel : public QObject void governanceChanged(); void masternodeListChanged() const; void chainLockChanged(); - void numBlocksChanged(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, bool header, SynchronizationState sync_state); + void numBlocksChanged(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, SyncType header, SynchronizationState sync_state); void additionalDataSyncProgressChanged(double nSyncProgress); void mempoolSizeChanged(long count, size_t mempoolSizeInBytes, size_t mempoolMaxSizeInBytes); void instantSendChanged(); diff --git a/src/qt/informationwidget.cpp b/src/qt/informationwidget.cpp index 1d26c30922a5..3102722c00f4 100644 --- a/src/qt/informationwidget.cpp +++ b/src/qt/informationwidget.cpp @@ -106,9 +106,9 @@ void InformationWidget::setNetworkActive(bool networkActive) updateNetworkState(); } -void InformationWidget::setNumBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, bool headers) +void InformationWidget::setNumBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, SyncType synctype, SynchronizationState sync_state) { - if (!headers) { + if (synctype == SyncType::BLOCK_SYNC) { ui->numberOfBlocks->setText(QString::number(count)); ui->lastBlockTime->setText(blockDate.toString()); ui->lastBlockHash->setText(blockHash); diff --git a/src/qt/informationwidget.h b/src/qt/informationwidget.h index 88eae235a9fd..d35524d9d222 100644 --- a/src/qt/informationwidget.h +++ b/src/qt/informationwidget.h @@ -13,6 +13,9 @@ namespace Ui { class InformationWidget; } // namespace Ui +enum class SyncType; +enum class SynchronizationState; + class InformationWidget : public QWidget { Q_OBJECT @@ -29,7 +32,7 @@ public Q_SLOTS: /** Set network state shown in the UI */ void setNetworkActive(bool networkActive); /** Set number of blocks, last block date and last block hash 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, SyncType synctype, SynchronizationState sync_state); /** Set size (number of transactions and memory usage) of the mempool in the UI */ void setMempoolSize(long numberOfTxs, size_t dynUsage, size_t maxUsage); diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 3e90b06be4c9..30478595d6fe 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -782,7 +783,7 @@ void RPCConsole::setClientModel(ClientModel *model, int bestblock_height, int64_ // Provide initial values ui->informationWidget->setNumBlocks(/*count=*/bestblock_height, QDateTime::fromSecsSinceEpoch(bestblock_date), QString::fromStdString(bestblock_hash.ToString()), - verification_progress, /*headers=*/false); + verification_progress, SyncType::BLOCK_SYNC, SynchronizationState::INIT_DOWNLOAD); //Setup autocomplete and attach it QStringList wordList; diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index c978d1af14c6..770707e21636 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -9,6 +9,7 @@ #include #endif +#include #include #include #include @@ -21,7 +22,6 @@ #include #include -class ClientModel; class MasternodeFeed; class RPCExecutor; class RPCTimerInterface; diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index db2a304b2410..1b25c171abb5 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -950,7 +950,7 @@ void SendCoinsDialog::updateCoinControlState() m_coin_control->fAllowWatchOnly = model->wallet().privateKeysDisabled() && !model->wallet().hasExternalSigner(); } -void SendCoinsDialog::updateNumberOfBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, bool header, SynchronizationState sync_state) { +void SendCoinsDialog::updateNumberOfBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, SyncType synctype, SynchronizationState sync_state) { if (sync_state == SynchronizationState::POST_INIT) { updateSmartFeeLabel(); } diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 90e1eff6ce6e..d691f1555195 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -5,6 +5,7 @@ #ifndef BITCOIN_QT_SENDCOINSDIALOG_H #define BITCOIN_QT_SENDCOINSDIALOG_H +#include #include #include @@ -14,7 +15,6 @@ static const int MAX_SEND_POPUP_ENTRIES = 10; -class ClientModel; class SendCoinsEntry; class SendCoinsRecipient; enum class SynchronizationState; @@ -112,7 +112,7 @@ private Q_SLOTS: void coinControlClipboardBytes(); void coinControlClipboardChange(); void updateFeeSectionControls(); - void updateNumberOfBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, bool header, SynchronizationState sync_state); + void updateNumberOfBlocks(int count, const QDateTime& blockDate, const QString& blockHash, double nVerificationProgress, SyncType synctype, SynchronizationState sync_state); void updateSmartFeeLabel(); void keepChangeAddressChanged(bool); diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp index 4b3dbf95f9a0..a0c1037bfbbf 100644 --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.cpp @@ -79,7 +79,7 @@ BOOST_AUTO_TEST_CASE(getlocator_test) for (int n=0; n<100; n++) { int r = InsecureRandRange(150000); CBlockIndex* tip = (r < 100000) ? &vBlocksMain[r] : &vBlocksSide[r - 100000]; - CBlockLocator locator = chain.GetLocator(tip); + CBlockLocator locator = GetLocator(tip); // The first result must be the block itself, the last one must be genesis. BOOST_CHECK(locator.vHave.front() == tip->GetBlockHash()); diff --git a/src/validation.cpp b/src/validation.cpp index bd99df8bc8d6..cdc77f40e373 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3245,7 +3245,7 @@ static bool NotifyHeaderTip(Chainstate& chainstate) LOCKS_EXCLUDED(cs_main) { } // Send block tip changed notifications without cs_main if (fNotify) { - uiInterface.NotifyHeaderTip(GetSynchronizationState(fInitialBlockDownload), pindexHeader); + uiInterface.NotifyHeaderTip(GetSynchronizationState(fInitialBlockDownload), pindexHeader->nHeight, pindexHeader->nTime); GetMainSignals().NotifyHeaderTip(pindexHeader, fInitialBlockDownload); } return fNotify;