diff options
-rw-r--r-- | src/Makefile.qt.include | 5 | ||||
-rw-r--r-- | src/checkpoints.cpp | 2 | ||||
-rw-r--r-- | src/main.cpp | 22 | ||||
-rw-r--r-- | src/pow.cpp | 2 | ||||
-rw-r--r-- | src/qt/bitcoin.qrc | 3 | ||||
-rw-r--r-- | src/qt/bitcoingui.cpp | 8 | ||||
-rw-r--r-- | src/qt/bitcoingui.h | 6 | ||||
-rw-r--r-- | src/qt/bitcoinunits.cpp | 11 | ||||
-rw-r--r-- | src/qt/bitcoinunits.h | 2 | ||||
-rw-r--r-- | src/qt/clientmodel.cpp | 2 | ||||
-rw-r--r-- | src/qt/res/icons/unit_btc.png | bin | 0 -> 2107 bytes | |||
-rw-r--r-- | src/qt/res/icons/unit_mbtc.png | bin | 0 -> 2107 bytes | |||
-rw-r--r-- | src/qt/res/icons/unit_ubtc.png | bin | 0 -> 2107 bytes | |||
-rw-r--r-- | src/qt/winshutdownmonitor.cpp | 19 | ||||
-rw-r--r-- | src/rpcdump.cpp | 6 | ||||
-rw-r--r-- | src/rpcmining.cpp | 2 | ||||
-rw-r--r-- | src/rpcprotocol.cpp | 16 | ||||
-rw-r--r-- | src/rpcrawtransaction.cpp | 4 | ||||
-rw-r--r-- | src/rpcwallet.cpp | 6 | ||||
-rw-r--r-- | src/test/skiplist_tests.cpp | 56 | ||||
-rw-r--r-- | src/util.cpp | 6 | ||||
-rw-r--r-- | src/wallet.cpp | 47 | ||||
-rw-r--r-- | src/wallet.h | 3 |
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 Binary files differnew file mode 100644 index 0000000000..ec3497435c --- /dev/null +++ b/src/qt/res/icons/unit_btc.png diff --git a/src/qt/res/icons/unit_mbtc.png b/src/qt/res/icons/unit_mbtc.png Binary files differnew file mode 100644 index 0000000000..32bf2f2ca0 --- /dev/null +++ b/src/qt/res/icons/unit_mbtc.png diff --git a/src/qt/res/icons/unit_ubtc.png b/src/qt/res/icons/unit_ubtc.png Binary files differnew file mode 100644 index 0000000000..d5a154882b --- /dev/null +++ b/src/qt/res/icons/unit_ubtc.png 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); |