aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/bdb.cpp51
-rw-r--r--src/wallet/bdb.h6
-rw-r--r--src/wallet/init.cpp2
-rw-r--r--src/wallet/rpcwallet.cpp9
-rw-r--r--src/wallet/scriptpubkeyman.cpp14
-rw-r--r--src/wallet/test/psbt_wallet_tests.cpp2
-rw-r--r--src/wallet/wallet.cpp51
-rw-r--r--src/wallet/wallet.h15
-rw-r--r--src/wallet/walletdb.cpp28
9 files changed, 102 insertions, 76 deletions
diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp
index 125bf004e4..24954f4a02 100644
--- a/src/wallet/bdb.cpp
+++ b/src/wallet/bdb.cpp
@@ -335,7 +335,7 @@ void BerkeleyEnvironment::CheckpointLSN(const std::string& strFile)
}
-BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bool fFlushOnCloseIn) : pdb(nullptr), activeTxn(nullptr)
+BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bool fFlushOnCloseIn) : pdb(nullptr), activeTxn(nullptr), m_cursor(nullptr)
{
fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
fFlushOnClose = fFlushOnCloseIn;
@@ -442,6 +442,7 @@ void BerkeleyBatch::Close()
activeTxn->abort();
activeTxn = nullptr;
pdb = nullptr;
+ CloseCursor();
if (fFlushOnClose)
Flush();
@@ -528,17 +529,15 @@ bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip)
fSuccess = false;
}
- Dbc* pcursor = db.GetCursor();
- if (pcursor)
+ if (db.StartCursor()) {
while (fSuccess) {
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
- int ret1 = db.ReadAtCursor(pcursor, ssKey, ssValue);
- if (ret1 == DB_NOTFOUND) {
- pcursor->close();
+ bool complete;
+ bool ret1 = db.ReadAtCursor(ssKey, ssValue, complete);
+ if (complete) {
break;
- } else if (ret1 != 0) {
- pcursor->close();
+ } else if (!ret1) {
fSuccess = false;
break;
}
@@ -556,6 +555,8 @@ bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip)
if (ret2 > 0)
fSuccess = false;
}
+ db.CloseCursor();
+ }
if (fSuccess) {
db.Close();
env->CloseDb(strFile);
@@ -738,27 +739,30 @@ void BerkeleyDatabase::ReloadDbEnv()
}
}
-Dbc* BerkeleyBatch::GetCursor()
+bool BerkeleyBatch::StartCursor()
{
+ assert(!m_cursor);
if (!pdb)
- return nullptr;
- Dbc* pcursor = nullptr;
- int ret = pdb->cursor(nullptr, &pcursor, 0);
- if (ret != 0)
- return nullptr;
- return pcursor;
+ return false;
+ int ret = pdb->cursor(nullptr, &m_cursor, 0);
+ return ret == 0;
}
-int BerkeleyBatch::ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue)
+bool BerkeleyBatch::ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete)
{
+ complete = false;
+ if (m_cursor == nullptr) return false;
// Read at cursor
SafeDbt datKey;
SafeDbt datValue;
- int ret = pcursor->get(datKey, datValue, DB_NEXT);
+ int ret = m_cursor->get(datKey, datValue, DB_NEXT);
+ if (ret == DB_NOTFOUND) {
+ complete = true;
+ }
if (ret != 0)
- return ret;
+ return false;
else if (datKey.get_data() == nullptr || datValue.get_data() == nullptr)
- return 99999;
+ return false;
// Convert to streams
ssKey.SetType(SER_DISK);
@@ -767,7 +771,14 @@ int BerkeleyBatch::ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& s
ssValue.SetType(SER_DISK);
ssValue.clear();
ssValue.write((char*)datValue.get_data(), datValue.get_size());
- return 0;
+ return true;
+}
+
+void BerkeleyBatch::CloseCursor()
+{
+ if (!m_cursor) return;
+ m_cursor->close();
+ m_cursor = nullptr;
}
bool BerkeleyBatch::TxnBegin()
diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h
index c121bb4228..ee9cfa46b1 100644
--- a/src/wallet/bdb.h
+++ b/src/wallet/bdb.h
@@ -198,6 +198,7 @@ protected:
Db* pdb;
std::string strFile;
DbTxn* activeTxn;
+ Dbc* m_cursor;
bool fReadOnly;
bool fFlushOnClose;
BerkeleyEnvironment *env;
@@ -284,8 +285,9 @@ public:
return HasKey(ssKey);
}
- Dbc* GetCursor();
- int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue);
+ bool StartCursor();
+ bool ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete);
+ void CloseCursor();
bool TxnBegin();
bool TxnCommit();
bool TxnAbort();
diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp
index 3885eb6185..f173b5e62b 100644
--- a/src/wallet/init.cpp
+++ b/src/wallet/init.cpp
@@ -7,8 +7,8 @@
#include <interfaces/chain.h>
#include <net.h>
#include <node/context.h>
+#include <node/ui_interface.h>
#include <outputtype.h>
-#include <ui_interface.h>
#include <util/moneystr.h>
#include <util/system.h>
#include <util/translation.h>
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 00927a2e55..55114a17d7 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -223,7 +223,7 @@ static void SetFeeEstimateMode(const CWallet* pwallet, CCoinControl& cc, const U
cc.m_feerate = CFeeRate(fee_rate);
// default RBF to true for explicit fee rate modes
- if (cc.m_signal_bip125_rbf == boost::none) cc.m_signal_bip125_rbf = true;
+ if (cc.m_signal_bip125_rbf == nullopt) cc.m_signal_bip125_rbf = true;
} else if (!estimate_param.isNull()) {
cc.m_confirm_target = ParseConfirmTarget(estimate_param, pwallet->chain().estimateMaxBlocks());
}
@@ -306,7 +306,7 @@ static UniValue getrawchangeaddress(const JSONRPCRequest& request)
throw JSONRPCError(RPC_WALLET_ERROR, "Error: This wallet has no available keys");
}
- OutputType output_type = pwallet->m_default_change_type != OutputType::CHANGE_AUTO ? pwallet->m_default_change_type : pwallet->m_default_address_type;
+ OutputType output_type = pwallet->m_default_change_type.get_value_or(pwallet->m_default_address_type);
if (!request.params[0].isNull()) {
if (!ParseOutputType(request.params[0].get_str(), output_type)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[0].get_str()));
@@ -2993,10 +2993,11 @@ void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& f
if (options.exists("changeAddress")) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both changeAddress and address_type options");
}
- coinControl.m_change_type = pwallet->m_default_change_type;
- if (!ParseOutputType(options["change_type"].get_str(), *coinControl.m_change_type)) {
+ OutputType out_type;
+ if (!ParseOutputType(options["change_type"].get_str(), out_type)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown change type '%s'", options["change_type"].get_str()));
}
+ coinControl.m_change_type.emplace(out_type);
}
coinControl.fAllowWatchOnly = ParseIncludeWatchonly(options["includeWatching"], *pwallet);
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp
index d7c50a9d2a..38d94335a3 100644
--- a/src/wallet/scriptpubkeyman.cpp
+++ b/src/wallet/scriptpubkeyman.cpp
@@ -597,11 +597,6 @@ TransactionError LegacyScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psb
continue;
}
- // Verify input looks sane. This will check that we have at most one uxto, witness or non-witness.
- if (!input.IsSane()) {
- return TransactionError::INVALID_PSBT;
- }
-
// Get the Sighash type
if (sign && input.sighash_type > 0 && input.sighash_type != sighash_type) {
return TransactionError::SIGHASH_MISMATCH;
@@ -1900,8 +1895,8 @@ bool DescriptorScriptPubKeyMan::SetupDescriptorGeneration(const CExtKey& master_
desc_prefix = "wpkh(" + xpub + "/84'";
break;
}
- default: assert(false);
- }
+ } // no default case, so the compiler can warn about missing cases
+ assert(!desc_prefix.empty());
// Mainnet derives at 0', testnet and regtest derive at 1'
if (Params().IsTestChain()) {
@@ -2086,11 +2081,6 @@ TransactionError DescriptorScriptPubKeyMan::FillPSBT(PartiallySignedTransaction&
continue;
}
- // Verify input looks sane. This will check that we have at most one uxto, witness or non-witness.
- if (!input.IsSane()) {
- return TransactionError::INVALID_PSBT;
- }
-
// Get the Sighash type
if (sign && input.sighash_type > 0 && input.sighash_type != sighash_type) {
return TransactionError::SIGHASH_MISMATCH;
diff --git a/src/wallet/test/psbt_wallet_tests.cpp b/src/wallet/test/psbt_wallet_tests.cpp
index 3f85a48ff3..ce7e661b67 100644
--- a/src/wallet/test/psbt_wallet_tests.cpp
+++ b/src/wallet/test/psbt_wallet_tests.cpp
@@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(psbt_updater_test)
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << psbtx;
std::string final_hex = HexStr(ssTx);
- BOOST_CHECK_EQUAL(final_hex, "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e88701042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000");
+ BOOST_CHECK_EQUAL(final_hex, "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001008a020000000158e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7501000000171600145f275f436b09a8cc9a2eb2a2f528485c68a56323feffffff02d8231f1b0100000017a914aed962d6654f9a2b36608eb9d64d2b260db4f1118700c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8876500000001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e88701042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000");
// Mutate the transaction so that one of the inputs is invalid
psbtx.tx->vin[0].prevout.n = 2;
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 57eec9baf9..235b269805 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -99,9 +99,11 @@ std::unique_ptr<interfaces::Handler> HandleLoadWallet(LoadWalletFn load_wallet)
return interfaces::MakeHandler([it] { LOCK(cs_wallets); g_load_wallet_fns.erase(it); });
}
+static Mutex g_loading_wallet_mutex;
static Mutex g_wallet_release_mutex;
static std::condition_variable g_wallet_release_cv;
-static std::set<std::string> g_unloading_wallet_set;
+static std::set<std::string> g_loading_wallet_set GUARDED_BY(g_loading_wallet_mutex);
+static std::set<std::string> g_unloading_wallet_set GUARDED_BY(g_wallet_release_mutex);
// Custom deleter for shared_ptr<CWallet>.
static void ReleaseWallet(CWallet* wallet)
@@ -145,7 +147,8 @@ void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
}
}
-std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const WalletLocation& location, bilingual_str& error, std::vector<bilingual_str>& warnings)
+namespace {
+std::shared_ptr<CWallet> LoadWalletInternal(interfaces::Chain& chain, const WalletLocation& location, bilingual_str& error, std::vector<bilingual_str>& warnings)
{
try {
if (!CWallet::Verify(chain, location, error, warnings)) {
@@ -166,6 +169,19 @@ std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const WalletLocati
return nullptr;
}
}
+} // namespace
+
+std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const WalletLocation& location, bilingual_str& error, std::vector<bilingual_str>& warnings)
+{
+ auto result = WITH_LOCK(g_loading_wallet_mutex, return g_loading_wallet_set.insert(location.GetName()));
+ if (!result.second) {
+ error = Untranslated("Wallet already being loading.");
+ return nullptr;
+ }
+ auto wallet = LoadWalletInternal(chain, location, error, warnings);
+ WITH_LOCK(g_loading_wallet_mutex, g_loading_wallet_set.erase(result.first));
+ return wallet;
+}
std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings)
{
@@ -2491,13 +2507,8 @@ TransactionError CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bool& comp
continue;
}
- // Verify input looks sane. This will check that we have at most one uxto, witness or non-witness.
- if (!input.IsSane()) {
- return TransactionError::INVALID_PSBT;
- }
-
// If we have no utxo, grab it from the wallet.
- if (!input.non_witness_utxo && input.witness_utxo.IsNull()) {
+ if (!input.non_witness_utxo) {
const uint256& txhash = txin.prevout.hash;
const auto it = mapWallet.find(txhash);
if (it != mapWallet.end()) {
@@ -2653,11 +2664,11 @@ static uint32_t GetLocktimeForNewTransaction(interfaces::Chain& chain, const uin
return locktime;
}
-OutputType CWallet::TransactionChangeType(OutputType change_type, const std::vector<CRecipient>& vecSend)
+OutputType CWallet::TransactionChangeType(const Optional<OutputType>& change_type, const std::vector<CRecipient>& vecSend)
{
// If -changetype is specified, always use that change type.
- if (change_type != OutputType::CHANGE_AUTO) {
- return change_type;
+ if (change_type) {
+ return *change_type;
}
// if m_default_address_type is legacy, use legacy address as change (even
@@ -3826,14 +3837,20 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
}
}
- if (!gArgs.GetArg("-addresstype", "").empty() && !ParseOutputType(gArgs.GetArg("-addresstype", ""), walletInstance->m_default_address_type)) {
- error = strprintf(_("Unknown address type '%s'"), gArgs.GetArg("-addresstype", ""));
- return nullptr;
+ if (!gArgs.GetArg("-addresstype", "").empty()) {
+ if (!ParseOutputType(gArgs.GetArg("-addresstype", ""), walletInstance->m_default_address_type)) {
+ error = strprintf(_("Unknown address type '%s'"), gArgs.GetArg("-addresstype", ""));
+ return nullptr;
+ }
}
- if (!gArgs.GetArg("-changetype", "").empty() && !ParseOutputType(gArgs.GetArg("-changetype", ""), walletInstance->m_default_change_type)) {
- error = strprintf(_("Unknown change type '%s'"), gArgs.GetArg("-changetype", ""));
- return nullptr;
+ if (!gArgs.GetArg("-changetype", "").empty()) {
+ OutputType out_type;
+ if (!ParseOutputType(gArgs.GetArg("-changetype", ""), out_type)) {
+ error = strprintf(_("Unknown change type '%s'"), gArgs.GetArg("-changetype", ""));
+ return nullptr;
+ }
+ walletInstance->m_default_change_type = out_type;
}
if (gArgs.IsArgSet("-mintxfee")) {
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 9931671fb4..32d8481cd8 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -13,11 +13,11 @@
#include <policy/feerate.h>
#include <psbt.h>
#include <tinyformat.h>
-#include <ui_interface.h>
#include <util/message.h>
#include <util/strencodings.h>
#include <util/string.h>
#include <util/system.h>
+#include <util/ui_change_type.h>
#include <validationinterface.h>
#include <wallet/coinselection.h>
#include <wallet/crypter.h>
@@ -105,9 +105,6 @@ class ReserveDestination;
//! Default for -addresstype
constexpr OutputType DEFAULT_ADDRESS_TYPE{OutputType::BECH32};
-//! Default for -changetype
-constexpr OutputType DEFAULT_CHANGE_TYPE{OutputType::CHANGE_AUTO};
-
static constexpr uint64_t KNOWN_WALLET_FLAGS =
WALLET_FLAG_AVOID_REUSE
| WALLET_FLAG_BLANK_WALLET
@@ -934,7 +931,7 @@ public:
Balance GetBalance(int min_depth = 0, bool avoid_reuse = true) const;
CAmount GetAvailableBalance(const CCoinControl* coinControl = nullptr) const;
- OutputType TransactionChangeType(OutputType change_type, const std::vector<CRecipient>& vecSend);
+ OutputType TransactionChangeType(const Optional<OutputType>& change_type, const std::vector<CRecipient>& vecSend);
/**
* Insert additional inputs into the transaction by
@@ -1012,7 +1009,13 @@ public:
CFeeRate m_fallback_fee{DEFAULT_FALLBACK_FEE};
CFeeRate m_discard_rate{DEFAULT_DISCARD_FEE};
OutputType m_default_address_type{DEFAULT_ADDRESS_TYPE};
- OutputType m_default_change_type{DEFAULT_CHANGE_TYPE};
+ /**
+ * Default output type for change outputs. When unset, automatically choose type
+ * based on address type setting and the types other of non-change outputs
+ * (see -changetype option documentation and implementation in
+ * CWallet::TransactionChangeType for details).
+ */
+ Optional<OutputType> m_default_change_type{};
/** Absolute maximum transaction fee (in satoshis) used by default for the wallet */
CAmount m_default_max_tx_fee{DEFAULT_TRANSACTION_MAXFEE};
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 603887ee58..ba5087e2e1 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -700,8 +700,7 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
}
// Get cursor
- Dbc* pcursor = m_batch.GetCursor();
- if (!pcursor)
+ if (!m_batch.StartCursor())
{
pwallet->WalletLogPrintf("Error getting wallet database cursor\n");
return DBErrors::CORRUPT;
@@ -712,11 +711,14 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
// Read next record
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
- int ret = m_batch.ReadAtCursor(pcursor, ssKey, ssValue);
- if (ret == DB_NOTFOUND)
+ bool complete;
+ bool ret = m_batch.ReadAtCursor(ssKey, ssValue, complete);
+ if (complete) {
break;
- else if (ret != 0)
+ }
+ else if (!ret)
{
+ m_batch.CloseCursor();
pwallet->WalletLogPrintf("Error reading next record from wallet database\n");
return DBErrors::CORRUPT;
}
@@ -743,10 +745,10 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
if (!strErr.empty())
pwallet->WalletLogPrintf("%s\n", strErr);
}
- pcursor->close();
} catch (...) {
result = DBErrors::CORRUPT;
}
+ m_batch.CloseCursor();
// Set the active ScriptPubKeyMans
for (auto spk_man_pair : wss.m_active_external_spks) {
@@ -850,8 +852,7 @@ DBErrors WalletBatch::FindWalletTx(std::vector<uint256>& vTxHash, std::list<CWal
}
// Get cursor
- Dbc* pcursor = m_batch.GetCursor();
- if (!pcursor)
+ if (!m_batch.StartCursor())
{
LogPrintf("Error getting wallet database cursor\n");
return DBErrors::CORRUPT;
@@ -862,11 +863,12 @@ DBErrors WalletBatch::FindWalletTx(std::vector<uint256>& vTxHash, std::list<CWal
// Read next record
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
- int ret = m_batch.ReadAtCursor(pcursor, ssKey, ssValue);
- if (ret == DB_NOTFOUND)
+ bool complete;
+ bool ret = m_batch.ReadAtCursor(ssKey, ssValue, complete);
+ if (complete) {
break;
- else if (ret != 0)
- {
+ } else if (!ret) {
+ m_batch.CloseCursor();
LogPrintf("Error reading next record from wallet database\n");
return DBErrors::CORRUPT;
}
@@ -881,10 +883,10 @@ DBErrors WalletBatch::FindWalletTx(std::vector<uint256>& vTxHash, std::list<CWal
ssValue >> vWtx.back();
}
}
- pcursor->close();
} catch (...) {
result = DBErrors::CORRUPT;
}
+ m_batch.CloseCursor();
return result;
}