aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.qt.include5
-rw-r--r--src/checkpoints.cpp2
-rw-r--r--src/main.cpp22
-rw-r--r--src/pow.cpp2
-rw-r--r--src/qt/bitcoin.qrc3
-rw-r--r--src/qt/bitcoingui.cpp8
-rw-r--r--src/qt/bitcoingui.h6
-rw-r--r--src/qt/bitcoinunits.cpp11
-rw-r--r--src/qt/bitcoinunits.h2
-rw-r--r--src/qt/clientmodel.cpp2
-rw-r--r--src/qt/res/icons/unit_btc.pngbin0 -> 2107 bytes
-rw-r--r--src/qt/res/icons/unit_mbtc.pngbin0 -> 2107 bytes
-rw-r--r--src/qt/res/icons/unit_ubtc.pngbin0 -> 2107 bytes
-rw-r--r--src/qt/winshutdownmonitor.cpp19
-rw-r--r--src/rpcdump.cpp6
-rw-r--r--src/rpcmining.cpp2
-rw-r--r--src/rpcprotocol.cpp16
-rw-r--r--src/rpcrawtransaction.cpp4
-rw-r--r--src/rpcwallet.cpp6
-rw-r--r--src/test/skiplist_tests.cpp56
-rw-r--r--src/util.cpp6
-rw-r--r--src/wallet.cpp47
-rw-r--r--src/wallet.h3
23 files changed, 156 insertions, 72 deletions
diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index f2b6c2ccd6..d97c2d064a 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -252,7 +252,10 @@ RES_ICONS = \
qt/res/icons/tx_inout.png \
qt/res/icons/tx_input.png \
qt/res/icons/tx_output.png \
- qt/res/icons/tx_mined.png
+ qt/res/icons/tx_mined.png \
+ qt/res/icons/unit_btc.png \
+ qt/res/icons/unit_mbtc.png \
+ qt/res/icons/unit_ubtc.png
BITCOIN_QT_CPP = \
qt/bitcoinaddressvalidator.cpp \
diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp
index 80479b47fb..4cab11db3d 100644
--- a/src/checkpoints.cpp
+++ b/src/checkpoints.cpp
@@ -127,7 +127,7 @@ namespace Checkpoints {
} else {
double nCheapBefore = data.nTransactionsLastCheckpoint;
double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
- double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
+ double nExpensiveAfter = (nNow - pindex->GetBlockTime())/86400.0*data.fTransactionsPerDay;
fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
}
diff --git a/src/main.cpp b/src/main.cpp
index e08b794184..f0ecda9768 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -423,15 +423,13 @@ CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const {
break;
// Exponentially larger steps back, plus the genesis block.
int nHeight = std::max(pindex->nHeight - nStep, 0);
- // Jump back quickly to the same height as the chain.
- if (pindex->nHeight > nHeight)
- pindex = pindex->GetAncestor(nHeight);
- // In case pindex is not in this chain, iterate pindex->pprev to find blocks.
- while (!Contains(pindex))
- pindex = pindex->pprev;
- // If pindex is in this chain, use direct height-based access.
- if (pindex->nHeight > nHeight)
+ 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;
}
@@ -1788,7 +1786,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
// BIP16 didn't become active until Apr 1 2012
int64_t nBIP16SwitchTime = 1333238400;
- bool fStrictPayToScriptHash = (pindex->nTime >= nBIP16SwitchTime);
+ bool fStrictPayToScriptHash = (pindex->GetBlockTime() >= nBIP16SwitchTime);
unsigned int flags = SCRIPT_VERIFY_NOCACHE |
(fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE);
@@ -2437,7 +2435,7 @@ bool AcceptBlockHeader(CBlockHeader& block, CValidationState& state, CBlockIndex
if (pcheckpoint && block.hashPrevBlock != (chainActive.Tip() ? chainActive.Tip()->GetBlockHash() : uint256(0)))
{
// Extra checks to prevent "fill up memory by spamming with bogus blocks"
- int64_t deltaTime = block.GetBlockTime() - pcheckpoint->nTime;
+ int64_t deltaTime = block.GetBlockTime() - pcheckpoint->GetBlockTime();
if (deltaTime < 0)
{
return state.DoS(100, error("CheckBlockHeader() : block with timestamp before last checkpoint"),
@@ -2548,7 +2546,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
CDiskBlockPos blockPos;
if (dbp != NULL)
blockPos = *dbp;
- if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.nTime, dbp != NULL))
+ if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
return error("AcceptBlock() : FindBlockPos failed");
if (dbp == NULL)
if (!WriteBlockToDisk(block, blockPos))
@@ -3146,7 +3144,7 @@ bool InitBlockIndex() {
unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
CDiskBlockPos blockPos;
CValidationState state;
- if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.nTime))
+ if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
return error("LoadBlockIndex() : FindBlockPos failed");
if (!WriteBlockToDisk(block, blockPos))
return error("LoadBlockIndex() : writing genesis block to disk failed");
diff --git a/src/pow.cpp b/src/pow.cpp
index 952250decd..c0d0a7ca20 100644
--- a/src/pow.cpp
+++ b/src/pow.cpp
@@ -26,7 +26,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
// Special difficulty rule for testnet:
// If the new block's timestamp is more than 2* 10 minutes
// then allow mining of a min-difficulty block.
- if (pblock->nTime > pindexLast->nTime + Params().TargetSpacing()*2)
+ if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + Params().TargetSpacing()*2)
return nProofOfWorkLimit;
else
{
diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc
index f38200c7f7..357c6470d3 100644
--- a/src/qt/bitcoin.qrc
+++ b/src/qt/bitcoin.qrc
@@ -35,6 +35,9 @@
<file alias="tx_input">res/icons/tx_input.png</file>
<file alias="tx_output">res/icons/tx_output.png</file>
<file alias="tx_inout">res/icons/tx_inout.png</file>
+ <file alias="unit_btc">res/icons/unit_btc.png</file>
+ <file alias="unit_mbtc">res/icons/unit_mbtc.png</file>
+ <file alias="unit_ubtc">res/icons/unit_ubtc.png</file>
<file alias="lock_closed">res/icons/lock_closed.png</file>
<file alias="lock_open">res/icons/lock_open.png</file>
<file alias="key">res/icons/key.png</file>
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index f2fb8c877e..6b3aa2a2df 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -34,13 +34,10 @@
#include <QDesktopWidget>
#include <QDragEnterEvent>
#include <QIcon>
-#include <QLabel>
#include <QListWidget>
-#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
#include <QMimeData>
-#include <QPoint>
#include <QProgressBar>
#include <QProgressDialog>
#include <QSettings>
@@ -51,8 +48,6 @@
#include <QToolBar>
#include <QVBoxLayout>
-
-
#if QT_VERSION < 0x050000
#include <QUrl>
#include <QTextDocument>
@@ -1014,7 +1009,6 @@ UnitDisplayStatusBarControl::UnitDisplayStatusBarControl():QLabel()
{
optionsModel = 0;
createContextMenu();
- setStyleSheet("font:11pt; color: #333333");
setToolTip(tr("Unit to show amounts in. Click to select another unit."));
}
@@ -1059,7 +1053,7 @@ void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *optionsModel)
/** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */
void UnitDisplayStatusBarControl::updateDisplayUnit(int newUnits)
{
- setText(BitcoinUnits::name(newUnits));
+ setPixmap(QIcon(":/icons/unit_" + BitcoinUnits::id(newUnits)).pixmap(31,STATUSBAR_ICONSIZE));
}
/** Shows context menu with Display Unit options by the mouse coordinates */
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index 705e629a69..30dd7ae317 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -21,18 +21,14 @@ class Notificator;
class OptionsModel;
class RPCConsole;
class SendCoinsRecipient;
+class UnitDisplayStatusBarControl;
class WalletFrame;
class WalletModel;
class CWallet;
-class UnitDisplayStatusBarControl;
-
QT_BEGIN_NAMESPACE
class QAction;
-class QLabel;
-class QMenu;
-class QPoint;
class QProgressBar;
class QProgressDialog;
QT_END_NAMESPACE
diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp
index 4ba6aba551..bbc9b2e5af 100644
--- a/src/qt/bitcoinunits.cpp
+++ b/src/qt/bitcoinunits.cpp
@@ -34,6 +34,17 @@ bool BitcoinUnits::valid(int unit)
}
}
+QString BitcoinUnits::id(int unit)
+{
+ switch(unit)
+ {
+ case BTC: return QString("btc");
+ case mBTC: return QString("mbtc");
+ case uBTC: return QString("ubtc");
+ default: return QString("???");
+ }
+}
+
QString BitcoinUnits::name(int unit)
{
switch(unit)
diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h
index 451b52ee21..da34ed8976 100644
--- a/src/qt/bitcoinunits.h
+++ b/src/qt/bitcoinunits.h
@@ -36,6 +36,8 @@ public:
static QList<Unit> availableUnits();
//! Is unit ID valid?
static bool valid(int unit);
+ //! Identifier, e.g. for image names
+ static QString id(int unit);
//! Short name
static QString name(int unit);
//! Longer description
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index 9c9565be67..4c21eb5594 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -85,7 +85,7 @@ QDateTime ClientModel::getLastBlockDate() const
if (chainActive.Tip())
return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());
else
- return QDateTime::fromTime_t(Params().GenesisBlock().nTime); // Genesis block's time of current network
+ return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
}
double ClientModel::getVerificationProgress() const
diff --git a/src/qt/res/icons/unit_btc.png b/src/qt/res/icons/unit_btc.png
new file mode 100644
index 0000000000..ec3497435c
--- /dev/null
+++ b/src/qt/res/icons/unit_btc.png
Binary files differ
diff --git a/src/qt/res/icons/unit_mbtc.png b/src/qt/res/icons/unit_mbtc.png
new file mode 100644
index 0000000000..32bf2f2ca0
--- /dev/null
+++ b/src/qt/res/icons/unit_mbtc.png
Binary files differ
diff --git a/src/qt/res/icons/unit_ubtc.png b/src/qt/res/icons/unit_ubtc.png
new file mode 100644
index 0000000000..d5a154882b
--- /dev/null
+++ b/src/qt/res/icons/unit_ubtc.png
Binary files differ
diff --git a/src/qt/winshutdownmonitor.cpp b/src/qt/winshutdownmonitor.cpp
index f8f9bf45b3..a06f42f66e 100644
--- a/src/qt/winshutdownmonitor.cpp
+++ b/src/qt/winshutdownmonitor.cpp
@@ -6,11 +6,14 @@
#if defined(Q_OS_WIN) && QT_VERSION >= 0x050000
#include "init.h"
+#include "util.h"
#include <windows.h>
#include <QDebug>
+#include <openssl/rand.h>
+
// If we don't want a message to be processed by Qt, return true and set result to
// the value that the window procedure should return. Otherwise return false.
bool WinShutdownMonitor::nativeEventFilter(const QByteArray &eventType, void *pMessage, long *pnResult)
@@ -19,6 +22,16 @@ bool WinShutdownMonitor::nativeEventFilter(const QByteArray &eventType, void *pM
MSG *pMsg = static_cast<MSG *>(pMessage);
+ // Seed OpenSSL PRNG with Windows event data (e.g. mouse movements and other user interactions)
+ if (RAND_event(pMsg->message, pMsg->wParam, pMsg->lParam) == 0) {
+ // Warn only once as this is performance-critical
+ static bool warned = false;
+ if (!warned) {
+ LogPrint("%s: OpenSSL RAND_event() failed to seed OpenSSL PRNG with enough data.\n", __func__);
+ warned = true;
+ }
+ }
+
switch(pMsg->message)
{
case WM_QUERYENDSESSION:
@@ -45,13 +58,13 @@ void WinShutdownMonitor::registerShutdownBlockReason(const QString& strReason, c
typedef BOOL (WINAPI *PSHUTDOWNBRCREATE)(HWND, LPCWSTR);
PSHUTDOWNBRCREATE shutdownBRCreate = (PSHUTDOWNBRCREATE)GetProcAddress(GetModuleHandleA("User32.dll"), "ShutdownBlockReasonCreate");
if (shutdownBRCreate == NULL) {
- qWarning() << "registerShutdownBlockReason : GetProcAddress for ShutdownBlockReasonCreate failed";
+ qWarning() << "registerShutdownBlockReason: GetProcAddress for ShutdownBlockReasonCreate failed";
return;
}
if (shutdownBRCreate(mainWinId, strReason.toStdWString().c_str()))
- qWarning() << "registerShutdownBlockReason : Successfully registered: " + strReason;
+ qWarning() << "registerShutdownBlockReason: Successfully registered: " + strReason;
else
- qWarning() << "registerShutdownBlockReason : Failed to register: " + strReason;
+ qWarning() << "registerShutdownBlockReason: Failed to register: " + strReason;
}
#endif
diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp
index 593e0d2b6b..d20bfcf095 100644
--- a/src/rpcdump.cpp
+++ b/src/rpcdump.cpp
@@ -157,7 +157,7 @@ Value importwallet(const Array& params, bool fHelp)
if (!file.is_open())
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
- int64_t nTimeBegin = chainActive.Tip()->nTime;
+ int64_t nTimeBegin = chainActive.Tip()->GetBlockTime();
bool fGood = true;
@@ -215,7 +215,7 @@ Value importwallet(const Array& params, bool fHelp)
pwalletMain->ShowProgress("", 100); // hide progress dialog in GUI
CBlockIndex *pindex = chainActive.Tip();
- while (pindex && pindex->pprev && pindex->nTime > nTimeBegin - 7200)
+ while (pindex && pindex->pprev && pindex->GetBlockTime() > nTimeBegin - 7200)
pindex = pindex->pprev;
if (!pwalletMain->nTimeFirstKey || nTimeBegin < pwalletMain->nTimeFirstKey)
@@ -301,7 +301,7 @@ Value dumpwallet(const Array& params, bool fHelp)
file << strprintf("# Wallet dump created by Bitcoin %s (%s)\n", CLIENT_BUILD, CLIENT_DATE);
file << strprintf("# * Created on %s\n", EncodeDumpTime(GetTime()));
file << strprintf("# * Best block at time of backup was %i (%s),\n", chainActive.Height(), chainActive.Tip()->GetBlockHash().ToString());
- file << strprintf("# mined on %s\n", EncodeDumpTime(chainActive.Tip()->nTime));
+ file << strprintf("# mined on %s\n", EncodeDumpTime(chainActive.Tip()->GetBlockTime()));
file << "\n";
for (std::vector<std::pair<int64_t, CKeyID> >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) {
const CKeyID &keyid = it->second;
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index db60ef3592..c7621dc137 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -442,7 +442,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
result.push_back(Pair("noncerange", "00000000ffffffff"));
result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS));
result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE));
- result.push_back(Pair("curtime", (int64_t)pblock->nTime));
+ result.push_back(Pair("curtime", pblock->GetBlockTime()));
result.push_back(Pair("bits", strprintf("%08x", pblock->nBits)));
result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1)));
diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp
index dd8692e802..9e18ca847e 100644
--- a/src/rpcprotocol.cpp
+++ b/src/rpcprotocol.cpp
@@ -25,6 +25,9 @@ using namespace boost;
using namespace boost::asio;
using namespace json_spirit;
+// Number of bytes to allocate and read at most at once in post data
+const size_t POST_READ_SIZE = 256 * 1024;
+
//
// HTTP protocol
//
@@ -204,8 +207,17 @@ int ReadHTTPMessage(std::basic_istream<char>& stream, map<string,
// Read message
if (nLen > 0)
{
- vector<char> vch(nLen);
- stream.read(&vch[0], nLen);
+ vector<char> vch;
+ size_t ptr = 0;
+ while (ptr < (size_t)nLen)
+ {
+ size_t bytes_to_read = std::min((size_t)nLen - ptr, POST_READ_SIZE);
+ vch.resize(ptr + bytes_to_read);
+ stream.read(&vch[ptr], bytes_to_read);
+ if (!stream) // Connection lost while reading
+ return HTTP_INTERNAL_SERVER_ERROR;
+ ptr += bytes_to_read;
+ }
strMessageRet = string(vch.begin(), vch.end());
}
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
index 9771f8e685..45a227d1dc 100644
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -99,8 +99,8 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
if (chainActive.Contains(pindex))
{
entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight));
- entry.push_back(Pair("time", (int64_t)pindex->nTime));
- entry.push_back(Pair("blocktime", (int64_t)pindex->nTime));
+ entry.push_back(Pair("time", pindex->GetBlockTime()));
+ entry.push_back(Pair("blocktime", pindex->GetBlockTime()));
}
else
entry.push_back(Pair("confirmations", 0));
diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp
index 38e96133b4..71a6058358 100644
--- a/src/rpcwallet.cpp
+++ b/src/rpcwallet.cpp
@@ -50,7 +50,7 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
{
entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
entry.push_back(Pair("blockindex", wtx.nIndex));
- entry.push_back(Pair("blocktime", (int64_t)(mapBlockIndex[wtx.hashBlock]->nTime)));
+ entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()));
}
uint256 hash = wtx.GetHash();
entry.push_back(Pair("txid", hash.GetHex()));
@@ -346,7 +346,7 @@ Value sendtoaddress(const Array& params, bool fHelp)
EnsureWalletIsUnlocked();
- string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
+ string strError = pwalletMain->SendMoney(address.Get(), nAmount, wtx);
if (strError != "")
throw JSONRPCError(RPC_WALLET_ERROR, strError);
@@ -786,7 +786,7 @@ Value sendfrom(const Array& params, bool fHelp)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
// Send
- string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
+ string strError = pwalletMain->SendMoney(address.Get(), nAmount, wtx);
if (strError != "")
throw JSONRPCError(RPC_WALLET_ERROR, strError);
diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp
index ea301685c9..11762c6ea0 100644
--- a/src/test/skiplist_tests.cpp
+++ b/src/test/skiplist_tests.cpp
@@ -41,5 +41,61 @@ BOOST_AUTO_TEST_CASE(skiplist_test)
}
}
+BOOST_AUTO_TEST_CASE(getlocator_test)
+{
+ // Build a main chain 100000 blocks long.
+ std::vector<uint256> vHashMain(100000);
+ std::vector<CBlockIndex> vBlocksMain(100000);
+ for (unsigned int i=0; i<vBlocksMain.size(); i++) {
+ vHashMain[i] = i; // Set the hash equal to the height, so we can quickly check the distances.
+ vBlocksMain[i].nHeight = i;
+ vBlocksMain[i].pprev = i ? &vBlocksMain[i - 1] : NULL;
+ vBlocksMain[i].phashBlock = &vHashMain[i];
+ vBlocksMain[i].BuildSkip();
+ BOOST_CHECK_EQUAL((int)vBlocksMain[i].GetBlockHash().GetLow64(), vBlocksMain[i].nHeight);
+ BOOST_CHECK(vBlocksMain[i].pprev == NULL || vBlocksMain[i].nHeight == vBlocksMain[i].pprev->nHeight + 1);
+ }
+
+ // Build a branch that splits off at block 49999, 50000 blocks long.
+ std::vector<uint256> vHashSide(50000);
+ std::vector<CBlockIndex> vBlocksSide(50000);
+ for (unsigned int i=0; i<vBlocksSide.size(); i++) {
+ vHashSide[i] = i + 50000 + (uint256(1) << 128); // Add 1<<128 to the hashes, so GetLow64() still returns the height.
+ vBlocksSide[i].nHeight = i + 50000;
+ vBlocksSide[i].pprev = i ? &vBlocksSide[i - 1] : &vBlocksMain[49999];
+ vBlocksSide[i].phashBlock = &vHashSide[i];
+ vBlocksSide[i].BuildSkip();
+ BOOST_CHECK_EQUAL((int)vBlocksSide[i].GetBlockHash().GetLow64(), vBlocksSide[i].nHeight);
+ BOOST_CHECK(vBlocksSide[i].pprev == NULL || vBlocksSide[i].nHeight == vBlocksSide[i].pprev->nHeight + 1);
+ }
+
+ // Build a CChain for the main branch.
+ CChain chain;
+ chain.SetTip(&vBlocksMain.back());
+
+ // Test 100 random starting points for locators.
+ for (int n=0; n<100; n++) {
+ int r = insecure_rand() % 150000;
+ CBlockIndex* tip = (r < 100000) ? &vBlocksMain[r] : &vBlocksSide[r - 100000];
+ CBlockLocator locator = chain.GetLocator(tip);
+
+ // The first result must be the block itself, the last one must be genesis.
+ BOOST_CHECK(locator.vHave.front() == tip->GetBlockHash());
+ BOOST_CHECK(locator.vHave.back() == vBlocksMain[0].GetBlockHash());
+
+ // Entries 1 through 11 (inclusive) go back one step each.
+ for (unsigned int i = 1; i < 12 && i < locator.vHave.size() - 1; i++) {
+ BOOST_CHECK_EQUAL(locator.vHave[i].GetLow64(), tip->nHeight - i);
+ }
+
+ // The further ones (excluding the last one) go back with exponential steps.
+ unsigned int dist = 2;
+ for (unsigned int i = 12; i < locator.vHave.size() - 1; i++) {
+ BOOST_CHECK_EQUAL(locator.vHave[i - 1].GetLow64() - locator.vHave[i].GetLow64(), dist);
+ dist *= 2;
+ }
+ }
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/util.cpp b/src/util.cpp
index 9adbbdec48..91ac8833d5 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -121,15 +121,17 @@ public:
CRYPTO_set_locking_callback(locking_callback);
#ifdef WIN32
- // Seed random number generator with screen scrape and other hardware sources
+ // Seed OpenSSL PRNG with current contents of the screen
RAND_screen();
#endif
- // Seed random number generator with performance counter
+ // Seed OpenSSL PRNG with performance counter
RandAddSeed();
}
~CInit()
{
+ // Securely erase the memory used by the PRNG
+ RAND_cleanup();
// Shutdown OpenSSL library multithreading support
CRYPTO_set_locking_callback(NULL);
for (int i = 0; i < CRYPTO_num_locks(); i++)
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 318a1388d2..090c1b5ab3 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -515,8 +515,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet)
{
if (mapBlockIndex.count(wtxIn.hashBlock))
{
- unsigned int latestNow = wtx.nTimeReceived;
- unsigned int latestEntry = 0;
+ int64_t latestNow = wtx.nTimeReceived;
+ int64_t latestEntry = 0;
{
// Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
int64_t latestTolerated = latestNow + 300;
@@ -547,7 +547,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet)
}
}
- unsigned int& blocktime = mapBlockIndex[wtxIn.hashBlock]->nTime;
+ int64_t blocktime = mapBlockIndex[wtxIn.hashBlock]->GetBlockTime();
wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
}
else
@@ -889,7 +889,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
// no need to read and scan block, if block was created before
// our wallet birthday (as adjusted for block time variability)
- while (pindex && nTimeFirstKey && (pindex->nTime < (nTimeFirstKey - 7200)))
+ while (pindex && nTimeFirstKey && (pindex->GetBlockTime() < (nTimeFirstKey - 7200)))
pindex = chainActive.Next(pindex);
ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
@@ -1487,18 +1487,29 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
-string CWallet::SendMoney(CScript scriptPubKey, int64_t nValue, CWalletTx& wtxNew)
+string CWallet::SendMoney(const CTxDestination &address, int64_t nValue, CWalletTx& wtxNew)
{
- CReserveKey reservekey(this);
- int64_t nFeeRequired;
+ // Check amount
+ if (nValue <= 0)
+ return _("Invalid amount");
+ if (nValue > GetBalance())
+ return _("Insufficient funds");
+ string strError;
if (IsLocked())
{
- string strError = _("Error: Wallet locked, unable to create transaction!");
+ strError = _("Error: Wallet locked, unable to create transaction!");
LogPrintf("SendMoney() : %s", strError);
return strError;
}
- string strError;
+
+ // Parse Bitcoin address
+ CScript scriptPubKey;
+ scriptPubKey.SetDestination(address);
+
+ // Create and send the transaction
+ CReserveKey reservekey(this);
+ int64_t nFeeRequired;
if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError))
{
if (nValue + nFeeRequired > GetBalance())
@@ -1506,7 +1517,6 @@ string CWallet::SendMoney(CScript scriptPubKey, int64_t nValue, CWalletTx& wtxNe
LogPrintf("SendMoney() : %s\n", strError);
return strError;
}
-
if (!CommitTransaction(wtxNew, reservekey))
return _("Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
@@ -1515,21 +1525,6 @@ string CWallet::SendMoney(CScript scriptPubKey, int64_t nValue, CWalletTx& wtxNe
-string CWallet::SendMoneyToDestination(const CTxDestination& address, int64_t nValue, CWalletTx& wtxNew)
-{
- // Check amount
- if (nValue <= 0)
- return _("Invalid amount");
- if (nValue > GetBalance())
- return _("Insufficient funds");
-
- // Parse Bitcoin address
- CScript scriptPubKey;
- scriptPubKey.SetDestination(address);
-
- return SendMoney(scriptPubKey, nValue, wtxNew);
-}
-
int64_t CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool)
{
// payTxFee is user-set "I want to pay this much"
@@ -2092,7 +2087,7 @@ void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
// Extract block timestamps for those keys
for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
- mapKeyBirth[it->first] = it->second->nTime - 7200; // block times can be 2h off
+ mapKeyBirth[it->first] = it->second->GetBlockTime() - 7200; // block times can be 2h off
}
bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
diff --git a/src/wallet.h b/src/wallet.h
index a5162bb838..62f13e4630 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -265,8 +265,7 @@ public:
bool CreateTransaction(CScript scriptPubKey, int64_t nValue,
CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl = NULL);
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
- std::string SendMoney(CScript scriptPubKey, int64_t nValue, CWalletTx& wtxNew);
- std::string SendMoneyToDestination(const CTxDestination &address, int64_t nValue, CWalletTx& wtxNew);
+ std::string SendMoney(const CTxDestination &address, int64_t nValue, CWalletTx& wtxNew);
static CFeeRate minTxFee;
static int64_t GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool);