diff -uNr a/bitcoin/build/Makefile b/bitcoin/build/Makefile --- a/bitcoin/build/Makefile 41b59259871a10241f2f34cd63d6b9500d5afe206c7669a308ec76cfaa1666a77c22d4d70c888816de2ee84fa47bd32447c583a338f1954e994b46f94568c566 +++ b/bitcoin/build/Makefile 4eb55ab5e6fa7659989267d40d6d076ba9074bffd5bb67c80a983811da5eefe7b9120c2c70694b5b456d8cf94034fa92d728e4b5e795d92bbe1f475bc1f440bd @@ -2,7 +2,8 @@ OURLIBS=$(CURDIR)/ourlibs CPPFLAGS = -DNOPCH -D_FORTIFY_SOURCE=2 -isystem ourlibs/include -CXXFLAGS = -g -O2 -pthread -Wall -Wextra +# TODO deal with at least the sign-compare and char-subscripts warnings (unused-parameter comes up a lot from the serialization templates) +CXXFLAGS = -g -O2 -pthread -Wall -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-char-subscripts LDFLAGS = -Lourlibs/lib LDLIBS = -lboost_system -lboost_filesystem -lboost_program_options -lboost_thread -ldb_cxx -lcrypto -lpthread diff -uNr a/bitcoin/manifest b/bitcoin/manifest --- a/bitcoin/manifest 56a9b8f0ce2813c45638e4ca9fedd14083bbb8f3ad43cc99fb283702fe0a6ffd84692f194f91192f7bec9781e8158f26ceeb57b1f0717c27d32a814c97d806a1 +++ b/bitcoin/manifest 5565b5a7778455f1064f17374339e51aa09e1cbea749b59d6dbd6a624ea0e22e4f149de2d6311e56a8a322b383fd6e6e4cefdef1504226979916d9a63603028d @@ -53,3 +53,4 @@ 833338 bitcoin_reorg_tracing jfw Add more useful log messages for tracking reorganize progress (as well as initial block connection). 833339 bitcoin_db_shutdown_checkpoint_calming jfw Remove various frantic, overdone database-related activities, mostly in the shutdown path where they were doing more harm than good. The goal is to make shutdown fast and somewhat easier to analyze. Checkpointing comes up because it's no longer necessarily done at shutdown. The conditions for periodic checkpoints are simplified; in particular, it's no longer done ~every time a db handle object goes out of scope. Given the use of DB_TXN_WRITE_NOSYNC this means update durability with respect to system crash is somewhat relaxed, but this seems fine given the nature of the application. The size limit on db transaction log files is raised 10x, restoring its earlier value. 835694 bitcoin_drop_bdb_locking jfw Turn off BDB's page-level locking subsystem, with some tweaks to firm up the already largely single-threaded pattern of database use. This allows removing the magic-number limits on locks, lockers and lock objects; the numbers were reported by past authority to be sufficient for any 1MB block, but have proven insufficient for large reorganizations, because BDB accumulates locks for the duration of a transaction. It also saves nearly 2GB of preallocations in the database environment (__db.00[1-5] files) to support the large limits. +835698 bitcoin_easy_warning_fixes jfw Quiet the vast majority of compiler warning spew so any actual trouble stands a chance of being spotted. Continue incremental conversion from CRITICAL_BLOCK to SCOPED_LOCK, as that and BOOST_FOREACH are the main sources of spurious -Wparentheses due to the macros' internal if-statements. Besides the more cosmetic changes, this cures a reckless stack buffer allocation (200k, when truncating the debug log) and a potential integer overflow (in string formatting code). Related string handling routines still need attention though. diff -uNr a/bitcoin/src/bitcoinrpc.cpp b/bitcoin/src/bitcoinrpc.cpp --- a/bitcoin/src/bitcoinrpc.cpp 24c9b92b9c80d0b2e8a9d9767e609cf73d26a7b8dd7811b8bf0b9bc6ccb3e127f4eb2cebd2c60397359ac3db1e1e21d170cbc48a8f91f1f777b7026dfcd21483 +++ b/bitcoin/src/bitcoinrpc.cpp 0ceb473bfc2901e66d569de7d3ea054697f43e39066621169400171c9a99adf81cffe34d414c2c97a640b0c5fe6120f4f615fd33fc1c591ca8f6f35c2c703dfc @@ -760,8 +760,10 @@ list > listSent; wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount); if (wtx.GetDepthInMainChain() >= nMinDepth) + { BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived) nBalance += r.second; + } BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listSent) nBalance -= r.second; nBalance -= allFee; @@ -1111,6 +1113,7 @@ // Received if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) + { BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived) { string account; @@ -1128,6 +1131,7 @@ ret.push_back(entry); } } + } } void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret) diff -uNr a/bitcoin/src/keystore.h b/bitcoin/src/keystore.h --- a/bitcoin/src/keystore.h 8bb123a590f5d5a536628e640847df536f8857afeba467f2503deeb728576ff0cfb2c450159d7e303d6292113dba473a16c364507d57290216edbc73b2a2396c +++ b/bitcoin/src/keystore.h ad495cb0177b522c6ede40868b903aa6d7746b524c64e064f41987e239ad7115ce22493d8d25af0fa83dda7e61715391e83df1707f6053600ea923c096f24f35 @@ -14,6 +14,9 @@ mutable CCriticalSection cs_KeyStore; public: + // A base class with virtual functions requires a virtual destructor if an instance is deleted through a pointer (per -Wdelete-non-virtual-dtor). + virtual ~CKeyStore() {} + // Add a key to the store. virtual bool AddKey(const CKey& key) =0; diff -uNr a/bitcoin/src/main.cpp b/bitcoin/src/main.cpp --- a/bitcoin/src/main.cpp e55bbe5755159c32d355c180a750d942058656a78f4eddbc3feb8ed3ba0fc8ccf35269ffd3d71f43e8fdae287ecfd300456e6a943caa674a67e237663ebf7b83 +++ b/bitcoin/src/main.cpp 45474609f59cfd70e2f3191c8bdabb57f23f5ef3f63926190016b1cd8777f2609f91df5caa70c7f9dc715def1373f6690d4024cad93a08d6b2b531d3fef48346 @@ -111,8 +111,8 @@ bool MempoolContainsTx(const uint256 &hash) { - CRITICAL_BLOCK(cs_mapTransactions) - return mapTransactions.count(hash) != 0; + SCOPED_LOCK(cs_mapTransactions); + return mapTransactions.count(hash) != 0; } ////////////////////////////////////////////////////////////////////////////// @@ -139,15 +139,6 @@ } } -// check whether the passed transaction is from us -bool static IsFromMe(CTransaction& tx) -{ - BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) - if (pwallet->IsFromMe(tx)) - return true; - return false; -} - // get the wallet transaction with the given hash (if it exists) bool static GetTransaction(const uint256& hashTx, CWalletTx& wtx) { @@ -992,14 +983,20 @@ // already refuses previously-known transaction id's entirely. // This rule applies to all blocks whose timestamp is after March 15, 2012, 0:00 UTC. if (pindex->nTime > 1331769600) + { BOOST_FOREACH(CTransaction& tx, vtx) { CTxIndex txindexOld; if (txdb.ReadTxIndex(tx.GetHash(), txindexOld)) + { BOOST_FOREACH(CDiskTxPos &pos, txindexOld.vSpent) + { if (pos.IsNull()) return false; + } + } } + } //// issue here: it doesn't know the version unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK) - 1 + GetSizeOfCompactSize(vtx.size()); @@ -1339,10 +1336,12 @@ // Relay inventory, but don't relay old inventory during initial block download if (hashBestChain == hash) - CRITICAL_BLOCK(cs_vNodes) - BOOST_FOREACH(CNode* pnode, vNodes) - if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 140700)) - pnode->PushInventory(CInv(MSG_BLOCK, hash)); + { + SCOPED_LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 140700)) + pnode->PushInventory(CInv(MSG_BLOCK, hash)); + } return true; } diff -uNr a/bitcoin/src/net.cpp b/bitcoin/src/net.cpp --- a/bitcoin/src/net.cpp 2e8488fc44ab3883e25516df67fcd1bf5c06e4c413950935850cd854a22e5cf5c1567e3b046aad6ab0afd421610371ee2e61585fa82f4877ca5a0b35796b155d +++ b/bitcoin/src/net.cpp d84be0a2d4aa69a293ded8e4cb97db0bc033fa36bd592ecb4f3fede7279bf7d4eb5070e34924509f2b6a6d7a30dea2b75db5bafae4d462e9fd41fafbcd26b658 @@ -609,10 +609,12 @@ if (hSocket != INVALID_SOCKET) addr = CAddress(sockaddr); - CRITICAL_BLOCK(cs_vNodes) + { + SCOPED_LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) - if (pnode->fInbound) - nInbound++; + if (pnode->fInbound) + nInbound++; + } if (hSocket == INVALID_SOCKET) { @@ -845,10 +847,12 @@ loop { int nOutbound = 0; - CRITICAL_BLOCK(cs_vNodes) + { + SCOPED_LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) if (!pnode->fInbound) nOutbound++; + } int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS; nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125)); if (nOutbound < nMaxOutboundConnections) @@ -869,9 +873,11 @@ // Only connect to one address per a.b.?.? range. // Do this here so we don't have to critsect vNodes inside mapAddresses critsect. set setConnected; - CRITICAL_BLOCK(cs_vNodes) + { + SCOPED_LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) setConnected.insert(pnode->addr.ip & 0x0000ffff); + } int64 nANow = GetAdjustedTime(); diff -uNr a/bitcoin/src/net.h b/bitcoin/src/net.h --- a/bitcoin/src/net.h 11a23408b4a7562a897755a96485957c61d11633a9ee5783fa950c0f6653ee69f1e7cc338963c1e694a994fa8f9f9dd07ad414512f3d607389a5770567141235 +++ b/bitcoin/src/net.h 535c36b1f7607ab818f9df2c020c583756542fe6dfa6a7fbd5aa0c5a4736106a0a8ea1e80a3dbc0dc2d666479793bf84c662a91b0c489db361baf6dc8c8cf727 @@ -352,9 +352,9 @@ inline void RelayInventory(const CInv& inv) { // Put on lists to offer to the other nodes - CRITICAL_BLOCK(cs_vNodes) - BOOST_FOREACH(CNode* pnode, vNodes) - pnode->PushInventory(inv); + SCOPED_LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + pnode->PushInventory(inv); } template diff -uNr a/bitcoin/src/util.cpp b/bitcoin/src/util.cpp --- a/bitcoin/src/util.cpp 7c70391a712c509983ac2a57e259ea8e834e54d81de1abc599dd9ef315373ce5c1dbcb242bcafd817ff2527f5a4ba98891145dcc1c47fbb4d6556061b2eb50d1 +++ b/bitcoin/src/util.cpp 04b7c3d690e97fdc8bae2b9fbf978f6f7ef4e4be95e98babd993754590b2c23bbbd800b53a5c404b26814ea2a20b0fa0bcd218272e2fa3974ad3eebd29d0e87a @@ -207,7 +207,7 @@ string strprintf(const std::string &format, ...) { - char buffer[50000]; + char buffer[512]; // arbitrary initial allocation, expanded on heap if needed char* p = buffer; int limit = sizeof(buffer); int ret; @@ -221,6 +221,8 @@ break; if (p != buffer) delete[] p; + if (limit > INT_MAX/2) + throw std::bad_alloc(); limit *= 2; p = new char[limit]; if (p == NULL) @@ -771,15 +773,15 @@ if (file && GetFilesize(file) > 10 * 1000000) { // Restart the file with some of the end - char pch[200000]; - fseek(file, -sizeof(pch), SEEK_END); - int nBytes = fread(pch, 1, sizeof(pch), file); + vector vch(200*1000); + fseek(file, -vch.size(), SEEK_END); + int nBytes = fread(vch.data(), 1, vch.size(), file); fclose(file); file = fopen(strFile.c_str(), "w"); if (file) { - fwrite(pch, 1, nBytes, file); + fwrite(vch.data(), 1, nBytes, file); fclose(file); } } diff -uNr a/bitcoin/src/wallet.cpp b/bitcoin/src/wallet.cpp --- a/bitcoin/src/wallet.cpp e185015ffd525641ab93cfc884b30b480ac5bba41e6e5596590fdc17063d0d749ebade8f3178ea1187120c17f25aca81eb8ffe0e303720826ef6bc031ff838f6 +++ b/bitcoin/src/wallet.cpp ba1f8959cc06b4d2921bb6d1e9c63be805a43a252fb9cfb4765be6e2844ab2633728e41660f88d6b60a3c7614251c55019fc636c8c9530bdef0fd7beba098f9d @@ -50,7 +50,8 @@ CCrypter crypter; CKeyingMaterial vMasterKey; - CRITICAL_BLOCK(cs_wallet) + { + SCOPED_LOCK(cs_wallet); BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys) { if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) @@ -60,6 +61,7 @@ if (CCryptoKeyStore::Unlock(vMasterKey)) return true; } + } return false; } @@ -554,8 +556,10 @@ vtxPrev.push_back(tx); if (nDepth < COPY_DEPTH) + { BOOST_FOREACH(const CTxIn& txin, tx.vin) vWorkQueue.push_back(txin.prevout.hash); + } } } } diff -uNr a/bitcoin/src/wallet.h b/bitcoin/src/wallet.h --- a/bitcoin/src/wallet.h 5b385f013f54c927ac9b33988a5d8429548b02c94385345780e79620776f546d3fe332b3f300f0eaa6a399936691f4fc8b16ad871f362de3386152ca3ef257c5 +++ b/bitcoin/src/wallet.h 6dd8b8e5f9e415543dfbb4c2ea3948a9f2338a02fdba9ed223051105ce9b58227b1e4990cea701d97acbd7cb85f64e043d851aa7158b79c9dcd77bd7205e0b3e @@ -508,8 +508,10 @@ return false; if (mapPrev.empty()) + { BOOST_FOREACH(const CMerkleTx& tx, vtxPrev) mapPrev[tx.GetHash()] = &tx; + } BOOST_FOREACH(const CTxIn& txin, ptx->vin) {