aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/init.cpp61
-rw-r--r--src/wallet/rpcdump.cpp44
-rw-r--r--src/wallet/rpcwallet.cpp20
-rw-r--r--src/wallet/test/wallet_tests.cpp25
-rw-r--r--src/wallet/wallet.cpp49
-rw-r--r--src/wallet/wallet.h27
-rw-r--r--src/wallet/walletdb.cpp11
7 files changed, 156 insertions, 81 deletions
diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp
index b6f4a0e1e1..5091477dfd 100644
--- a/src/wallet/init.cpp
+++ b/src/wallet/init.cpp
@@ -18,39 +18,38 @@ class WalletInit : public WalletInitInterface {
public:
//! Return the wallets help message.
- std::string GetHelpString(bool showDebug) override;
+ std::string GetHelpString(bool showDebug) const override;
//! Wallets parameter interaction
- bool ParameterInteraction() override;
+ bool ParameterInteraction() const override;
//! Register wallet RPCs.
- void RegisterRPC(CRPCTable &tableRPC) override;
+ void RegisterRPC(CRPCTable &tableRPC) const override;
//! Responsible for reading and validating the -wallet arguments and verifying the wallet database.
// This function will perform salvage on the wallet if requested, as long as only one wallet is
// being loaded (WalletParameterInteraction forbids -salvagewallet, -zapwallettxes or -upgradewallet with multiwallet).
- bool Verify() override;
+ bool Verify() const override;
//! Load wallet databases.
- bool Open() override;
+ bool Open() const override;
//! Complete startup of wallets.
- void Start(CScheduler& scheduler) override;
+ void Start(CScheduler& scheduler) const override;
//! Flush all wallets in preparation for shutdown.
- void Flush() override;
+ void Flush() const override;
//! Stop all wallets. Wallets will be flushed first.
- void Stop() override;
+ void Stop() const override;
//! Close all wallets.
- void Close() override;
+ void Close() const override;
};
-static WalletInit g_wallet_init;
-WalletInitInterface* const g_wallet_init_interface = &g_wallet_init;
+const WalletInitInterface& g_wallet_init_interface = WalletInit();
-std::string WalletInit::GetHelpString(bool showDebug)
+std::string WalletInit::GetHelpString(bool showDebug) const
{
std::string strUsage = HelpMessageGroup(_("Wallet options:"));
strUsage += HelpMessageOpt("-addresstype", strprintf("What type of addresses to use (\"legacy\", \"p2sh-segwit\", or \"bech32\", default: \"%s\")", FormatOutputType(DEFAULT_ADDRESS_TYPE)));
@@ -92,7 +91,7 @@ std::string WalletInit::GetHelpString(bool showDebug)
return strUsage;
}
-bool WalletInit::ParameterInteraction()
+bool WalletInit::ParameterInteraction() const
{
if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
for (const std::string& wallet : gArgs.GetArgs("-wallet")) {
@@ -119,19 +118,19 @@ bool WalletInit::ParameterInteraction()
}
}
- int zapwallettxes = gArgs.GetArg("-zapwallettxes", 0);
+ bool zapwallettxes = gArgs.GetBoolArg("-zapwallettxes", false);
// -zapwallettxes implies dropping the mempool on startup
- if (zapwallettxes != 0 && gArgs.SoftSetBoolArg("-persistmempool", false)) {
- LogPrintf("%s: parameter interaction: -zapwallettxes=%s -> setting -persistmempool=0\n", __func__, zapwallettxes);
+ if (zapwallettxes && gArgs.SoftSetBoolArg("-persistmempool", false)) {
+ LogPrintf("%s: parameter interaction: -zapwallettxes enabled -> setting -persistmempool=0\n", __func__);
}
// -zapwallettxes implies a rescan
- if (zapwallettxes != 0) {
+ if (zapwallettxes) {
if (is_multiwallet) {
return InitError(strprintf("%s is only allowed with a single wallet file", "-zapwallettxes"));
}
if (gArgs.SoftSetBoolArg("-rescan", true)) {
- LogPrintf("%s: parameter interaction: -zapwallettxes=%s -> setting -rescan=1\n", __func__, zapwallettxes);
+ LogPrintf("%s: parameter interaction: -zapwallettxes enabled -> setting -rescan=1\n", __func__);
}
}
@@ -220,7 +219,7 @@ bool WalletInit::ParameterInteraction()
return true;
}
-void WalletInit::RegisterRPC(CRPCTable &t)
+void WalletInit::RegisterRPC(CRPCTable &t) const
{
if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
return;
@@ -229,7 +228,7 @@ void WalletInit::RegisterRPC(CRPCTable &t)
RegisterWalletRPCCommands(t);
}
-bool WalletInit::Verify()
+bool WalletInit::Verify() const
{
if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
return true;
@@ -304,7 +303,7 @@ bool WalletInit::Verify()
return true;
}
-bool WalletInit::Open()
+bool WalletInit::Open() const
{
if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
LogPrintf("Wallet disabled!\n");
@@ -316,37 +315,37 @@ bool WalletInit::Open()
if (!pwallet) {
return false;
}
- vpwallets.push_back(pwallet);
+ AddWallet(pwallet);
}
return true;
}
-void WalletInit::Start(CScheduler& scheduler)
+void WalletInit::Start(CScheduler& scheduler) const
{
- for (CWalletRef pwallet : vpwallets) {
+ for (CWallet* pwallet : GetWallets()) {
pwallet->postInitProcess(scheduler);
}
}
-void WalletInit::Flush()
+void WalletInit::Flush() const
{
- for (CWalletRef pwallet : vpwallets) {
+ for (CWallet* pwallet : GetWallets()) {
pwallet->Flush(false);
}
}
-void WalletInit::Stop()
+void WalletInit::Stop() const
{
- for (CWalletRef pwallet : vpwallets) {
+ for (CWallet* pwallet : GetWallets()) {
pwallet->Flush(true);
}
}
-void WalletInit::Close()
+void WalletInit::Close() const
{
- for (CWalletRef pwallet : vpwallets) {
+ for (CWallet* pwallet : GetWallets()) {
+ RemoveWallet(pwallet);
delete pwallet;
}
- vpwallets.clear();
}
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index a3594aa692..b8533839a0 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -172,7 +172,13 @@ UniValue importprivkey(const JSONRPCRequest& request)
}
}
if (fRescan) {
- pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ int64_t scanned_time = pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ if (pwallet->IsAbortingRescan()) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
+ }
+ if (scanned_time > TIMESTAMP_MIN) {
+ throw JSONRPCError(RPC_WALLET_ERROR, "Rescan was unable to fully rescan the blockchain. Some transactions may be missing.");
+ }
}
return NullUniValue;
@@ -310,7 +316,13 @@ UniValue importaddress(const JSONRPCRequest& request)
}
if (fRescan)
{
- pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ int64_t scanned_time = pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ if (pwallet->IsAbortingRescan()) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
+ }
+ if (scanned_time > TIMESTAMP_MIN) {
+ throw JSONRPCError(RPC_WALLET_ERROR, "Rescan was unable to fully rescan the blockchain. Some transactions may be missing.");
+ }
pwallet->ReacceptWalletTransactions();
}
@@ -479,7 +491,13 @@ UniValue importpubkey(const JSONRPCRequest& request)
}
if (fRescan)
{
- pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ int64_t scanned_time = pwallet->RescanFromTime(TIMESTAMP_MIN, reserver, true /* update */);
+ if (pwallet->IsAbortingRescan()) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
+ }
+ if (scanned_time > TIMESTAMP_MIN) {
+ throw JSONRPCError(RPC_WALLET_ERROR, "Rescan was unable to fully rescan the blockchain. Some transactions may be missing.");
+ }
pwallet->ReacceptWalletTransactions();
}
@@ -534,9 +552,11 @@ UniValue importwallet(const JSONRPCRequest& request)
int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg());
file.seekg(0, file.beg);
- pwallet->ShowProgress(_("Importing..."), 0); // show progress dialog in GUI
+ // Use uiInterface.ShowProgress instead of pwallet.ShowProgress because pwallet.ShowProgress has a cancel button tied to AbortRescan which
+ // we don't want for this progress bar shoing the import progress. uiInterface.ShowProgress does not have a cancel button.
+ uiInterface.ShowProgress(_("Importing..."), 0, false); // show progress dialog in GUI
while (file.good()) {
- pwallet->ShowProgress("", std::max(1, std::min(99, (int)(((double)file.tellg() / (double)nFilesize) * 100))));
+ uiInterface.ShowProgress("", std::max(1, std::min(99, (int)(((double)file.tellg() / (double)nFilesize) * 100))), false);
std::string line;
std::getline(file, line);
if (line.empty() || line[0] == '#')
@@ -599,10 +619,17 @@ UniValue importwallet(const JSONRPCRequest& request)
}
}
file.close();
- pwallet->ShowProgress("", 100); // hide progress dialog in GUI
+ uiInterface.ShowProgress("", 100, false); // hide progress dialog in GUI
pwallet->UpdateTimeFirstKey(nTimeBegin);
}
- pwallet->RescanFromTime(nTimeBegin, reserver, false /* update */);
+ uiInterface.ShowProgress("", 100, false); // hide progress dialog in GUI
+ int64_t scanned_time = pwallet->RescanFromTime(nTimeBegin, reserver, false /* update */);
+ if (pwallet->IsAbortingRescan()) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
+ }
+ if (scanned_time > nTimeBegin) {
+ throw JSONRPCError(RPC_WALLET_ERROR, "Rescan was unable to fully rescan the blockchain. Some transactions may be missing.");
+ }
pwallet->MarkDirty();
if (!fGood)
@@ -1212,6 +1239,9 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
int64_t scannedTime = pwallet->RescanFromTime(nLowestTimestamp, reserver, true /* update */);
pwallet->ReacceptWalletTransactions();
+ if (pwallet->IsAbortingRescan()) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
+ }
if (scannedTime > nLowestTimestamp) {
std::vector<UniValue> results = response.getValues();
response.clear();
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index c6b1034e45..5bc8788c7c 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -46,14 +46,13 @@ CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest& request)
if (request.URI.substr(0, WALLET_ENDPOINT_BASE.size()) == WALLET_ENDPOINT_BASE) {
// wallet endpoint was used
std::string requestedWallet = urlDecode(request.URI.substr(WALLET_ENDPOINT_BASE.size()));
- for (CWalletRef pwallet : ::vpwallets) {
- if (pwallet->GetName() == requestedWallet) {
- return pwallet;
- }
- }
- throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Requested wallet does not exist or is not loaded");
+ CWallet* pwallet = GetWallet(requestedWallet);
+ if (!pwallet) throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Requested wallet does not exist or is not loaded");
+ return pwallet;
}
- return ::vpwallets.size() == 1 || (request.fHelp && ::vpwallets.size() > 0) ? ::vpwallets[0] : nullptr;
+
+ std::vector<CWallet*> wallets = GetWallets();
+ return wallets.size() == 1 || (request.fHelp && wallets.size() > 0) ? wallets[0] : nullptr;
}
std::string HelpRequiringPassphrase(CWallet * const pwallet)
@@ -67,7 +66,7 @@ bool EnsureWalletIsAvailable(CWallet * const pwallet, bool avoidException)
{
if (pwallet) return true;
if (avoidException) return false;
- if (::vpwallets.empty()) {
+ if (!HasWallets()) {
// Note: It isn't currently possible to trigger this error because
// wallet RPC methods aren't registered unless a wallet is loaded. But
// this error is being kept as a precaution, because it's possible in
@@ -1670,7 +1669,7 @@ UniValue listreceivedbyaddress(const JSONRPCRequest& request)
" \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n"
" \"label\" : \"label\", (string) The label of the receiving address. The default label is \"\".\n"
" \"txids\": [\n"
- " n, (numeric) The ids of transactions received with the address \n"
+ " \"txid\", (string) The ids of transactions received with the address \n"
" ...\n"
" ]\n"
" }\n"
@@ -3020,8 +3019,7 @@ UniValue listwallets(const JSONRPCRequest& request)
UniValue obj(UniValue::VARR);
- for (CWalletRef pwallet : vpwallets) {
-
+ for (CWallet* pwallet : GetWallets()) {
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
return NullUniValue;
}
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index 14c5ad7214..99c963a348 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -74,7 +74,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup)
// after.
{
CWallet wallet("dummy", WalletDatabase::CreateDummy());
- vpwallets.insert(vpwallets.begin(), &wallet);
+ AddWallet(&wallet);
UniValue keys;
keys.setArray();
UniValue key;
@@ -105,7 +105,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup)
"downloading and rescanning the relevant blocks (see -reindex and -rescan "
"options).\"}},{\"success\":true}]",
0, oldTip->GetBlockTimeMax(), TIMESTAMP_WINDOW));
- vpwallets.erase(vpwallets.begin());
+ RemoveWallet(&wallet);
}
}
@@ -119,14 +119,14 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
// will pick up both blocks, not just the first.
const int64_t BLOCK_TIME = chainActive.Tip()->GetBlockTimeMax() + 5;
SetMockTime(BLOCK_TIME);
- coinbaseTxns.emplace_back(*CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
- coinbaseTxns.emplace_back(*CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
+ m_coinbase_txns.emplace_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
+ m_coinbase_txns.emplace_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
// Set key birthday to block time increased by the timestamp window, so
// rescan will start at the block time.
const int64_t KEY_TIME = BLOCK_TIME + TIMESTAMP_WINDOW;
SetMockTime(KEY_TIME);
- coinbaseTxns.emplace_back(*CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
+ m_coinbase_txns.emplace_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
LOCK(cs_main);
@@ -140,8 +140,9 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
JSONRPCRequest request;
request.params.setArray();
request.params.push_back((pathTemp / "wallet.backup").string());
- vpwallets.insert(vpwallets.begin(), &wallet);
+ AddWallet(&wallet);
::dumpwallet(request);
+ RemoveWallet(&wallet);
}
// Call importwallet RPC and verify all blocks with timestamps >= BLOCK_TIME
@@ -152,21 +153,21 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
JSONRPCRequest request;
request.params.setArray();
request.params.push_back((pathTemp / "wallet.backup").string());
- vpwallets[0] = &wallet;
+ AddWallet(&wallet);
::importwallet(request);
+ RemoveWallet(&wallet);
LOCK(wallet.cs_wallet);
BOOST_CHECK_EQUAL(wallet.mapWallet.size(), 3U);
- BOOST_CHECK_EQUAL(coinbaseTxns.size(), 103U);
- for (size_t i = 0; i < coinbaseTxns.size(); ++i) {
- bool found = wallet.GetWalletTx(coinbaseTxns[i].GetHash());
+ BOOST_CHECK_EQUAL(m_coinbase_txns.size(), 103U);
+ for (size_t i = 0; i < m_coinbase_txns.size(); ++i) {
+ bool found = wallet.GetWalletTx(m_coinbase_txns[i]->GetHash());
bool expected = i >= 100;
BOOST_CHECK_EQUAL(found, expected);
}
}
SetMockTime(0);
- vpwallets.erase(vpwallets.begin());
}
// Check that GetImmatureCredit() returns a newly calculated value instead of
@@ -178,7 +179,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup)
{
CWallet wallet("dummy", WalletDatabase::CreateDummy());
- CWalletTx wtx(&wallet, MakeTransactionRef(coinbaseTxns.back()));
+ CWalletTx wtx(&wallet, m_coinbase_txns.back());
LOCK2(cs_main, wallet.cs_wallet);
wtx.hashBlock = chainActive.Tip()->GetBlockHash();
wtx.nIndex = 0;
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 673d91c613..8c392434fc 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -28,12 +28,50 @@
#include <utilmoneystr.h>
#include <wallet/fees.h>
+#include <algorithm>
#include <assert.h>
#include <future>
#include <boost/algorithm/string/replace.hpp>
-std::vector<CWalletRef> vpwallets;
+static std::vector<CWallet*> vpwallets;
+
+bool AddWallet(CWallet* wallet)
+{
+ assert(wallet);
+ std::vector<CWallet*>::const_iterator i = std::find(vpwallets.begin(), vpwallets.end(), wallet);
+ if (i != vpwallets.end()) return false;
+ vpwallets.push_back(wallet);
+ return true;
+}
+
+bool RemoveWallet(CWallet* wallet)
+{
+ assert(wallet);
+ std::vector<CWallet*>::iterator i = std::find(vpwallets.begin(), vpwallets.end(), wallet);
+ if (i == vpwallets.end()) return false;
+ vpwallets.erase(i);
+ return true;
+}
+
+bool HasWallets()
+{
+ return !vpwallets.empty();
+}
+
+std::vector<CWallet*> GetWallets()
+{
+ return vpwallets;
+}
+
+CWallet* GetWallet(const std::string& name)
+{
+ for (CWallet* wallet : vpwallets) {
+ if (wallet->GetName() == name) return wallet;
+ }
+ return nullptr;
+}
+
/** Transaction fee set by the user */
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
@@ -1535,7 +1573,7 @@ bool CWallet::DummySignInput(CTxIn &tx_in, const CTxOut &txout) const
const CScript& scriptPubKey = txout.scriptPubKey;
SignatureData sigdata;
- if (!ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata))
+ if (!ProduceSignature(*this, DUMMY_SIGNATURE_CREATOR, scriptPubKey, sigdata))
{
return false;
} else {
@@ -1714,6 +1752,9 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock
CBlockIndex* pindex = pindexStart;
CBlockIndex* ret = nullptr;
+
+ if (pindex) LogPrintf("Rescan started from block %d...\n", pindex->nHeight);
+
{
fAbortRescan = false;
ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
@@ -2579,7 +2620,7 @@ bool CWallet::SignTransaction(CMutableTransaction &tx)
const CScript& scriptPubKey = mi->second.tx->vout[input.prevout.n].scriptPubKey;
const CAmount& amount = mi->second.tx->vout[input.prevout.n].nValue;
SignatureData sigdata;
- if (!ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) {
+ if (!ProduceSignature(*this, TransactionSignatureCreator(&txNewConst, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) {
return false;
}
UpdateTransaction(tx, nIn, sigdata);
@@ -3008,7 +3049,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
const CScript& scriptPubKey = coin.txout.scriptPubKey;
SignatureData sigdata;
- if (!ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.txout.nValue, SIGHASH_ALL), scriptPubKey, sigdata))
+ if (!ProduceSignature(*this, TransactionSignatureCreator(&txNewConst, nIn, coin.txout.nValue, SIGHASH_ALL), scriptPubKey, sigdata))
{
strFailReason = _("Signing transaction failed");
return false;
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index b85f374a06..dd165de825 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -32,8 +32,11 @@
#include <utility>
#include <vector>
-typedef CWallet* CWalletRef;
-extern std::vector<CWalletRef> vpwallets;
+bool AddWallet(CWallet* wallet);
+bool RemoveWallet(CWallet* wallet);
+bool HasWallets();
+std::vector<CWallet*> GetWallets();
+CWallet* GetWallet(const std::string& name);
/**
* Settings
@@ -268,7 +271,7 @@ public:
//Get the marginal bytes of spending the specified output
int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* pwallet);
-/**
+/**
* A transaction with a bunch of additional info that only the owner cares about.
* It includes any unrecorded transactions needed to link it back to the block chain.
*/
@@ -653,7 +656,7 @@ struct CoinEligibilityFilter
};
class WalletRescanReserver; //forward declarations for ScanForWalletTransactions/RescanFromTime
-/**
+/**
* A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
* and provides the ability to create new transactions.
*/
@@ -903,7 +906,7 @@ public:
void GetKeyBirthTimes(std::map<CTxDestination, int64_t> &mapKeyBirth) const;
unsigned int ComputeTimeSmart(const CWalletTx& wtx) const;
- /**
+ /**
* Increment the next transaction order id
* @return next transaction order id
*/
@@ -1032,7 +1035,7 @@ public:
}
void GetScriptForMining(std::shared_ptr<CReserveScript> &script);
-
+
unsigned int GetKeyPoolSize()
{
AssertLockHeld(cs_wallet); // set{Ex,In}ternalKeyPool
@@ -1057,7 +1060,7 @@ public:
//! Flush wallet (bitdb flush)
void Flush(bool shutdown=false);
- /**
+ /**
* Address book entry changed.
* @note called with lock cs_wallet held.
*/
@@ -1066,7 +1069,7 @@ public:
const std::string &purpose,
ChangeType status)> NotifyAddressBookChanged;
- /**
+ /**
* Wallet transaction added, removed or updated.
* @note called with lock cs_wallet held.
*/
@@ -1113,7 +1116,7 @@ public:
/* Generates a new HD master key (will not be activated) */
CPubKey GenerateNewHDMasterKey();
-
+
/* Set the current HD master key (will reset the chain child index counters)
Sets the master key's version based on the current wallet version (so the
caller must ensure the current wallet version is correct before calling
@@ -1184,7 +1187,7 @@ public:
};
-/**
+/**
* DEPRECATED Account information.
* Stored in wallet with key "acc"+string account name.
*/
@@ -1230,10 +1233,10 @@ std::vector<CTxDestination> GetAllDestinationsForKey(const CPubKey& key);
class WalletRescanReserver
{
private:
- CWalletRef m_wallet;
+ CWallet* m_wallet;
bool m_could_reserve;
public:
- explicit WalletRescanReserver(CWalletRef w) : m_wallet(w), m_could_reserve(false) {}
+ explicit WalletRescanReserver(CWallet* w) : m_wallet(w), m_could_reserve(false) {}
bool reserve()
{
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 803cc5f0a0..5b275131af 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -232,13 +232,14 @@ public:
unsigned int nCKeys;
unsigned int nWatchKeys;
unsigned int nKeyMeta;
+ unsigned int m_unknown_records;
bool fIsEncrypted;
bool fAnyUnordered;
int nFileVersion;
std::vector<uint256> vWalletUpgrade;
CWalletScanState() {
- nKeys = nCKeys = nWatchKeys = nKeyMeta = 0;
+ nKeys = nCKeys = nWatchKeys = nKeyMeta = m_unknown_records = 0;
fIsEncrypted = false;
fAnyUnordered = false;
nFileVersion = 0;
@@ -509,6 +510,8 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
strErr = "Error reading wallet database: SetHDChain failed";
return false;
}
+ } else if (strType != "bestblock" && strType != "bestblock_nomerkle"){
+ wss.m_unknown_records++;
}
} catch (...)
{
@@ -600,8 +603,8 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
LogPrintf("nFileVersion = %d\n", wss.nFileVersion);
- LogPrintf("Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total\n",
- wss.nKeys, wss.nCKeys, wss.nKeyMeta, wss.nKeys + wss.nCKeys);
+ LogPrintf("Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total. Unknown wallet records: %u\n",
+ wss.nKeys, wss.nCKeys, wss.nKeyMeta, wss.nKeys + wss.nCKeys, wss.m_unknown_records);
// nTimeFirstKey is only reliable if all keys have metadata
if ((wss.nKeys + wss.nCKeys + wss.nWatchKeys) != wss.nKeyMeta)
@@ -753,7 +756,7 @@ void MaybeCompactWalletDB()
return;
}
- for (CWalletRef pwallet : vpwallets) {
+ for (CWallet* pwallet : GetWallets()) {
WalletDatabase& dbh = pwallet->GetDBHandle();
unsigned int nUpdateCounter = dbh.nUpdateCounter;