Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,9 @@ void PrepareShutdown()
privateSendClient.fPrivateSendRunning = false;
privateSendClient.ResetPool();
}
if (pwalletMain)
pwalletMain->Flush(false);
for (CWalletRef pwallet : vpwallets) {
pwallet->Flush(false);
}
#endif
MapPort(false);
UnregisterValidationInterface(peerLogic.get());
Expand Down Expand Up @@ -306,8 +307,9 @@ void PrepareShutdown()
evoDb = NULL;
}
#ifdef ENABLE_WALLET
if (pwalletMain)
pwalletMain->Flush(true);
for (CWalletRef pwallet : vpwallets) {
pwallet->Flush(true);
}
#endif

#if ENABLE_ZMQ
Expand Down Expand Up @@ -359,8 +361,10 @@ void Shutdown()
// Shutdown part 2: Stop TOR thread and delete wallet instance
StopTorControl();
#ifdef ENABLE_WALLET
delete pwalletMain;
pwalletMain = NULL;
for (CWalletRef pwallet : vpwallets) {
delete pwallet;
}
vpwallets.clear();
#endif
globalVerifyHandle.reset();
ECC_Stop();
Expand Down Expand Up @@ -834,8 +838,8 @@ void ThreadImport(std::vector<fs::path> vImportFiles)

#ifdef ENABLE_WALLET
// we can't do this before DIP3 is fully initialized
if (pwalletMain) {
pwalletMain->AutoLockMasternodeCollaterals();
for (CWalletRef pwallet : vpwallets) {
pwallet->AutoLockMasternodeCollaterals();
}
#endif

Expand Down Expand Up @@ -1998,11 +2002,11 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
nMaxRounds = std::numeric_limits<int>::max();
}

if (pwalletMain == nullptr) {
if (vpwallets.empty()) {
privateSendClient.fEnablePrivateSend = privateSendClient.fPrivateSendRunning = false;
} else {
privateSendClient.fEnablePrivateSend = gArgs.GetBoolArg("-enableprivatesend", !fLiteMode);
privateSendClient.fPrivateSendRunning = pwalletMain->IsLocked() ? false : gArgs.GetBoolArg("-privatesendautostart", DEFAULT_PRIVATESEND_AUTOSTART);
privateSendClient.fPrivateSendRunning = vpwallets[0]->IsLocked() ? false : gArgs.GetBoolArg("-privatesendautostart", DEFAULT_PRIVATESEND_AUTOSTART);
}
privateSendClient.fPrivateSendMultiSession = gArgs.GetBoolArg("-privatesendmultisession", DEFAULT_PRIVATESEND_MULTISESSION);
privateSendClient.nPrivateSendSessions = std::min(std::max((int)gArgs.GetArg("-privatesendsessions", DEFAULT_PRIVATESEND_SESSIONS), MIN_PRIVATESEND_SESSIONS), MAX_PRIVATESEND_SESSIONS);
Expand Down Expand Up @@ -2151,8 +2155,9 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
uiInterface.InitMessage(_("Done loading"));

#ifdef ENABLE_WALLET
if (pwalletMain)
pwalletMain->postInitProcess(scheduler);
for (CWalletRef pwallet : vpwallets) {
pwallet->postInitProcess(scheduler);
}
#endif

return true;
Expand Down
106 changes: 53 additions & 53 deletions src/privatesend/privatesend-client.cpp

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/qt/coincontroldialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column)
item->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
else {
coinControl->Select(outpt);
int nRounds = pwalletMain->GetRealOutpointPrivateSendRounds(outpt);
int nRounds = vpwallets[0]->GetRealOutpointPrivateSendRounds(outpt);
if (coinControl->fUsePrivateSend && nRounds < privateSendClient.nPrivateSendRounds) {
QMessageBox::warning(this, windowTitle(),
tr("Non-anonymized input selected. <b>PrivateSend will be disabled.</b><br><br>If you still want to use PrivateSend, please deselect all non-anonymized inputs first and then check the PrivateSend checkbox again."),
Expand Down Expand Up @@ -751,7 +751,7 @@ void CoinControlDialog::updateView()

// PrivateSend rounds
COutPoint outpoint = COutPoint(out.tx->tx->GetHash(), out.i);
int nRounds = pwalletMain->GetRealOutpointPrivateSendRounds(outpoint);
int nRounds = vpwallets[0]->GetRealOutpointPrivateSendRounds(outpoint);

if (nRounds >= 0 || LogAcceptCategory(BCLog::PRIVATESEND)) itemOutput->setText(COLUMN_PRIVATESEND_ROUNDS, QString::number(nRounds));
else itemOutput->setText(COLUMN_PRIVATESEND_ROUNDS, tr("n/a"));
Expand Down
5 changes: 3 additions & 2 deletions src/qt/dash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,9 +507,10 @@ void BitcoinApplication::initializeResult(bool success)
window->setClientModel(clientModel);

#ifdef ENABLE_WALLET
if(pwalletMain)
// TODO: Expose secondary wallets
if (!vpwallets.empty())
{
walletModel = new WalletModel(platformStyle, pwalletMain, optionsModel);
walletModel = new WalletModel(platformStyle, vpwallets[0], optionsModel);

window->addWallet(BitcoinGUI::DEFAULT_WALLET, walletModel);
window->setCurrentWallet(BitcoinGUI::DEFAULT_WALLET);
Expand Down
9 changes: 5 additions & 4 deletions src/qt/optionsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@
#include <QTimer>

#ifdef ENABLE_WALLET
extern CWallet* pwalletMain;
#endif // ENABLE_WALLET
typedef CWallet* CWalletRef;
extern std::vector<CWalletRef> vpwallets;
#endif //ENABLE_WALLET

OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
QDialog(parent),
Expand Down Expand Up @@ -272,8 +273,8 @@ void OptionsDialog::on_okButton_clicked()
mapper->submit();
#ifdef ENABLE_WALLET
privateSendClient.nCachedNumBlocks = std::numeric_limits<int>::max();
if(pwalletMain)
pwalletMain->MarkDirty();
if(!vpwallets.empty())
vpwallets[0]->MarkDirty();
#endif // ENABLE_WALLET
accept();
updateDefaultProxyNets();
Expand Down
20 changes: 10 additions & 10 deletions src/qt/overviewpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ void OverviewPage::updatePrivateSendProgress()
{
if(!masternodeSync.IsBlockchainSynced() || ShutdownRequested()) return;

if(!pwalletMain) return;
if(vpwallets.empty()) return;

QString strAmountAndRounds;
QString strPrivateSendAmount = BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, privateSendClient.nPrivateSendAmount * COIN, false, BitcoinUnits::separatorAlways);
Expand All @@ -360,7 +360,7 @@ void OverviewPage::updatePrivateSendProgress()
return;
}

CAmount nAnonymizableBalance = pwalletMain->GetAnonymizableBalance(false, false);
CAmount nAnonymizableBalance = vpwallets[0]->GetAnonymizableBalance(false, false);

CAmount nMaxToAnonymize = nAnonymizableBalance + currentAnonymizedBalance;

Expand Down Expand Up @@ -394,10 +394,10 @@ void OverviewPage::updatePrivateSendProgress()
CAmount nNormalizedAnonymizedBalance;
float nAverageAnonymizedRounds;

nDenominatedConfirmedBalance = pwalletMain->GetDenominatedBalance();
nDenominatedUnconfirmedBalance = pwalletMain->GetDenominatedBalance(true);
nNormalizedAnonymizedBalance = pwalletMain->GetNormalizedAnonymizedBalance();
nAverageAnonymizedRounds = pwalletMain->GetAverageAnonymizedRounds();
nDenominatedConfirmedBalance = vpwallets[0]->GetDenominatedBalance();
nDenominatedUnconfirmedBalance = vpwallets[0]->GetDenominatedBalance(true);
nNormalizedAnonymizedBalance = vpwallets[0]->GetNormalizedAnonymizedBalance();
nAverageAnonymizedRounds = vpwallets[0]->GetAverageAnonymizedRounds();

// calculate parts of the progress, each of them shouldn't be higher than 1
// progress of denominating
Expand Down Expand Up @@ -473,8 +473,8 @@ void OverviewPage::privateSendStatus()
if(((nBestHeight - privateSendClient.nCachedNumBlocks) / (GetTimeMillis() - nLastDSProgressBlockTime + 1) > 1)) return;
nLastDSProgressBlockTime = GetTimeMillis();

QString strKeysLeftText(tr("keys left: %1").arg(pwalletMain->nKeysLeftSinceAutoBackup));
if(pwalletMain->nKeysLeftSinceAutoBackup < PRIVATESEND_KEYS_THRESHOLD_WARNING) {
QString strKeysLeftText(tr("keys left: %1").arg(vpwallets[0]->nKeysLeftSinceAutoBackup));
if(vpwallets[0]->nKeysLeftSinceAutoBackup < PRIVATESEND_KEYS_THRESHOLD_WARNING) {
strKeysLeftText = "<span style='color:red;'>" + strKeysLeftText + "</span>";
}
ui->labelPrivateSendEnabled->setToolTip(strKeysLeftText);
Expand All @@ -498,7 +498,7 @@ void OverviewPage::privateSendStatus()

// Warn user that wallet is running out of keys
// NOTE: we do NOT warn user and do NOT create autobackups if mixing is not running
if (nWalletBackups > 0 && pwalletMain->nKeysLeftSinceAutoBackup < PRIVATESEND_KEYS_THRESHOLD_WARNING) {
if (nWalletBackups > 0 && vpwallets[0]->nKeysLeftSinceAutoBackup < PRIVATESEND_KEYS_THRESHOLD_WARNING) {
QSettings settings;
if(settings.value("fLowKeysWarning").toBool()) {
QString strWarn = tr("Very low number of keys left since last automatic backup!") + "<br><br>" +
Expand All @@ -515,7 +515,7 @@ void OverviewPage::privateSendStatus()

std::string strBackupWarning;
std::string strBackupError;
if(!AutoBackupWallet(pwalletMain, "", strBackupWarning, strBackupError)) {
if(!AutoBackupWallet(vpwallets[0], "", strBackupWarning, strBackupError)) {
if (!strBackupWarning.empty()) {
// It's still more or less safe to continue but warn user anyway
LogPrintf("OverviewPage::privateSendStatus -- WARNING! Something went wrong on automatic backup: %s\n", strBackupWarning);
Expand Down
1 change: 1 addition & 0 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ void ArgsManager::ForceSetArg(const std::string& strArg, const std::string& strV
{
LOCK(cs_args);
mapArgs[strArg] = strValue;
mapMultiArgs[strArg].clear();
mapMultiArgs[strArg].push_back(strValue);
}

Expand Down
22 changes: 14 additions & 8 deletions src/wallet/db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ void CDBEnv::MakeMock()
fMockDb = true;
}

CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, bool (*recoverFunc)(const std::string& strFile))
CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, recoverFunc_type recoverFunc, std::string& out_backup_filename)
{
LOCK(cs_db);
assert(mapFileUseCount.count(strFile) == 0);
Expand All @@ -155,21 +155,21 @@ CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, bool (*recoverFu
return RECOVER_FAIL;

// Try to recover:
bool fRecovered = (*recoverFunc)(strFile);
bool fRecovered = (*recoverFunc)(strFile, out_backup_filename);
return (fRecovered ? RECOVER_OK : RECOVER_FAIL);
}

bool CDB::Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue))
bool CDB::Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& newFilename)
{
// Recovery procedure:
// move wallet file to wallet.timestamp.bak
// move wallet file to walletfilename.timestamp.bak
// Call Salvage with fAggressive=true to
// get as much data as possible.
// Rewrite salvaged data to fresh wallet file
// Set -rescan so any missing transactions will be
// found.
int64_t now = GetTime();
std::string newFilename = strprintf("wallet.%d.bak", now);
newFilename = strprintf("%s.%d.bak", filename, now);

int result = bitdb.dbenv->dbrename(NULL, filename.c_str(), NULL,
newFilename.c_str(), DB_AUTO_COMMIT);
Expand Down Expand Up @@ -259,18 +259,19 @@ bool CDB::VerifyEnvironment(const std::string& walletFile, const fs::path& dataD
return true;
}

bool CDB::VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr, bool (*recoverFunc)(const std::string& strFile))
bool CDB::VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr, CDBEnv::recoverFunc_type recoverFunc)
{
if (fs::exists(dataDir / walletFile))
{
CDBEnv::VerifyResult r = bitdb.Verify(walletFile, recoverFunc);
std::string backup_filename;
CDBEnv::VerifyResult r = bitdb.Verify(walletFile, recoverFunc, backup_filename);
if (r == CDBEnv::RECOVER_OK)
{
warningStr = strprintf(_("Warning: Wallet file corrupt, data salvaged!"
" Original %s saved as %s in %s; if"
" your balance or transactions are incorrect you should"
" restore from a backup."),
walletFile, "wallet.{timestamp}.bak", dataDir);
walletFile, backup_filename, dataDir);
}
if (r == CDBEnv::RECOVER_FAIL)
{
Expand Down Expand Up @@ -432,6 +433,11 @@ void CDB::Flush()
env->dbenv->txn_checkpoint(nMinutes ? gArgs.GetArg("-dblogsize", DEFAULT_WALLET_DBLOGSIZE) * 1024 : 0, nMinutes, 0);
}

void CWalletDBWrapper::IncrementUpdateCounter()
{
++nUpdateCounter;
}

void CDB::Close()
{
if (!pdb)
Expand Down
20 changes: 14 additions & 6 deletions src/wallet/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ class CDBEnv
enum VerifyResult { VERIFY_OK,
RECOVER_OK,
RECOVER_FAIL };
VerifyResult Verify(const std::string& strFile, bool (*recoverFunc)(const std::string& strFile));
typedef bool (*recoverFunc_type)(const std::string& strFile, std::string& out_backup_filename);
VerifyResult Verify(const std::string& strFile, recoverFunc_type recoverFunc, std::string& out_backup_filename);
/**
* Salvage data from a file that Verify says is bad.
* fAggressive sets the DB_AGGRESSIVE flag (see berkeley DB->verify() method documentation).
Expand Down Expand Up @@ -93,13 +94,13 @@ class CWalletDBWrapper
friend class CDB;
public:
/** Create dummy DB handle */
CWalletDBWrapper(): env(nullptr)
CWalletDBWrapper() : nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0), env(nullptr)
{
}

/** Create DB handle to real database */
CWalletDBWrapper(CDBEnv *env_in, const std::string &strFile_in):
env(env_in), strFile(strFile_in)
CWalletDBWrapper(CDBEnv *env_in, const std::string &strFile_in) :
nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0), env(env_in), strFile(strFile_in)
{
}

Expand All @@ -119,6 +120,13 @@ class CWalletDBWrapper
*/
void Flush(bool shutdown);

void IncrementUpdateCounter();

std::atomic<unsigned int> nUpdateCounter;
unsigned int nLastSeen;
unsigned int nLastFlushed;
int64_t nLastWalletUpdate;

private:
/** BerkeleyDB specific */
CDBEnv *env;
Expand Down Expand Up @@ -149,15 +157,15 @@ class CDB

void Flush();
void Close();
static bool Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue));
static bool Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& out_backup_filename);

/* flush the wallet passively (TRY_LOCK)
ideal to be called periodically */
static bool PeriodicFlush(CWalletDBWrapper& dbw);
/* verifies the database environment */
static bool VerifyEnvironment(const std::string& walletFile, const fs::path& dataDir, std::string& errorStr);
/* verifies the database file */
static bool VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr, bool (*recoverFunc)(const std::string& strFile));
static bool VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr, CDBEnv::recoverFunc_type recoverFunc);

private:
CDB(const CDB&);
Expand Down
3 changes: 2 additions & 1 deletion src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@

CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest& request)
{
return pwalletMain;
// TODO: Some way to access secondary wallets
return vpwallets.empty() ? nullptr : vpwallets[0];
}

std::string HelpRequiringPassphrase(CWallet * const pwallet)
Expand Down
2 changes: 2 additions & 0 deletions src/wallet/test/wallet_test_fixture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "wallet/db.h"
#include "wallet/wallet.h"

CWallet *pwalletMain;

WalletTestingSetup::WalletTestingSetup(const std::string& chainName):
TestingSetup(chainName)
{
Expand Down
Loading