Skip to content
This repository has been archived by the owner on Jul 19, 2021. It is now read-only.

Commit

Permalink
[Wallet] Fix wallet flushing on client-related TXs
Browse files Browse the repository at this point in the history
  • Loading branch information
JSKitty committed Aug 8, 2019
1 parent 5a0ccf7 commit 5f8d994
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 19 deletions.
7 changes: 5 additions & 2 deletions src/db.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2019 The Oasis developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -218,10 +219,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;

Expand Down Expand Up @@ -298,7 +300,8 @@ void CDB::Close()
activeTxn = NULL;
pdb = NULL;

Flush();
if (fFlushOnClose)
Flush();

{
LOCK(bitdb.cs_db);
Expand Down
4 changes: 3 additions & 1 deletion src/db.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2019 The Oasis developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -101,8 +102,9 @@ class CDB
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:
Expand Down
4 changes: 3 additions & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1589,6 +1589,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();
std::map<uint256, CWalletTx>::iterator mi = pwalletMain->mapWallet.find(hash);
Expand All @@ -1602,7 +1604,7 @@ bool AppInit2(boost::thread_group& threadGroup)
copyTo->fFromMe = copyFrom->fFromMe;
copyTo->strFromAccount = copyFrom->strFromAccount;
copyTo->nOrderPos = copyFrom->nOrderPos;
copyTo->WriteToDisk();
copyTo->WriteToDisk(&walletdb);
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/test/accounting_tests.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2012-2014 The Bitcoin Core developers
// Copyright (c) 2019 The Oasis developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -46,7 +47,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;
Expand Down Expand Up @@ -88,7 +89,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade)
--tx.nLockTime; // Just to change the hash :)
*static_cast<CTransaction*>(&wtx) = CTransaction(tx);
}
pwalletMain->AddToWallet(wtx);
pwalletMain->AddToWallet(wtx, false, &walletdb);
vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]);
vpwtx[1]->nTimeReceived = (unsigned int)1333333336;

Expand All @@ -98,7 +99,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade)
--tx.nLockTime; // Just to change the hash :)
*static_cast<CTransaction*>(&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;
Expand Down
23 changes: 15 additions & 8 deletions src/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2014-2015 The Dash developers
// Copyright (c) 2015-2017 The PIVX developers
// Copyright (c) 2019 The Oasis developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -656,7 +657,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();

Expand All @@ -673,7 +674,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet)
bool fInsertedNew = ret.second;
if (fInsertedNew) {
wtx.nTimeReceived = GetAdjustedTime();
wtx.nOrderPos = IncOrderPosNext();
wtx.nOrderPos = IncOrderPosNext(pwalletdb);

wtx.nTimeSmart = wtx.nTimeReceived;
if (wtxIn.hashBlock != 0) {
Expand Down Expand Up @@ -739,7 +740,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:
Expand Down Expand Up @@ -772,10 +773,16 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl
if (fExisted && !fUpdate) return false;
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;
Expand Down Expand Up @@ -1121,9 +1128,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);
}

/**
Expand Down Expand Up @@ -2747,14 +2754,14 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, std:
// 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
if (!wtxNew.IsZerocoinSpend()) {
Expand Down
5 changes: 3 additions & 2 deletions src/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2014-2015 The Dash developers
// Copyright (c) 2015-2017 The PIVX developers
// Copyright (c) 2019 The Oasis developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -435,7 +436,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
TxItems OrderedTxItems(std::list<CAccountingEntry>& 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);
Expand Down Expand Up @@ -1294,7 +1295,7 @@ class CWalletTx : public CMerkleTx
return true;
}

bool WriteToDisk();
bool WriteToDisk(CWalletDB *pwalletdb);

int64_t GetTxTime() const;
int64_t GetComputedTxTime() const;
Expand Down
3 changes: 2 additions & 1 deletion src/walletdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2014-2015 The Dash developers
// Copyright (c) 2015-2017 The PIVX developers
// Copyright (c) 2019 The Oasis developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -460,7 +461,7 @@ bool ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, CW
if (wtx.nOrderPos == -1)
wss.fAnyUnordered = true;

pwallet->AddToWallet(wtx, true);
pwallet->AddToWallet(wtx, true, NULL);
} else if (strType == "acentry") {
string strAccount;
ssKey >> strAccount;
Expand Down
2 changes: 1 addition & 1 deletion src/walletdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class CKeyMetadata
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)
{
}

Expand Down

0 comments on commit 5f8d994

Please sign in to comment.