diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.test.include | 1 | ||||
-rw-r--r-- | src/addrman.h | 2 | ||||
-rw-r--r-- | src/ecwrapper.cpp | 33 | ||||
-rw-r--r-- | src/leveldbwrapper.cpp | 3 | ||||
-rw-r--r-- | src/limitedmap.h | 19 | ||||
-rw-r--r-- | src/main.cpp | 2 | ||||
-rw-r--r-- | src/merkleblock.cpp | 2 | ||||
-rw-r--r-- | src/miner.cpp | 6 | ||||
-rw-r--r-- | src/net.cpp | 2 | ||||
-rw-r--r-- | src/net.h | 2 | ||||
-rw-r--r-- | src/netbase.cpp | 2 | ||||
-rw-r--r-- | src/policy/fees.cpp | 2 | ||||
-rw-r--r-- | src/policy/fees.h | 2 | ||||
-rw-r--r-- | src/qt/paymentserver.cpp | 2 | ||||
-rw-r--r-- | src/qt/rpcconsole.cpp | 2 | ||||
-rw-r--r-- | src/qt/splashscreen.cpp | 2 | ||||
-rw-r--r-- | src/rest.cpp | 56 | ||||
-rw-r--r-- | src/rpcblockchain.cpp | 97 | ||||
-rw-r--r-- | src/rpcmining.cpp | 6 | ||||
-rw-r--r-- | src/rpcserver.cpp | 4 | ||||
-rw-r--r-- | src/scheduler.cpp | 12 | ||||
-rw-r--r-- | src/script/interpreter.cpp | 2 | ||||
-rw-r--r-- | src/sync.h | 2 | ||||
-rw-r--r-- | src/test/data/tx_invalid.json | 4 | ||||
-rw-r--r-- | src/test/data/tx_valid.json | 2 | ||||
-rw-r--r-- | src/test/limitedmap_tests.cpp | 101 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 2 |
27 files changed, 287 insertions, 85 deletions
diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 8289198959..fc4e047c35 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -52,6 +52,7 @@ BITCOIN_TESTS =\ test/getarg_tests.cpp \ test/hash_tests.cpp \ test/key_tests.cpp \ + test/limitedmap_tests.cpp \ test/main_tests.cpp \ test/mempool_tests.cpp \ test/miner_tests.cpp \ diff --git a/src/addrman.h b/src/addrman.h index 2623d89809..384b6cfdb9 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -265,7 +265,7 @@ public: * Notice that vvTried, mapAddr and vVector are never encoded explicitly; * they are instead reconstructed from the other information. * - * vvNew is serialized, but only used if ADDRMAN_UNKOWN_BUCKET_COUNT didn't change, + * vvNew is serialized, but only used if ADDRMAN_UNKNOWN_BUCKET_COUNT didn't change, * otherwise it is reconstructed as well. * * This format is more complex, but significantly smaller (at most 1.5 MiB), and supports diff --git a/src/ecwrapper.cpp b/src/ecwrapper.cpp index 5e3aec25ba..f94bc954fd 100644 --- a/src/ecwrapper.cpp +++ b/src/ecwrapper.cpp @@ -13,6 +13,29 @@ namespace { +class ecgroup_order +{ +public: + static const EC_GROUP* get() + { + static const ecgroup_order wrapper; + return wrapper.pgroup; + } + +private: + ecgroup_order() + : pgroup(EC_GROUP_new_by_curve_name(NID_secp256k1)) + { + } + + ~ecgroup_order() + { + EC_GROUP_free(pgroup); + } + + EC_GROUP* pgroup; +}; + /** * Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields * recid selects which key is recovered @@ -92,8 +115,10 @@ err: } // anon namespace CECKey::CECKey() { - pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + pkey = EC_KEY_new(); assert(pkey != NULL); + int result = EC_KEY_set_group(pkey, ecgroup_order::get()); + assert(result); } CECKey::~CECKey() { @@ -185,11 +210,9 @@ bool CECKey::TweakPublic(const unsigned char vchTweak[32]) { bool CECKey::SanityCheck() { - EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1); - if(pkey == NULL) + const EC_GROUP *pgroup = ecgroup_order::get(); + if(pgroup == NULL) return false; - EC_KEY_free(pkey); - // TODO Is there more EC functionality that could be missing? return true; } diff --git a/src/leveldbwrapper.cpp b/src/leveldbwrapper.cpp index c353dfa6d9..26cacf95ae 100644 --- a/src/leveldbwrapper.cpp +++ b/src/leveldbwrapper.cpp @@ -58,7 +58,8 @@ CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path& path, size_t nCa } else { if (fWipe) { LogPrintf("Wiping LevelDB in %s\n", path.string()); - leveldb::DestroyDB(path.string(), options); + leveldb::Status result = leveldb::DestroyDB(path.string(), options); + HandleError(result); } TryCreateDirectory(path); LogPrintf("Opening LevelDB in %s\n", path.string()); diff --git a/src/limitedmap.h b/src/limitedmap.h index e8ea549653..5456dfc7c4 100644 --- a/src/limitedmap.h +++ b/src/limitedmap.h @@ -27,7 +27,11 @@ protected: size_type nMaxSize; public: - limitedmap(size_type nMaxSizeIn = 0) { nMaxSize = nMaxSizeIn; } + limitedmap(size_type nMaxSizeIn) + { + assert(nMaxSizeIn > 0); + nMaxSize = nMaxSizeIn; + } const_iterator begin() const { return map.begin(); } const_iterator end() const { return map.end(); } size_type size() const { return map.size(); } @@ -38,13 +42,12 @@ public: { std::pair<iterator, bool> ret = map.insert(x); if (ret.second) { - if (nMaxSize && map.size() == nMaxSize) { + if (map.size() > nMaxSize) { map.erase(rmap.begin()->second); rmap.erase(rmap.begin()); } rmap.insert(make_pair(x.second, ret.first)); } - return; } void erase(const key_type& k) { @@ -81,11 +84,11 @@ public: size_type max_size() const { return nMaxSize; } size_type max_size(size_type s) { - if (s) - while (map.size() > s) { - map.erase(rmap.begin()->second); - rmap.erase(rmap.begin()); - } + assert(s > 0); + while (map.size() > s) { + map.erase(rmap.begin()->second); + rmap.erase(rmap.begin()); + } nMaxSize = s; return nMaxSize; } diff --git a/src/main.cpp b/src/main.cpp index 9f42819a0a..33b57a5285 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1457,7 +1457,7 @@ bool AbortNode(const std::string& strMessage, const std::string& userMessage="") strMiscWarning = strMessage; LogPrintf("*** %s\n", strMessage); uiInterface.ThreadSafeMessageBox( - userMessage.empty() ? _("Error: A fatal internal error occured, see debug.log for details") : userMessage, + userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage, "", CClientUIInterface::MSG_ERROR); StartShutdown(); return false; diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index 4d90fd8cd7..f8e877df25 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -168,7 +168,7 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) { // traverse the partial tree unsigned int nBitsUsed = 0, nHashUsed = 0; uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch); - // verify that no problems occured during the tree traversal + // verify that no problems occurred during the tree traversal if (fBad) return uint256(); // verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence) diff --git a/src/miner.cpp b/src/miner.cpp index 4172266067..9dd1d459b5 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -444,8 +444,10 @@ void static BitcoinMiner(const CChainParams& chainparams) GetMainSignals().ScriptForMining(coinbaseScript); try { - //throw an error if no script was provided - if (!coinbaseScript->reserveScript.size()) + // Throw an error if no script was provided. This can happen + // due to some internal error but also if the keypool is empty. + // In the latter case, already the pointer is NULL. + if (!coinbaseScript || coinbaseScript->reserveScript.empty()) throw std::runtime_error("No coinbase script available (mining requires a wallet)"); while (true) { diff --git a/src/net.cpp b/src/net.cpp index e4ead3c92e..fb5726a2b9 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2319,7 +2319,7 @@ void DumpBanlist() { int64_t nStart = GetTimeMillis(); - CNode::SweepBanned(); //clean unused entires (if bantime has expired) + CNode::SweepBanned(); //clean unused entries (if bantime has expired) CBanDB bandb; banmap_t banmap; @@ -695,7 +695,7 @@ public: static bool BannedSetIsDirty(); //!set the "dirty" flag for the banlist static void SetBannedSetDirty(bool dirty=true); - //!clean unused entires (if bantime has expired) + //!clean unused entries (if bantime has expired) static void SweepBanned(); void copyStats(CNodeStats &stats); diff --git a/src/netbase.cpp b/src/netbase.cpp index 259e5c14a3..7a87d125c2 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -349,7 +349,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials } if (pchRetA[0] != 0x01 || pchRetA[1] != 0x00) { CloseSocket(hSocket); - return error("Proxy authentication unsuccesful"); + return error("Proxy authentication unsuccessful"); } } else if (pchRet1[1] == 0x00) { // Perform no authentication diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index cdee541d2f..ffe31d1942 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -261,7 +261,7 @@ void TxConfirmStats::removeTx(unsigned int entryHeight, unsigned int nBestSeenHe blocksAgo = 0; if (blocksAgo < 0) { LogPrint("estimatefee", "Blockpolicy error, blocks ago is negative for mempool tx\n"); - return; //This can't happen becasue we call this with our best seen height, no entries can have higher + return; //This can't happen because we call this with our best seen height, no entries can have higher } if (blocksAgo >= (int)unconfTxs.size()) { diff --git a/src/policy/fees.h b/src/policy/fees.h index ce4d782566..15577d128a 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -118,7 +118,7 @@ public: /** * Initialize the data structures. This is called by BlockPolicyEstimator's * constructor with default values. - * @param defaultBuckets contains the upper limits for the bucket boundries + * @param defaultBuckets contains the upper limits for the bucket boundaries * @param maxConfirms max number of confirms to track * @param decay how much to decay the historical moving average per block * @param dataTypeString for logging purposes diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 0827d99125..5cc4d00dbf 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -762,7 +762,7 @@ void PaymentServer::setOptionsModel(OptionsModel *optionsModel) void PaymentServer::handlePaymentACK(const QString& paymentACKMsg) { - // currently we don't futher process or store the paymentACK message + // currently we don't further process or store the paymentACK message Q_EMIT message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL); } diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 35729bbb8b..d9d4f1d0ed 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -570,7 +570,7 @@ void RPCConsole::peerLayoutChanged() if (detailNodeRow < 0) { - // detail node dissapeared from table (node disconnected) + // detail node disappeared from table (node disconnected) fUnselect = true; } else diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 8430e017c1..c15b64c327 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -57,7 +57,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) QPainter pixPaint(&pixmap); pixPaint.setPen(QColor(100,100,100)); - // draw a slighly radial gradient + // draw a slightly radial gradient QRadialGradient gradient(QPoint(0,0), splashSize.width()/devicePixelRatio); gradient.setColorAt(0, Qt::white); gradient.setColorAt(1, QColor(247,247,247)); diff --git a/src/rest.cpp b/src/rest.cpp index 0dd238b683..74d27e73bb 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -65,6 +65,8 @@ public: extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); +extern UniValue mempoolInfoToJSON(); +extern UniValue mempoolToJSON(bool fVerbose = false); extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); extern UniValue blockheaderToJSON(const CBlockIndex* blockindex); @@ -293,6 +295,58 @@ static bool rest_chaininfo(AcceptedConnection* conn, return true; // continue to process further HTTP reqs on this cxn } +static bool rest_mempool_info(AcceptedConnection* conn, + const std::string& strURIPart, + const std::string& strRequest, + const std::map<std::string, std::string>& mapHeaders, + bool fRun) +{ + vector<string> params; + const RetFormat rf = ParseDataFormat(params, strURIPart); + + switch (rf) { + case RF_JSON: { + UniValue mempoolInfoObject = mempoolInfoToJSON(); + + string strJSON = mempoolInfoObject.write() + "\n"; + conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + return true; + } + default: { + throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: json)"); + } + } + + // not reached + return true; // continue to process further HTTP reqs on this cxn +} + +static bool rest_mempool_contents(AcceptedConnection* conn, + const std::string& strURIPart, + const std::string& strRequest, + const std::map<std::string, std::string>& mapHeaders, + bool fRun) +{ + vector<string> params; + const RetFormat rf = ParseDataFormat(params, strURIPart); + + switch (rf) { + case RF_JSON: { + UniValue mempoolObject = mempoolToJSON(true); + + string strJSON = mempoolObject.write() + "\n"; + conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + return true; + } + default: { + throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: json)"); + } + } + + // not reached + return true; // continue to process further HTTP reqs on this cxn +} + static bool rest_tx(AcceptedConnection* conn, const std::string& strURIPart, const std::string& strRequest, @@ -553,6 +607,8 @@ static const struct { {"/rest/block/notxdetails/", rest_block_notxdetails}, {"/rest/block/", rest_block_extended}, {"/rest/chaininfo", rest_chaininfo}, + {"/rest/mempool/info", rest_mempool_info}, + {"/rest/mempool/contents", rest_mempool_contents}, {"/rest/headers/", rest_headers}, {"/rest/getutxos", rest_getutxos}, }; diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 80d49490d2..e6751de96b 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -175,45 +175,8 @@ UniValue getdifficulty(const UniValue& params, bool fHelp) return GetDifficulty(); } - -UniValue getrawmempool(const UniValue& params, bool fHelp) +UniValue mempoolToJSON(bool fVerbose = false) { - if (fHelp || params.size() > 1) - throw runtime_error( - "getrawmempool ( verbose )\n" - "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n" - "\nArguments:\n" - "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" - "\nResult: (for verbose = false):\n" - "[ (json array of string)\n" - " \"transactionid\" (string) The transaction id\n" - " ,...\n" - "]\n" - "\nResult: (for verbose = true):\n" - "{ (json object)\n" - " \"transactionid\" : { (json object)\n" - " \"size\" : n, (numeric) transaction size in bytes\n" - " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n" - " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" - " \"height\" : n, (numeric) block height when transaction entered pool\n" - " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n" - " \"currentpriority\" : n, (numeric) transaction priority now\n" - " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" - " \"transactionid\", (string) parent transaction id\n" - " ... ]\n" - " }, ...\n" - "}\n" - "\nExamples\n" - + HelpExampleCli("getrawmempool", "true") - + HelpExampleRpc("getrawmempool", "true") - ); - - LOCK(cs_main); - - bool fVerbose = false; - if (params.size() > 0) - fVerbose = params[0].get_bool(); - if (fVerbose) { LOCK(mempool.cs); @@ -261,6 +224,47 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) } } +UniValue getrawmempool(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "getrawmempool ( verbose )\n" + "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n" + "\nArguments:\n" + "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" + "\nResult: (for verbose = false):\n" + "[ (json array of string)\n" + " \"transactionid\" (string) The transaction id\n" + " ,...\n" + "]\n" + "\nResult: (for verbose = true):\n" + "{ (json object)\n" + " \"transactionid\" : { (json object)\n" + " \"size\" : n, (numeric) transaction size in bytes\n" + " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n" + " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" + " \"height\" : n, (numeric) block height when transaction entered pool\n" + " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n" + " \"currentpriority\" : n, (numeric) transaction priority now\n" + " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" + " \"transactionid\", (string) parent transaction id\n" + " ... ]\n" + " }, ...\n" + "}\n" + "\nExamples\n" + + HelpExampleCli("getrawmempool", "true") + + HelpExampleRpc("getrawmempool", "true") + ); + + LOCK(cs_main); + + bool fVerbose = false; + if (params.size() > 0) + fVerbose = params[0].get_bool(); + + return mempoolToJSON(fVerbose); +} + UniValue getblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -757,6 +761,16 @@ UniValue getchaintips(const UniValue& params, bool fHelp) return res; } +UniValue mempoolInfoToJSON() +{ + UniValue ret(UniValue::VOBJ); + ret.push_back(Pair("size", (int64_t) mempool.size())); + ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); + ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); + + return ret; +} + UniValue getmempoolinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -774,12 +788,7 @@ UniValue getmempoolinfo(const UniValue& params, bool fHelp) + HelpExampleRpc("getmempoolinfo", "") ); - UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("size", (int64_t) mempool.size())); - ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); - ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); - - return ret; + return mempoolInfoToJSON(); } UniValue invalidateblock(const UniValue& params, bool fHelp) diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index b7d4ff58fc..620a46be15 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -138,8 +138,12 @@ UniValue generate(const UniValue& params, bool fHelp) boost::shared_ptr<CReserveScript> coinbaseScript; GetMainSignals().ScriptForMining(coinbaseScript); + // If the keypool is exhausted, no script is returned at all. Catch this. + if (!coinbaseScript) + throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); + //throw an error if no script was provided - if (!coinbaseScript->reserveScript.size()) + if (coinbaseScript->reserveScript.empty()) throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)"); { // Don't keep cs_main locked diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 4088f374f8..9362401b1e 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -607,7 +607,7 @@ void StartRPCThreads() LogPrintf("No rpcpassword set - using random cookie authentication\n"); if (!GenerateAuthCookie(&strRPCUserColonPass)) { uiInterface.ThreadSafeMessageBox( - _("Error: A fatal internal error occured, see debug.log for details"), // Same message as AbortNode + _("Error: A fatal internal error occurred, see debug.log for details"), // Same message as AbortNode "", CClientUIInterface::MSG_ERROR); StartShutdown(); return; @@ -671,7 +671,7 @@ void StartRPCThreads() vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::any(), defaultPort)); vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::any(), defaultPort)); // Prefer making the socket dual IPv6/IPv4 instead of binding - // to both addresses seperately. + // to both addresses separately. bBindAny = true; } diff --git a/src/scheduler.cpp b/src/scheduler.cpp index d5bb588b71..06115f5619 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -6,6 +6,7 @@ #include <assert.h> #include <boost/bind.hpp> +#include <boost/thread/reverse_lock.hpp> #include <utility> CScheduler::CScheduler() : nThreadsServicingQueue(0), stopRequested(false), stopWhenEmpty(false) @@ -65,11 +66,12 @@ void CScheduler::serviceQueue() Function f = taskQueue.begin()->second; taskQueue.erase(taskQueue.begin()); - // Unlock before calling f, so it can reschedule itself or another task - // without deadlocking: - lock.unlock(); - f(); - lock.lock(); + { + // Unlock before calling f, so it can reschedule itself or another task + // without deadlocking: + boost::reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock); + f(); + } } catch (...) { --nThreadsServicingQueue; throw; diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 0b78fdf5a8..bd5e54b33f 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1128,7 +1128,7 @@ bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const { - // There are two times of nLockTime: lock-by-blockheight + // There are two kinds of nLockTime: lock-by-blockheight // and lock-by-blocktime, distinguished by whether // nLockTime < LOCKTIME_THRESHOLD. // diff --git a/src/sync.h b/src/sync.h index 705647e4a5..68a9443084 100644 --- a/src/sync.h +++ b/src/sync.h @@ -16,7 +16,7 @@ //////////////////////////////////////////////// // // -// THE SIMPLE DEFINITON, EXCLUDING DEBUG CODE // +// THE SIMPLE DEFINITION, EXCLUDING DEBUG CODE // // // //////////////////////////////////////////////// diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index 20bdbd08a5..5cad5af7c3 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -128,7 +128,7 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000fe64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -["By-time locks, with argument just beyond tx nLockTime (but within numerical boundries)"], +["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 NOP2 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]], @@ -181,7 +181,7 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP2 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffff7f", "P2SH,CHECKLOCKTIMEVERIFY"], -["6 byte non-minimally-encoded arguments are invalid even in their contents are valid"], +["6 byte non-minimally-encoded arguments are invalid even if their contents are valid"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 NOP2 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index 24fff575c1..9744a3c848 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -197,7 +197,7 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -["By-time locks, with argument just beyond tx nLockTime (but within numerical boundries)"], +["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]], diff --git a/src/test/limitedmap_tests.cpp b/src/test/limitedmap_tests.cpp new file mode 100644 index 0000000000..faaddffad8 --- /dev/null +++ b/src/test/limitedmap_tests.cpp @@ -0,0 +1,101 @@ +// Copyright (c) 2012-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "limitedmap.h" + +#include "test/test_bitcoin.h" + +#include <boost/test/unit_test.hpp> + +BOOST_FIXTURE_TEST_SUITE(limitedmap_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(limitedmap_test) +{ + // create a limitedmap capped at 10 items + limitedmap<int, int> map(10); + + // check that the max size is 10 + BOOST_CHECK(map.max_size() == 10); + + // check that it's empty + BOOST_CHECK(map.size() == 0); + + // insert (-1, -1) + map.insert(std::pair<int, int>(-1, -1)); + + // make sure that the size is updated + BOOST_CHECK(map.size() == 1); + + // make sure that the new items is in the map + BOOST_CHECK(map.count(-1) == 1); + + // insert 10 new items + for (int i = 0; i < 10; i++) { + map.insert(std::pair<int, int>(i, i + 1)); + } + + // make sure that the map now contains 10 items... + BOOST_CHECK(map.size() == 10); + + // ...and that the first item has been discarded + BOOST_CHECK(map.count(-1) == 0); + + // iterate over the map, both with an index and an iterator + limitedmap<int, int>::const_iterator it = map.begin(); + for (int i = 0; i < 10; i++) { + // make sure the item is present + BOOST_CHECK(map.count(i) == 1); + + // use the iterator to check for the expected key adn value + BOOST_CHECK(it->first == i); + BOOST_CHECK(it->second == i + 1); + + // use find to check for the value + BOOST_CHECK(map.find(i)->second == i + 1); + + // update and recheck + map.update(it, i + 2); + BOOST_CHECK(map.find(i)->second == i + 2); + + it++; + } + + // check that we've exhausted the iterator + BOOST_CHECK(it == map.end()); + + // resize the map to 5 items + map.max_size(5); + + // check that the max size and size are now 5 + BOOST_CHECK(map.max_size() == 5); + BOOST_CHECK(map.size() == 5); + + // check that items less than 5 have been discarded + // and items greater than 5 are retained + for (int i = 0; i < 10; i++) { + if (i < 5) { + BOOST_CHECK(map.count(i) == 0); + } else { + BOOST_CHECK(map.count(i) == 1); + } + } + + // erase some items not in the map + for (int i = 100; i < 1000; i += 100) { + map.erase(i); + } + + // check that the size is unaffected + BOOST_CHECK(map.size() == 5); + + // erase the remaining elements + for (int i = 5; i < 10; i++) { + map.erase(i); + } + + // check that the map is now empty + BOOST_CHECK(map.empty()); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index bd16da7614..5d182f3d42 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -797,7 +797,7 @@ UniValue movecmd(const UniValue& params, bool fHelp) "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" "5. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n" "\nResult:\n" - "true|false (boolean) true if successfull.\n" + "true|false (boolean) true if successful.\n" "\nExamples:\n" "\nMove 0.01 " + CURRENCY_UNIT + " from the default account to the account named tabby\n" + HelpExampleCli("move", "\"\" \"tabby\" 0.01") + |