diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 10038a80e..d603c18ea 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1240,7 +1240,9 @@ void Main::refreshBlockCount() { auto d = ethereum()->blockChain().details(); BlockQueueStatus b = ethereum()->blockQueueStatus(); - ui->chainStatus->setText(QString("%3 ready %4 verifying %5 unverified %6 future %7 unknown %8 bad %1 #%2").arg(m_privateChain.size() ? "[" + m_privateChain + "] " : "testnet").arg(d.number).arg(b.verified).arg(b.verifying).arg(b.unverified).arg(b.future).arg(b.unknown).arg(b.bad)); + HashChainStatus h = ethereum()->hashChainStatus(); + ui->chainStatus->setText(QString("%9/%10%11 hashes %3 ready %4 verifying %5 unverified %6 future %7 unknown %8 bad %1 #%2") + .arg(m_privateChain.size() ? "[" + m_privateChain + "] " : "testnet").arg(d.number).arg(b.verified).arg(b.verifying).arg(b.unverified).arg(b.future).arg(b.unknown).arg(b.bad).arg(h.received).arg(h.estimated ? "~" : "").arg(h.total)); } void Main::on_turboMining_triggered() diff --git a/libdevcore/RangeMask.h b/libdevcore/RangeMask.h index bdf00e687..7c402fc98 100644 --- a/libdevcore/RangeMask.h +++ b/libdevcore/RangeMask.h @@ -219,6 +219,14 @@ public: return uit == m_ranges.end() ? m_all.second : uit->first; } + size_t size() const + { + size_t c = 0; + for (auto const& r: this->m_ranges) + c += r.second - r.first; + return c; + } + private: UnsignedRange m_all; std::map m_ranges; diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 46fbbdfb1..08bfcc935 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -745,3 +745,9 @@ void Client::flushTransactions() { doWork(); } + +HashChainStatus Client::hashChainStatus() const +{ + auto h = m_host.lock(); + return h ? h->status() : HashChainStatus { 0, 0, false }; +} diff --git a/libethereum/Client.h b/libethereum/Client.h index 5132b5a30..adfca38b6 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -156,6 +156,8 @@ public: CanonBlockChain const& blockChain() const { return m_bc; } /// Get some information on the block queue. BlockQueueStatus blockQueueStatus() const { return m_bq.status(); } + /// Get some information on the block queue. + HashChainStatus hashChainStatus() const; // Mining stuff: diff --git a/libethereum/CommonNet.h b/libethereum/CommonNet.h index a2f4a2e7c..b9ad354f6 100644 --- a/libethereum/CommonNet.h +++ b/libethereum/CommonNet.h @@ -82,5 +82,12 @@ enum class Syncing Done }; +struct HashChainStatus +{ + unsigned total; + unsigned received; + bool estimated; +}; + } } diff --git a/libethereum/DownloadMan.h b/libethereum/DownloadMan.h index 3e1a071c9..0ffa6fdb0 100644 --- a/libethereum/DownloadMan.h +++ b/libethereum/DownloadMan.h @@ -255,6 +255,11 @@ public: return m_got.full(); } + unsigned gotCount() const + { + return m_got.size(); + } + size_t chainSize() const { ReadGuard l(m_lock); return m_chainCount; } size_t chainEmpty() const { ReadGuard l(m_lock); return m_chainCount == 0; } void foreachSub(std::function const& _f) const { ReadGuard l(x_subs); for(auto i: m_subs) _f(*i); } diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index 8b2427e42..b52e319e7 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -615,7 +615,10 @@ void EthereumHost::continueSync(EthereumPeer* _peer) return; } if (_peer->m_protocolVersion == protocolVersion() && !m_hashMan.isComplete()) + { + m_syncingV61 = true; _peer->requestHashes(); /// v61+ and not catching up to a particular hash + } else { // Restart/continue sync in single peer mode @@ -625,7 +628,13 @@ void EthereumHost::continueSync(EthereumPeer* _peer) m_syncingTotalDifficulty = _peer->m_totalDifficulty; } if (_peer->m_totalDifficulty >= m_syncingTotalDifficulty) + { _peer->requestHashes(m_syncingLatestHash); + m_syncingV61 = false; + m_estimatedHashes = _peer->m_expectedHashes; + } + else + _peer->setIdle(); } } else if (m_needSyncBlocks && peerShouldGrabBlocks(_peer)) // Check if this peer can help with downloading blocks @@ -677,3 +686,11 @@ bool EthereumHost::isSyncing_UNSAFE() const }); return syncing; } + +HashChainStatus EthereumHost::status() +{ + RecursiveGuard l(x_sync); + if (m_syncingV61) + return HashChainStatus { static_cast(m_hashMan.chainSize()), static_cast(m_hashMan.gotCount()), false }; + return HashChainStatus { m_estimatedHashes, static_cast(m_hashes.size()), true }; +} diff --git a/libethereum/EthereumHost.h b/libethereum/EthereumHost.h index d9628de3a..7e03dee8c 100644 --- a/libethereum/EthereumHost.h +++ b/libethereum/EthereumHost.h @@ -87,6 +87,7 @@ public: DownloadMan& downloadMan() { return m_man; } HashDownloadMan& hashDownloadMan() { return m_hashMan; } BlockChain const& chain() { return m_chain; } + HashChainStatus status(); static unsigned const c_oldProtocolVersion; @@ -147,7 +148,9 @@ private: bool m_needSyncBlocks = true; ///< Indicates if we still need to download some blocks h256 m_syncingLatestHash; ///< Latest block's hash, as of the current sync. u256 m_syncingTotalDifficulty; ///< Latest block's total difficulty, as of the current sync. - h256s m_hashes; ///< List of hashes with unknown block numbers. Used for v60 chain downloading and catching up to a particular unknown + h256s m_hashes; ///< List of hashes with unknown block numbers. Used for PV60 chain downloading and catching up to a particular unknown + unsigned m_estimatedHashes = 0; ///< Number of estimated hashes for the last peer over PV60. Used for status reporting only. + bool m_syncingV61 = false; ///< True if recent activity was over pv61+. Used for status reporting only. }; }