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::eth;
DownloadView::DownloadView(QWidget* _p): QWidget(_p)
SyncView::SyncView(QWidget* _p): QWidget(_p)
{
}
void DownloadView::paintEvent(QPaintEvent*)
void SyncView::paintEvent(QPaintEvent*)
{
QPainter p(this);
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;
}
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();
if (ratio < 1)
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(n, n);
QPointF pos(0, 0);
auto bg = m_man->blocksGot();
unsigned subCount = m_man->subCount();
auto bg = man->blocksGot();
unsigned subCount = man->subCount();
if (subCount == 0)
return;
unsigned dh = 360 / subCount;
@ -64,7 +130,7 @@ void DownloadView::paintEvent(QPaintEvent*)
else
{
unsigned h = 0;
m_man->foreachSub([&](DownloadSub const& sub)
man->foreachSub([&](DownloadSub const& sub)
{
if (sub.askedContains(i))
s = h;

12
alethzero/DownloadView.h

@ -32,21 +32,23 @@
#endif
namespace dev { namespace eth {
class DownloadMan;
class Client;
}}
class DownloadView: public QWidget
class SyncView: public QWidget
{
Q_OBJECT
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:
virtual void paintEvent(QPaintEvent*);
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>
</property>
<item>
<widget class="DownloadView" name="downloadView" native="true"/>
<widget class="SyncView" name="downloadView" native="true"/>
</item>
</layout>
</widget>
@ -1814,7 +1814,7 @@ font-size: 14pt</string>
<container>1</container>
</customwidget>
<customwidget>
<class>DownloadView</class>
<class>SyncView</class>
<extends>QWidget</extends>
<header>DownloadView.h</header>
<container>1</container>

4
alethzero/MainWin.cpp

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

2
exp/main.cpp

@ -135,7 +135,7 @@ int main()
DownloadSub s0(man);
DownloadSub s1(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((s1.nextFetch(2) == h256Set{(u256)5, (u256)6}));
assert((s2.nextFetch(2) == h256Set{(u256)3, (u256)4}));

14
libdevcore/RangeMask.h

@ -200,6 +200,20 @@ public:
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:
/// The ground range.
UnsignedRange m_all;

2
libethereum/BlockChainSync.cpp

@ -80,7 +80,7 @@ DownloadMan& BlockChainSync::downloadMan()
void BlockChainSync::abortSync()
{
downloadMan().resetToChain(h256s());
downloadMan().reset();
}
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::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)
{
WriteGuard l(m_man->x_subs);

33
libethereum/DownloadMan.h

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

Loading…
Cancel
Save