aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2013-02-10 19:46:42 +0100
committerPieter Wuille <pieter.wuille@gmail.com>2013-02-16 14:51:00 +0100
commit9f2467ad6241ce6cf0897ed30c676598d59441a7 (patch)
tree88f4a58c49b2982ce57098f2e30cd860a2ea352a
parent24cde0b7d1ad014ffca5d0af896bc50b30e5ddcd (diff)
Transactions-based verification progress
-rw-r--r--src/checkpoints.cpp75
-rw-r--r--src/checkpoints.h2
-rw-r--r--src/qt/bitcoingui.cpp4
-rw-r--r--src/qt/clientmodel.cpp5
-rw-r--r--src/qt/clientmodel.h1
5 files changed, 79 insertions, 8 deletions
diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp
index e2c420edd7..9b11f0b351 100644
--- a/src/checkpoints.cpp
+++ b/src/checkpoints.cpp
@@ -14,13 +14,25 @@ namespace Checkpoints
{
typedef std::map<int, uint256> MapCheckpoints;
- //
+ // How many times we expect transactions after the last checkpoint to
+ // be slower. This number is conservative. On multi-core CPUs with
+ // parallel signature checking enabled, this number is way too high.
+ // We prefer a progressbar that's faster at the end than the other
+ // way around, though.
+ static const double fSigcheckVerificationFactor = 15.0;
+
+ struct CCheckpointData {
+ const MapCheckpoints *mapCheckpoints;
+ int64 nTimeLastCheckpoint;
+ int64 nTransactionsLastCheckpoint;
+ double fTransactionsPerDay;
+ };
+
// What makes a good checkpoint block?
// + Is surrounded by blocks with reasonable timestamps
// (no blocks before with a timestamp after, none after with
// timestamp before)
// + Contains no strange transactions
- //
static MapCheckpoints mapCheckpoints =
boost::assign::map_list_of
( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
@@ -33,30 +45,81 @@ namespace Checkpoints
(210000, uint256("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
(216116, uint256("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e"))
;
+ static const CCheckpointData data = {
+ &mapCheckpoints,
+ 1357902690, // * UNIX timestamp of last checkpoint block
+ 11011160, // * total number of transactions between genesis and last checkpoint
+ // (the tx=... number in the SetBestChain debug.log lines)
+ 50000.0 // * estimated number of transactions per day after checkpoint
+ };
- static MapCheckpoints mapCheckpointsTestnet =
+ static MapCheckpoints mapCheckpointsTestnet =
boost::assign::map_list_of
( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
;
+ static const CCheckpointData dataTestnet = {
+ &mapCheckpointsTestnet,
+ 1338180505,
+ 16341,
+ 300
+ };
+
+ const CCheckpointData &Checkpoints() {
+ if (fTestNet)
+ return dataTestnet;
+ else
+ return data;
+ }
bool CheckBlock(int nHeight, const uint256& hash)
{
if (!GetBoolArg("-checkpoints", true))
return true;
- MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);
+ const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;
MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
if (i == checkpoints.end()) return true;
return hash == i->second;
}
+ // Guess how far we are in the verification process at the given block index
+ double GuessVerificationProgress(CBlockIndex *pindex) {
+ if (pindex==NULL)
+ return 0.0;
+
+ int64 nNow = time(NULL);
+
+ double fWorkBefore = 0.0; // Amount of work done before pindex
+ double fWorkAfter = 0.0; // Amount of work left after pindex (estimated)
+ // Work is defined as: 1.0 per transaction before the last checkoint, and
+ // fSigcheckVerificationFactor per transaction after.
+
+ const CCheckpointData &data = Checkpoints();
+
+ if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
+ double nCheapBefore = pindex->nChainTx;
+ double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
+ double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
+ fWorkBefore = nCheapBefore;
+ fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
+ } else {
+ double nCheapBefore = data.nTransactionsLastCheckpoint;
+ double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
+ double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
+ fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
+ fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
+ }
+
+ return fWorkBefore / (fWorkBefore + fWorkAfter);
+ }
+
int GetTotalBlocksEstimate()
{
if (!GetBoolArg("-checkpoints", true))
return 0;
- MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);
+ const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;
return checkpoints.rbegin()->first;
}
@@ -66,7 +129,7 @@ namespace Checkpoints
if (!GetBoolArg("-checkpoints", true))
return NULL;
- MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);
+ const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;
BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
{
diff --git a/src/checkpoints.h b/src/checkpoints.h
index 70e936564c..dcfb44e10f 100644
--- a/src/checkpoints.h
+++ b/src/checkpoints.h
@@ -22,6 +22,8 @@ namespace Checkpoints
// Returns last CBlockIndex* in mapBlockIndex that is a checkpoint
CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex);
+
+ double GuessVerificationProgress(CBlockIndex *pindex);
}
#endif
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 635e0cb34b..16bc0a47de 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -572,8 +572,8 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
progressBarLabel->setText(importText);
progressBarLabel->setVisible(true);
progressBar->setFormat(tr("%1 behind").arg(timeBehindText));
- progressBar->setMaximum(totalSecs);
- progressBar->setValue(totalSecs - secs);
+ progressBar->setMaximum(1000000000);
+ progressBar->setValue(clientModel->getVerificationProgress() * 1000000000.0 + 0.5);
progressBar->setVisible(true);
tooltip = tr("Catching up...") + QString("<br>") + tooltip;
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index 5f3368c30a..858fbe241f 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -6,6 +6,7 @@
#include "alert.h"
#include "main.h"
+#include "checkpoints.h"
#include "ui_interface.h"
#include <QDateTime>
@@ -54,6 +55,10 @@ QDateTime ClientModel::getLastBlockDate() const
return QDateTime::fromTime_t(1231006505); // Genesis block's time
}
+double ClientModel::getVerificationProgress() const
+{
+ return Checkpoints::GuessVerificationProgress(pindexBest);
+}
void ClientModel::updateTimer()
{
diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h
index 1afccb7859..a3fe92048c 100644
--- a/src/qt/clientmodel.h
+++ b/src/qt/clientmodel.h
@@ -34,6 +34,7 @@ public:
int getNumBlocks() const;
int getNumBlocksAtStartup();
+ double getVerificationProgress() const;
QDateTime getLastBlockDate() const;
//! Return true if client connected to testnet