wallet: provide WalletBatch to 'RemoveTxs'

Preparing it to be used within a broader db txn procedure.
This commit is contained in:
furszy committed 2024-10-21 08:29:23 -03:00
1 parent 57249ff669
commit aacaaaa0d3
2 files changed
+22 -16

No files matched your search

+21 -16
View File
@@ -2388,8 +2388,21 @@ DBErrors CWallet::LoadWallet()
util::Result<void> CWallet::RemoveTxs(std::vector<uint256>& txs_to_remove) util::Result<void> CWallet::RemoveTxs(std::vector<uint256>& txs_to_remove)
{ {
AssertLockHeld(cs_wallet); AssertLockHeld(cs_wallet);
WalletBatch batch(GetDatabase()); bilingual_str str_err; // future: make RunWithinTxn return a util::Result
if (!batch.TxnBegin()) return util::Error{_("Error starting db txn for wallet transactions removal")}; bool was_txn_committed = RunWithinTxn(GetDatabase(), /*process_desc=*/"remove transactions", [&](WalletBatch& batch) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) {
util::Result<void> result{RemoveTxs(batch, txs_to_remove)};
if (!result) str_err = util::ErrorString(result);
return result.has_value();
});
if (!str_err.empty()) return util::Error{str_err};
if (!was_txn_committed) return util::Error{_("Error starting/committing db txn for wallet transactions removal process")};
return {}; // all good
}
util::Result<void> CWallet::RemoveTxs(WalletBatch& batch, std::vector<uint256>& txs_to_remove)
{
AssertLockHeld(cs_wallet);
if (!batch.HasActiveTxn()) return util::Error{strprintf(_("The transactions removal process can only be executed within a db txn"))};
// Check for transaction existence and remove entries from disk // Check for transaction existence and remove entries from disk
using TxIterator = std::unordered_map<uint256, CWalletTx, SaltedTxidHasher>::const_iterator; using TxIterator = std::unordered_map<uint256, CWalletTx, SaltedTxidHasher>::const_iterator;
@@ -2398,25 +2411,16 @@ util::Result<void> CWallet::RemoveTxs(std::vector<uint256>& txs_to_remove)
for (const uint256& hash : txs_to_remove) { for (const uint256& hash : txs_to_remove) {
auto it_wtx = mapWallet.find(hash); auto it_wtx = mapWallet.find(hash);
if (it_wtx == mapWallet.end()) { if (it_wtx == mapWallet.end()) {
str_err = strprintf(_("Transaction %s does not belong to this wallet"), hash.GetHex()); return util::Error{strprintf(_("Transaction %s does not belong to this wallet"), hash.GetHex())};
break;
} }
if (!batch.EraseTx(hash)) { if (!batch.EraseTx(hash)) {
str_err = strprintf(_("Failure removing transaction: %s"), hash.GetHex()); return util::Error{strprintf(_("Failure removing transaction: %s"), hash.GetHex())};
break;
} }
erased_txs.emplace_back(it_wtx); erased_txs.emplace_back(it_wtx);
} }
// Roll back removals in case of an error // Register callback to update the memory state only when the db txn is actually dumped to disk
if (!str_err.empty()) { batch.RegisterTxnListener({.on_commit=[&, erased_txs]() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) {
batch.TxnAbort();
return util::Error{str_err};
}
// Dump changes to disk
if (!batch.TxnCommit()) return util::Error{_("Error committing db txn for wallet transactions removal")};
// Update the in-memory state and notify upper layers about the removals // Update the in-memory state and notify upper layers about the removals
for (const auto& it : erased_txs) { for (const auto& it : erased_txs) {
const uint256 hash{it->first}; const uint256 hash{it->first};
@@ -2428,8 +2432,9 @@ util::Result<void> CWallet::RemoveTxs(std::vector<uint256>& txs_to_remove)
} }
MarkDirty(); MarkDirty();
}, .on_abort={}});
return {}; // all good return {};
} }
bool CWallet::SetAddressBookWithDB(WalletBatch& batch, const CTxDestination& address, const std::string& strName, const std::optional<AddressPurpose>& new_purpose) bool CWallet::SetAddressBookWithDB(WalletBatch& batch, const CTxDestination& address, const std::string& strName, const std::optional<AddressPurpose>& new_purpose)
+1
View File
@@ -794,6 +794,7 @@ public:
/** Erases the provided transactions from the wallet. */ /** Erases the provided transactions from the wallet. */
util::Result<void> RemoveTxs(std::vector<uint256>& txs_to_remove) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); util::Result<void> RemoveTxs(std::vector<uint256>& txs_to_remove) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
util::Result<void> RemoveTxs(WalletBatch& batch, std::vector<uint256>& txs_to_remove) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::optional<AddressPurpose>& purpose); bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::optional<AddressPurpose>& purpose);