Skip to content

Commit 57249ff

Browse files
committed
wallet: introduce active db txn listeners
Useful to ensure that the in-memory state is updated only after successfully committing the data to disk.
1 parent 91e065e commit 57249ff

File tree

8 files changed

+44
-2
lines changed

8 files changed

+44
-2
lines changed

src/wallet/bdb.h

+1
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ class BerkeleyBatch : public DatabaseBatch
208208
bool TxnBegin() override;
209209
bool TxnCommit() override;
210210
bool TxnAbort() override;
211+
bool HasActiveTxn() override { return activeTxn != nullptr; }
211212
DbTxn* txn() const { return activeTxn; }
212213
};
213214

src/wallet/db.h

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ class DatabaseBatch
122122
virtual bool TxnBegin() = 0;
123123
virtual bool TxnCommit() = 0;
124124
virtual bool TxnAbort() = 0;
125+
virtual bool HasActiveTxn() = 0;
125126
};
126127

127128
/** An instance of this class represents one database.

src/wallet/migrate.h

+1
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ class BerkeleyROBatch : public DatabaseBatch
115115
bool TxnBegin() override { return false; }
116116
bool TxnCommit() override { return false; }
117117
bool TxnAbort() override { return false; }
118+
bool HasActiveTxn() override { return false; }
118119
};
119120

120121
//! Return object giving access to Berkeley Read Only database at specified path.

src/wallet/salvage.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class DummyBatch : public DatabaseBatch
4444
bool TxnBegin() override { return true; }
4545
bool TxnCommit() override { return true; }
4646
bool TxnAbort() override { return true; }
47+
bool HasActiveTxn() override { return false; }
4748
};
4849

4950
/** A dummy WalletDatabase that does nothing and never fails. Only used by salvage.

src/wallet/sqlite.h

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ class SQLiteBatch : public DatabaseBatch
9595
bool TxnBegin() override;
9696
bool TxnCommit() override;
9797
bool TxnAbort() override;
98+
bool HasActiveTxn() override { return m_txn; }
9899
};
99100

100101
/** An instance of this class represents one SQLite3 database.

src/wallet/test/util.h

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ class MockableBatch : public DatabaseBatch
9595
bool TxnBegin() override { return m_pass; }
9696
bool TxnCommit() override { return m_pass; }
9797
bool TxnAbort() override { return m_pass; }
98+
bool HasActiveTxn() override { return false; }
9899
};
99100

100101
/** A WalletDatabase whose contents and return values can be modified as needed for testing

src/wallet/walletdb.cpp

+24-2
Original file line numberDiff line numberDiff line change
@@ -1347,12 +1347,34 @@ bool WalletBatch::TxnBegin()
13471347

13481348
bool WalletBatch::TxnCommit()
13491349
{
1350-
return m_batch->TxnCommit();
1350+
bool res = m_batch->TxnCommit();
1351+
if (res) {
1352+
for (const auto& listener : m_txn_listeners) {
1353+
listener.on_commit();
1354+
}
1355+
// txn finished, clear listeners
1356+
m_txn_listeners.clear();
1357+
}
1358+
return res;
13511359
}
13521360

13531361
bool WalletBatch::TxnAbort()
13541362
{
1355-
return m_batch->TxnAbort();
1363+
bool res = m_batch->TxnAbort();
1364+
if (res) {
1365+
for (const auto& listener : m_txn_listeners) {
1366+
listener.on_abort();
1367+
}
1368+
// txn finished, clear listeners
1369+
m_txn_listeners.clear();
1370+
}
1371+
return res;
1372+
}
1373+
1374+
void WalletBatch::RegisterTxnListener(const DbTxnListener& l)
1375+
{
1376+
assert(m_batch->HasActiveTxn());
1377+
m_txn_listeners.emplace_back(l);
13561378
}
13571379

13581380
std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error)

src/wallet/walletdb.h

+14
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,11 @@ class CKeyMetadata
180180
}
181181
};
182182

183+
struct DbTxnListener
184+
{
185+
std::function<void()> on_commit, on_abort;
186+
};
187+
183188
/** Access to the wallet database.
184189
* Opens the database and provides read and write access to it. Each read and write is its own transaction.
185190
* Multiple operation transactions can be started using TxnBegin() and committed using TxnCommit()
@@ -292,9 +297,18 @@ class WalletBatch
292297
bool TxnCommit();
293298
//! Abort current transaction
294299
bool TxnAbort();
300+
bool HasActiveTxn() { return m_batch->HasActiveTxn(); }
301+
302+
//! Registers db txn callback functions
303+
void RegisterTxnListener(const DbTxnListener& l);
304+
295305
private:
296306
std::unique_ptr<DatabaseBatch> m_batch;
297307
WalletDatabase& m_database;
308+
309+
// External functions listening to the current db txn outcome.
310+
// Listeners are cleared at the end of the transaction.
311+
std::vector<DbTxnListener> m_txn_listeners;
298312
};
299313

300314
/**

0 commit comments

Comments
 (0)