Browse Source

Better visualisation of sync.

cl-refactor
Gav Wood 10 years ago
parent
commit
dbf49bbc49
  1. 82
      alethzero/DownloadView.cpp
  2. 12
      alethzero/DownloadView.h
  3. 4
      alethzero/Main.ui
  4. 4
      alethzero/MainWin.cpp
  5. 2
      exp/main.cpp
  6. 14
      libdevcore/RangeMask.h
  7. 2
      libethereum/BlockChainSync.cpp
  8. 10
      libethereum/DownloadMan.cpp
  9. 33
      libethereum/DownloadMan.h

82
alethzero/DownloadView.cpp

@ -30,29 +30,95 @@ using namespace std;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
DownloadView::DownloadView(QWidget* _p): QWidget(_p) SyncView::SyncView(QWidget* _p): QWidget(_p)
{ {
} }
void DownloadView::paintEvent(QPaintEvent*) void SyncView::paintEvent(QPaintEvent*)
{ {
QPainter p(this); QPainter p(this);
p.fillRect(rect(), Qt::white); p.fillRect(rect(), Qt::white);
if (!m_man || m_man->chainEmpty() || !m_man->subCount())
if (!m_client)
return;
DownloadMan const* man = m_client->downloadMan();
BlockQueueStatus bqs = m_client->blockQueueStatus();
SyncStatus sync = m_client->syncStatus();
unsigned syncFrom = m_client->numberFromHash(PendingBlockHash);
unsigned syncImported = syncFrom;
unsigned syncImporting = syncImported + bqs.importing;
unsigned syncVerified = syncImporting + bqs.verified;
unsigned syncVerifying = syncVerified + bqs.verifying;
unsigned syncUnverified = syncVerifying + bqs.unverified;
unsigned syncUnknown = syncUnverified + bqs.unknown;
// best effort guess. assumes there's no forks.
unsigned downloadFrom = m_client->numberFromHash(m_client->isKnown(man->firstBlock()) ? man->firstBlock() : PendingBlockHash);
unsigned downloadCount = sync.blocksTotal;
DownloadMan::Overview overview = man->overview();
unsigned downloadDone = downloadFrom + overview.total;
unsigned downloadFlank = downloadFrom + overview.firstIncomplete;
unsigned downloadPoint = downloadFrom + overview.lastComplete;
unsigned hashFrom = sync.state == SyncState::Hashes ? m_client->numberFromHash(PendingBlockHash) : downloadFrom;
unsigned hashCount = sync.state == SyncState::Hashes ? sync.hashesTotal : downloadCount;
unsigned hashDone = hashFrom + (sync.state == SyncState::Hashes ? sync.hashesReceived : hashCount);
m_lastFrom = min(syncFrom, m_lastFrom);
unsigned from = min(min(hashFrom, downloadFrom), min(syncFrom, m_lastFrom));
unsigned count = max(hashFrom + hashCount, downloadFrom + downloadCount) - from;
m_lastFrom = (m_lastFrom * 95 + syncFrom) / 100;
if (!count)
{
m_lastFrom = (unsigned)-1;
return; return;
}
cnote << "Range " << from << "-" << (from + count);
auto r = [&](unsigned u) {
return toString((u - from) * 100 / count) + "%";
};
if (count)
{
cnote << "Hashes:" << r(hashDone) << " Blocks:" << r(downloadFlank) << r(downloadDone) << r(downloadPoint);
cnote << "Importing:" << r(syncFrom) << r(syncImported) << r(syncImporting) << r(syncVerified) << r(syncVerifying) << r(syncUnverified) << r(syncUnknown);
}
if (!man || man->chainEmpty() || !man->subCount())
return;
float s = min(rect().width(), rect().height());
QPen pen;
pen.setCapStyle(Qt::FlatCap);
pen.setWidthF(s / 10);
p.setPen(pen);
auto middle = [&](float x) {
return QRectF(s / 2 - s / 2 * x, 0 + s / 2 - s / 2 * x, s * x, s * x);
};
auto toArc = [&](unsigned x) {
return (x - from) * -5760.f / count;
};
const float arcFrom = 90 * 16.f;
p.drawArc(middle(0.5f), arcFrom, toArc(downloadDone));
p.drawPie(middle(0.2f), arcFrom, toArc(hashDone));
return;
double ratio = (double)rect().width() / rect().height(); double ratio = (double)rect().width() / rect().height();
if (ratio < 1) if (ratio < 1)
ratio = 1 / ratio; ratio = 1 / ratio;
double n = min(16.0, min(rect().width(), rect().height()) / ceil(sqrt(m_man->chainSize() / ratio))); double n = min(16.0, min(rect().width(), rect().height()) / ceil(sqrt(man->chainSize() / ratio)));
// QSizeF area(rect().width() / floor(rect().width() / n), rect().height() / floor(rect().height() / n)); // QSizeF area(rect().width() / floor(rect().width() / n), rect().height() / floor(rect().height() / n));
QSizeF area(n, n); QSizeF area(n, n);
QPointF pos(0, 0); QPointF pos(0, 0);
auto bg = m_man->blocksGot(); auto bg = man->blocksGot();
unsigned subCount = m_man->subCount(); unsigned subCount = man->subCount();
if (subCount == 0) if (subCount == 0)
return; return;
unsigned dh = 360 / subCount; unsigned dh = 360 / subCount;
@ -64,7 +130,7 @@ void DownloadView::paintEvent(QPaintEvent*)
else else
{ {
unsigned h = 0; unsigned h = 0;
m_man->foreachSub([&](DownloadSub const& sub) man->foreachSub([&](DownloadSub const& sub)
{ {
if (sub.askedContains(i)) if (sub.askedContains(i))
s = h; s = h;

12
alethzero/DownloadView.h

@ -32,21 +32,23 @@
#endif #endif
namespace dev { namespace eth { namespace dev { namespace eth {
class DownloadMan; class Client;
}} }}
class DownloadView: public QWidget class SyncView: public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
DownloadView(QWidget* _p = nullptr); SyncView(QWidget* _p = nullptr);
void setDownloadMan(dev::eth::DownloadMan const* _man) { m_man = _man; } void setEthereum(dev::eth::Client const* _c) { m_client = _c; }
protected: protected:
virtual void paintEvent(QPaintEvent*); virtual void paintEvent(QPaintEvent*);
private: private:
dev::eth::DownloadMan const* m_man = nullptr; dev::eth::Client const* m_client = nullptr;
unsigned m_lastFrom = (unsigned)-1;
}; };

4
alethzero/Main.ui

@ -1149,7 +1149,7 @@ font-size: 14pt</string>
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<widget class="DownloadView" name="downloadView" native="true"/> <widget class="SyncView" name="downloadView" native="true"/>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -1814,7 +1814,7 @@ font-size: 14pt</string>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>DownloadView</class> <class>SyncView</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>DownloadView.h</header> <header>DownloadView.h</header>
<container>1</container> <container>1</container>

4
alethzero/MainWin.cpp

@ -1993,12 +1993,12 @@ void Main::on_net_triggered()
web3()->setNetworkPreferences(netPrefs(), ui->dropPeers->isChecked()); web3()->setNetworkPreferences(netPrefs(), ui->dropPeers->isChecked());
ethereum()->setNetworkId(m_privateChain.size() ? sha3(m_privateChain.toStdString()) : h256()); ethereum()->setNetworkId(m_privateChain.size() ? sha3(m_privateChain.toStdString()) : h256());
web3()->startNetwork(); web3()->startNetwork();
ui->downloadView->setDownloadMan(ethereum()->downloadMan()); ui->downloadView->setEthereum(ethereum());
ui->enode->setText(QString::fromStdString(web3()->enode())); ui->enode->setText(QString::fromStdString(web3()->enode()));
} }
else else
{ {
ui->downloadView->setDownloadMan(nullptr); ui->downloadView->setEthereum(nullptr);
writeSettings(); writeSettings();
web3()->stopNetwork(); web3()->stopNetwork();
} }

2
exp/main.cpp

@ -135,7 +135,7 @@ int main()
DownloadSub s0(man); DownloadSub s0(man);
DownloadSub s1(man); DownloadSub s1(man);
DownloadSub s2(man); DownloadSub s2(man);
man.resetToChain(h256s({u256(0), u256(1), u256(2), u256(3), u256(4), u256(5), u256(6), u256(7), u256(8)})); man.resetToChain(h256s({u256(0), u256(1), u256(2), u256(3), u256(4), u256(5), u256(6), u256(7), u256(8)}), 0);
assert((s0.nextFetch(2) == h256Set{(u256)7, (u256)8})); assert((s0.nextFetch(2) == h256Set{(u256)7, (u256)8}));
assert((s1.nextFetch(2) == h256Set{(u256)5, (u256)6})); assert((s1.nextFetch(2) == h256Set{(u256)5, (u256)6}));
assert((s2.nextFetch(2) == h256Set{(u256)3, (u256)4})); assert((s2.nextFetch(2) == h256Set{(u256)3, (u256)4}));

14
libdevcore/RangeMask.h

@ -200,6 +200,20 @@ public:
return c; return c;
} }
size_t firstOut() const
{
if (m_ranges.empty() || !m_ranges.count(m_all.first))
return m_all.first;
return m_ranges.at(m_all.first);
}
size_t lastIn() const
{
if (m_ranges.empty())
return m_all.first;
return m_ranges.rbegin()->second - 1;
}
private: private:
/// The ground range. /// The ground range.
UnsignedRange m_all; UnsignedRange m_all;

2
libethereum/BlockChainSync.cpp

@ -80,7 +80,7 @@ DownloadMan& BlockChainSync::downloadMan()
void BlockChainSync::abortSync() void BlockChainSync::abortSync()
{ {
downloadMan().resetToChain(h256s()); downloadMan().reset();
} }
void BlockChainSync::onPeerStatus(std::shared_ptr<EthereumPeer> _peer) void BlockChainSync::onPeerStatus(std::shared_ptr<EthereumPeer> _peer)

10
libethereum/DownloadMan.cpp

@ -24,6 +24,16 @@ using namespace std;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
DownloadMan::Overview DownloadMan::overview() const
{
ReadGuard l(m_lock);
Overview ret;
ret.firstIncomplete = m_blocksGot.firstOut();
ret.lastComplete = ret.lastStarted = m_blocksGot.lastIn();// TODO: lastStarted properly
ret.total = m_blocksGot.size();
return ret;
}
DownloadSub::DownloadSub(DownloadMan& _man): m_man(&_man) DownloadSub::DownloadSub(DownloadMan& _man): m_man(&_man)
{ {
WriteGuard l(m_man->x_subs); WriteGuard l(m_man->x_subs);

33
libethereum/DownloadMan.h

@ -82,6 +82,14 @@ class DownloadMan
friend class DownloadSub; friend class DownloadSub;
public: public:
struct Overview
{
size_t total;
size_t firstIncomplete;
size_t lastComplete;
size_t lastStarted;
};
~DownloadMan() ~DownloadMan()
{ {
for (auto i: m_subs) for (auto i: m_subs)
@ -97,11 +105,9 @@ public:
void resetToChain(h256s const& _chain) void resetToChain(h256s const& _chain)
{ {
{ DEV_READ_GUARDED(x_subs)
ReadGuard l(x_subs);
for (auto i: m_subs) for (auto i: m_subs)
i->resetFetch(); i->resetFetch();
}
WriteGuard l(m_lock); WriteGuard l(m_lock);
m_chain.clear(); m_chain.clear();
m_chain.reserve(_chain.size()); m_chain.reserve(_chain.size());
@ -112,11 +118,9 @@ public:
void reset() void reset()
{ {
{ DEV_READ_GUARDED(x_subs)
ReadGuard l(x_subs);
for (auto i: m_subs) for (auto i: m_subs)
i->resetFetch(); i->resetFetch();
}
WriteGuard l(m_lock); WriteGuard l(m_lock);
m_chain.clear(); m_chain.clear();
m_blocksGot.reset(); m_blocksGot.reset();
@ -127,11 +131,9 @@ public:
ReadGuard l(m_lock); ReadGuard l(m_lock);
auto ret = m_blocksGot; auto ret = m_blocksGot;
if (!_desperate) if (!_desperate)
{ DEV_READ_GUARDED(x_subs)
ReadGuard l(x_subs); for (auto i: m_subs)
for (auto i: m_subs) ret += i->m_asked;
ret += i->m_asked;
}
return ret; return ret;
} }
@ -144,12 +146,15 @@ public:
h256s remaining() const h256s remaining() const
{ {
h256s ret; h256s ret;
ReadGuard l(m_lock); DEV_READ_GUARDED(m_lock)
for (auto i: m_blocksGot.inverted()) for (auto i: m_blocksGot.inverted())
ret.push_back(m_chain[i]); ret.push_back(m_chain[i]);
return ret; return ret;
} }
h256 firstBlock() const { return m_chain.empty() ? h256() : m_chain[0]; }
Overview overview() const;
size_t chainSize() const { ReadGuard l(m_lock); return m_chain.size(); } size_t chainSize() const { ReadGuard l(m_lock); return m_chain.size(); }
size_t chainEmpty() const { ReadGuard l(m_lock); return m_chain.empty(); } size_t chainEmpty() const { ReadGuard l(m_lock); return m_chain.empty(); }
void foreachSub(std::function<void(DownloadSub const&)> const& _f) const { ReadGuard l(x_subs); for(auto i: m_subs) _f(*i); } void foreachSub(std::function<void(DownloadSub const&)> const& _f) const { ReadGuard l(x_subs); for(auto i: m_subs) _f(*i); }

Loading…
Cancel
Save