From 44bc988e7becb492a78ed92ea1052f4789012534 Mon Sep 17 00:00:00 2001 From: Cozz Lovan Date: Sun, 31 Aug 2014 05:55:27 +0200 Subject: [PATCH] [Wallet] Do not flush the wallet in AddToWalletIfInvolvingMe(..) --- src/db.cpp | 6 ++++-- src/db.h | 3 ++- src/init.cpp | 4 +++- src/test/accounting_tests.cpp | 6 +++--- src/wallet.cpp | 22 ++++++++++++++-------- src/wallet.h | 4 ++-- src/walletdb.cpp | 2 +- src/walletdb.h | 2 +- 8 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 12650e459..a9fd8e951 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -218,10 +218,11 @@ void CDBEnv::CheckpointLSN(const std::string& strFile) } -CDB::CDB(const std::string& strFilename, const char* pszMode) : pdb(NULL), activeTxn(NULL) +CDB::CDB(const std::string& strFilename, const char* pszMode, bool fFlushOnCloseIn) : pdb(NULL), activeTxn(NULL) { int ret; fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); + fFlushOnClose = fFlushOnCloseIn; if (strFilename.empty()) return; @@ -298,7 +299,8 @@ void CDB::Close() activeTxn = NULL; pdb = NULL; - Flush(); + if (fFlushOnClose) + Flush(); { LOCK(bitdb.cs_db); diff --git a/src/db.h b/src/db.h index d20239938..271ecfece 100644 --- a/src/db.h +++ b/src/db.h @@ -97,8 +97,9 @@ protected: std::string strFile; DbTxn* activeTxn; bool fReadOnly; + bool fFlushOnClose; - explicit CDB(const std::string& strFilename, const char* pszMode = "r+"); + explicit CDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnCloseIn=true); ~CDB() { Close(); } public: diff --git a/src/init.cpp b/src/init.cpp index 980c589b2..b943b8662 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1177,6 +1177,8 @@ bool AppInit2(boost::thread_group& threadGroup) // Restore wallet transaction metadata after -zapwallettxes=1 if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2") { + CWalletDB walletdb(strWalletFile); + BOOST_FOREACH(const CWalletTx& wtxOld, vWtx) { uint256 hash = wtxOld.GetHash(); @@ -1192,7 +1194,7 @@ bool AppInit2(boost::thread_group& threadGroup) copyTo->fFromMe = copyFrom->fFromMe; copyTo->strFromAccount = copyFrom->strFromAccount; copyTo->nOrderPos = copyFrom->nOrderPos; - copyTo->WriteToDisk(); + copyTo->WriteToDisk(&walletdb); } } } diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp index af2a9a214..c35f96495 100644 --- a/src/test/accounting_tests.cpp +++ b/src/test/accounting_tests.cpp @@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade) walletdb.WriteAccountingEntry(ae); wtx.mapValue["comment"] = "z"; - pwalletMain->AddToWallet(wtx); + pwalletMain->AddToWallet(wtx, false, &walletdb); vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]); vpwtx[0]->nTimeReceived = (unsigned int)1333333335; vpwtx[0]->nOrderPos = -1; @@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade) --tx.nLockTime; // Just to change the hash :) *static_cast(&wtx) = CTransaction(tx); } - pwalletMain->AddToWallet(wtx); + pwalletMain->AddToWallet(wtx, false, &walletdb); vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]); vpwtx[1]->nTimeReceived = (unsigned int)1333333336; @@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade) --tx.nLockTime; // Just to change the hash :) *static_cast(&wtx) = CTransaction(tx); } - pwalletMain->AddToWallet(wtx); + pwalletMain->AddToWallet(wtx, false, &walletdb); vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]); vpwtx[2]->nTimeReceived = (unsigned int)1333333329; vpwtx[2]->nOrderPos = -1; diff --git a/src/wallet.cpp b/src/wallet.cpp index b20b0007c..caf1f67f5 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -512,7 +512,7 @@ void CWallet::MarkDirty() } } -bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet) +bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb) { uint256 hash = wtxIn.GetHash(); @@ -533,7 +533,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet) if (fInsertedNew) { wtx.nTimeReceived = GetAdjustedTime(); - wtx.nOrderPos = IncOrderPosNext(); + wtx.nOrderPos = IncOrderPosNext(pwalletdb); wtx.nTimeSmart = wtx.nTimeReceived; if (wtxIn.hashBlock != 0) @@ -610,7 +610,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet) // Write to disk if (fInsertedNew || fUpdated) - if (!wtx.WriteToDisk()) + if (!wtx.WriteToDisk(pwalletdb)) return false; // Break debit/credit balance caches: @@ -644,10 +644,16 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl if (fExisted || IsMine(tx) || IsFromMe(tx)) { CWalletTx wtx(this,tx); + // Get merkle branch if transaction was found in a block if (pblock) wtx.SetMerkleBranch(*pblock); - return AddToWallet(wtx); + + // Do not flush the wallet here for performance reasons + // this is safe, as in case of a crash, we rescan the necessary blocks on startup through our SetBestChain-mechanism + CWalletDB walletdb(strWalletFile, "r+", false); + + return AddToWallet(wtx, false, &walletdb); } } return false; @@ -871,9 +877,9 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived, } -bool CWalletTx::WriteToDisk() +bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb) { - return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this); + return pwalletdb->WriteTx(GetHash(), *this); } // Scan the block chain (starting in pindexStart) for transactions @@ -1499,14 +1505,14 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) // This is only to keep the database open to defeat the auto-flush for the // duration of this scope. This is the only place where this optimization // maybe makes sense; please don't do it anywhere else. - CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL; + CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r+") : NULL; // Take key pair from key pool so it won't be used again reservekey.KeepKey(); // Add tx to wallet, because if it has change it's also ours, // otherwise just for transaction history. - AddToWallet(wtxNew); + AddToWallet(wtxNew, false, pwalletdb); // Notify that old coins are spent set setCoins; diff --git a/src/wallet.h b/src/wallet.h index f3fffb225..cd1a09035 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -246,7 +246,7 @@ public: TxItems OrderedTxItems(std::list& acentries, std::string strAccount = ""); void MarkDirty(); - bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet=false); + bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb); void SyncTransaction(const CTransaction& tx, const CBlock* pblock); bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate); void EraseFromWallet(const uint256 &hash); @@ -849,7 +849,7 @@ public: return true; } - bool WriteToDisk(); + bool WriteToDisk(CWalletDB *pwalletdb); int64_t GetTxTime() const; int GetRequestCount() const; diff --git a/src/walletdb.cpp b/src/walletdb.cpp index 3e5a664a5..8831ad157 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -390,7 +390,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, if (wtx.nOrderPos == -1) wss.fAnyUnordered = true; - pwallet->AddToWallet(wtx, true); + pwallet->AddToWallet(wtx, true, NULL); } else if (strType == "acentry") { diff --git a/src/walletdb.h b/src/walletdb.h index f3d6e61f8..590d63e33 100644 --- a/src/walletdb.h +++ b/src/walletdb.h @@ -76,7 +76,7 @@ public: class CWalletDB : public CDB { public: - CWalletDB(const std::string& strFilename, const char* pszMode = "r+") : CDB(strFilename, pszMode) + CWalletDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnClose = true) : CDB(strFilename, pszMode, fFlushOnClose) { }