diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.cpp | 31 | ||||
-rw-r--r-- | src/main.h | 3 | ||||
-rw-r--r-- | src/rpcwallet.cpp | 3 | ||||
-rw-r--r-- | src/test/test_bitcoin.cpp | 7 | ||||
-rw-r--r-- | src/util.cpp | 22 | ||||
-rw-r--r-- | src/util.h | 1 |
6 files changed, 62 insertions, 5 deletions
diff --git a/src/main.cpp b/src/main.cpp index 8279924a3c..944345abb2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -818,7 +818,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, CTransaction &tx) } -bool CTxMemPool::remove(CTransaction &tx) +bool CTxMemPool::remove(const CTransaction &tx, bool fRecursive) { // Remove transaction from memory pool { @@ -826,6 +826,13 @@ bool CTxMemPool::remove(CTransaction &tx) uint256 hash = tx.GetHash(); if (mapTx.count(hash)) { + if (fRecursive) { + for (unsigned int i = 0; i < tx.vout.size(); i++) { + std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(hash, i)); + if (it != mapNextTx.end()) + remove(*it->second.ptx, true); + } + } BOOST_FOREACH(const CTxIn& txin, tx.vin) mapNextTx.erase(txin.prevout); mapTx.erase(hash); @@ -835,6 +842,21 @@ bool CTxMemPool::remove(CTransaction &tx) return true; } +bool CTxMemPool::removeConflicts(const CTransaction &tx) +{ + // Remove transactions which depend on inputs of tx, recursively + LOCK(cs); + BOOST_FOREACH(const CTxIn &txin, tx.vin) { + std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(txin.prevout); + if (it != mapNextTx.end()) { + const CTransaction &txConflict = *it->second.ptx; + if (txConflict != tx) + remove(txConflict, true); + } + } + return true; +} + void CTxMemPool::clear() { LOCK(cs); @@ -1757,8 +1779,10 @@ bool SetBestChain(CBlockIndex* pindexNew) tx.AcceptToMemoryPool(false); // Delete redundant memory transactions that are in the connected branch - BOOST_FOREACH(CTransaction& tx, vDelete) + BOOST_FOREACH(CTransaction& tx, vDelete) { mempool.remove(tx); + mempool.removeConflicts(tx); + } // Update best block in wallet (so we can detect restored wallets) if (!fIsInitialDownload) @@ -3730,6 +3754,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) // Priority order to process transactions list<COrphan> vOrphan; // list memory doesn't move map<uint256, vector<COrphan*> > mapDependers; + bool fPrintPriority = GetBoolArg("-printpriority"); // This vector will be sorted into a priority queue: vector<TxPriority> vecPriority; @@ -3876,7 +3901,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) nBlockSigOps += nTxSigOps; nFees += nTxFees; - if (fDebug && GetBoolArg("-printpriority")) + if (fPrintPriority) { printf("priority %.1f feeperkb %.1f txid %s\n", dPriority, dFeePerKb, tx.GetHash().ToString().c_str()); diff --git a/src/main.h b/src/main.h index a5f60fe945..4bd4782ccb 100644 --- a/src/main.h +++ b/src/main.h @@ -1831,7 +1831,8 @@ public: bool accept(CTransaction &tx, bool fCheckInputs, bool* pfMissingInputs); bool addUnchecked(const uint256& hash, CTransaction &tx); - bool remove(CTransaction &tx); + bool remove(const CTransaction &tx, bool fRecursive = false); + bool removeConflicts(const CTransaction &tx); void clear(); void queryHashes(std::vector<uint256>& vtxid); void pruneSpent(const uint256& hash, CCoins &coins); diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 5ebab755b7..d597e5e3f7 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1228,7 +1228,8 @@ Value backupwallet(const Array& params, bool fHelp) "Safely copies wallet.dat to destination, which can be a directory or a path with filename."); string strDest = params[0].get_str(); - BackupWallet(*pwalletMain, strDest); + if (!BackupWallet(*pwalletMain, strDest)) + throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!"); return Value::null; } diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index e4ba0259ba..b98816d53d 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -1,10 +1,12 @@ #define BOOST_TEST_MODULE Bitcoin Test Suite #include <boost/test/unit_test.hpp> +#include <boost/filesystem.hpp> #include "db.h" #include "txdb.h" #include "main.h" #include "wallet.h" +#include "util.h" CWallet* pwalletMain; CClientUIInterface uiInterface; @@ -14,11 +16,15 @@ extern void noui_connect(); struct TestingSetup { CCoinsViewDB *pcoinsdbview; + boost::filesystem::path pathTemp; TestingSetup() { fPrintToDebugger = true; // don't want to write to debug.log file noui_connect(); bitdb.MakeMock(); + pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); + boost::filesystem::create_directories(pathTemp); + mapArgs["-datadir"] = pathTemp.string(); pblocktree = new CBlockTreeDB(1 << 20, true); pcoinsdbview = new CCoinsViewDB(1 << 23, true); pcoinsTip = new CCoinsViewCache(*pcoinsdbview); @@ -36,6 +42,7 @@ struct TestingSetup { delete pcoinsdbview; delete pblocktree; bitdb.Flush(true); + boost::filesystem::remove_all(pathTemp); } }; diff --git a/src/util.cpp b/src/util.cpp index 2f36c66067..bd8ad8acd0 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1310,6 +1310,28 @@ boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate) } #endif +boost::filesystem::path GetTempPath() { +#if BOOST_FILESYSTEM_VERSION == 3 + return boost::filesystem::temp_directory_path(); +#else + // TODO: remove when we don't support filesystem v2 anymore + boost::filesystem::path path; +#ifdef WIN32 + char pszPath[MAX_PATH] = ""; + + if (GetTempPathA(MAX_PATH, pszPath)) + path = boost::filesystem::path(pszPath); +#else + path = boost::filesystem::path("/tmp"); +#endif + if (path.empty() || !boost::filesystem::is_directory(path)) { + printf("GetTempPath(): failed to find temp path\n"); + return boost::filesystem::path(""); + } + return path; +#endif +} + void runCommand(std::string strCommand) { int nErr = ::system(strCommand.c_str()); diff --git a/src/util.h b/src/util.h index b798f60aa7..ada0dd3790 100644 --- a/src/util.h +++ b/src/util.h @@ -207,6 +207,7 @@ void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map #ifdef WIN32 boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true); #endif +boost::filesystem::path GetTempPath(); void ShrinkDebugFile(); int GetRandInt(int nMax); uint64 GetRand(uint64 nMax); |