Skip to content

Commit 043fcb0

Browse files
committed
wallet: bugfix, GetNewCursor() misses to provide batch ptr to BerkeleyCursor
If the batch ptr is not passed, the cursor will not use the db active txn context which could lead to a deadlock if the code tries to modify the db while it is traversing it. E.g. the 'EraseRecords()' function.
1 parent d7700d3 commit 043fcb0

File tree

2 files changed

+5
-5
lines changed

2 files changed

+5
-5
lines changed

src/wallet/bdb.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -668,14 +668,14 @@ void BerkeleyDatabase::ReloadDbEnv()
668668
env->ReloadDbEnv();
669669
}
670670

671-
BerkeleyCursor::BerkeleyCursor(BerkeleyDatabase& database, BerkeleyBatch* batch)
671+
BerkeleyCursor::BerkeleyCursor(BerkeleyDatabase& database, const BerkeleyBatch& batch)
672672
{
673673
if (!database.m_db.get()) {
674674
throw std::runtime_error(STR_INTERNAL_BUG("BerkeleyDatabase does not exist"));
675675
}
676676
// Transaction argument to cursor is only needed when using the cursor to
677677
// write to the database. Read-only cursors do not need a txn pointer.
678-
int ret = database.m_db->cursor(batch ? batch->txn() : nullptr, &m_cursor, 0);
678+
int ret = database.m_db->cursor(batch.txn(), &m_cursor, 0);
679679
if (ret != 0) {
680680
throw std::runtime_error(STR_INTERNAL_BUG(strprintf("BDB Cursor could not be created. Returned %d", ret)));
681681
}
@@ -713,7 +713,7 @@ BerkeleyCursor::~BerkeleyCursor()
713713
std::unique_ptr<DatabaseCursor> BerkeleyBatch::GetNewCursor()
714714
{
715715
if (!pdb) return nullptr;
716-
return std::make_unique<BerkeleyCursor>(m_database);
716+
return std::make_unique<BerkeleyCursor>(m_database, *this);
717717
}
718718

719719
bool BerkeleyBatch::TxnBegin()
@@ -825,7 +825,7 @@ bool BerkeleyBatch::HasKey(DataStream&& key)
825825
bool BerkeleyBatch::ErasePrefix(Span<const std::byte> prefix)
826826
{
827827
if (!TxnBegin()) return false;
828-
auto cursor{std::make_unique<BerkeleyCursor>(m_database, this)};
828+
auto cursor{std::make_unique<BerkeleyCursor>(m_database, *this)};
829829
// const_cast is safe below even though prefix_key is an in/out parameter,
830830
// because we are not using the DB_DBT_USERMEM flag, so BDB will allocate
831831
// and return a different output data pointer

src/wallet/bdb.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ class BerkeleyCursor : public DatabaseCursor
192192
Dbc* m_cursor;
193193

194194
public:
195-
explicit BerkeleyCursor(BerkeleyDatabase& database, BerkeleyBatch* batch=nullptr);
195+
explicit BerkeleyCursor(BerkeleyDatabase& database, const BerkeleyBatch& batch);
196196
~BerkeleyCursor() override;
197197

198198
Status Next(DataStream& key, DataStream& value) override;

0 commit comments

Comments
 (0)