Skip to content

Commit cf4d72a

Browse files
committed
wallet: db, introduce 'RunWithinTxn()' helper function
'RunWithinTxn()' provides a way to execute db operations within a transactional context. It avoids writing repetitive boilerplate code for starting and committing the database transaction.
1 parent 6ff0aa0 commit cf4d72a

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

src/wallet/wallet.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2411,8 +2411,9 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const std::string& s
24112411

24122412
bool CWallet::DelAddressBook(const CTxDestination& address)
24132413
{
2414-
WalletBatch batch(GetDatabase());
2415-
return DelAddressBookWithDB(batch, address);
2414+
return RunWithinTxn(GetDatabase(), /*process_desc=*/"address book entry removal", [&](WalletBatch& batch){
2415+
return DelAddressBookWithDB(batch, address);
2416+
});
24162417
}
24172418

24182419
bool CWallet::DelAddressBookWithDB(WalletBatch& batch, const CTxDestination& address)

src/wallet/walletdb.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,30 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
12301230
return result;
12311231
}
12321232

1233+
bool RunWithinTxn(WalletDatabase& database, std::string_view process_desc, const std::function<bool(WalletBatch&)>& func)
1234+
{
1235+
WalletBatch batch(database);
1236+
if (!batch.TxnBegin()) {
1237+
LogPrint(BCLog::WALLETDB, "Error: cannot create db txn for %s\n", process_desc);
1238+
return false;
1239+
}
1240+
1241+
// Run procedure
1242+
if (!func(batch)) {
1243+
LogPrint(BCLog::WALLETDB, "Error: %s failed\n", process_desc);
1244+
batch.TxnAbort();
1245+
return false;
1246+
}
1247+
1248+
if (!batch.TxnCommit()) {
1249+
LogPrint(BCLog::WALLETDB, "Error: cannot commit db txn for %s\n", process_desc);
1250+
return false;
1251+
}
1252+
1253+
// All good
1254+
return true;
1255+
}
1256+
12331257
void MaybeCompactWalletDB(WalletContext& context)
12341258
{
12351259
static std::atomic<bool> fOneThread(false);

src/wallet/walletdb.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,20 @@ class WalletBatch
294294
WalletDatabase& m_database;
295295
};
296296

297+
/**
298+
* Executes the provided function 'func' within a database transaction context.
299+
*
300+
* This function ensures that all db modifications performed within 'func()' are
301+
* atomically committed to the db at the end of the process. And, in case of a
302+
* failure during execution, all performed changes are rolled back.
303+
*
304+
* @param database The db connection instance to perform the transaction on.
305+
* @param process_desc A description of the process being executed, used for logging purposes in the event of a failure.
306+
* @param func The function to be executed within the db txn context. It returns a boolean indicating whether to commit or roll back the txn.
307+
* @return true if the db txn executed successfully, false otherwise.
308+
*/
309+
bool RunWithinTxn(WalletDatabase& database, std::string_view process_desc, const std::function<bool(WalletBatch&)>& func);
310+
297311
//! Compacts BDB state so that wallet.dat is self-contained (if there are changes)
298312
void MaybeCompactWalletDB(WalletContext& context);
299313

0 commit comments

Comments
 (0)