mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -04:00
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.
This commit is contained in:
parent
d7700d3a26
commit
043fcb0b05
2 changed files with 5 additions and 5 deletions
|
@ -668,14 +668,14 @@ void BerkeleyDatabase::ReloadDbEnv()
|
||||||
env->ReloadDbEnv();
|
env->ReloadDbEnv();
|
||||||
}
|
}
|
||||||
|
|
||||||
BerkeleyCursor::BerkeleyCursor(BerkeleyDatabase& database, BerkeleyBatch* batch)
|
BerkeleyCursor::BerkeleyCursor(BerkeleyDatabase& database, const BerkeleyBatch& batch)
|
||||||
{
|
{
|
||||||
if (!database.m_db.get()) {
|
if (!database.m_db.get()) {
|
||||||
throw std::runtime_error(STR_INTERNAL_BUG("BerkeleyDatabase does not exist"));
|
throw std::runtime_error(STR_INTERNAL_BUG("BerkeleyDatabase does not exist"));
|
||||||
}
|
}
|
||||||
// Transaction argument to cursor is only needed when using the cursor to
|
// Transaction argument to cursor is only needed when using the cursor to
|
||||||
// write to the database. Read-only cursors do not need a txn pointer.
|
// write to the database. Read-only cursors do not need a txn pointer.
|
||||||
int ret = database.m_db->cursor(batch ? batch->txn() : nullptr, &m_cursor, 0);
|
int ret = database.m_db->cursor(batch.txn(), &m_cursor, 0);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
throw std::runtime_error(STR_INTERNAL_BUG(strprintf("BDB Cursor could not be created. Returned %d", ret)));
|
throw std::runtime_error(STR_INTERNAL_BUG(strprintf("BDB Cursor could not be created. Returned %d", ret)));
|
||||||
}
|
}
|
||||||
|
@ -713,7 +713,7 @@ BerkeleyCursor::~BerkeleyCursor()
|
||||||
std::unique_ptr<DatabaseCursor> BerkeleyBatch::GetNewCursor()
|
std::unique_ptr<DatabaseCursor> BerkeleyBatch::GetNewCursor()
|
||||||
{
|
{
|
||||||
if (!pdb) return nullptr;
|
if (!pdb) return nullptr;
|
||||||
return std::make_unique<BerkeleyCursor>(m_database);
|
return std::make_unique<BerkeleyCursor>(m_database, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BerkeleyBatch::TxnBegin()
|
bool BerkeleyBatch::TxnBegin()
|
||||||
|
@ -825,7 +825,7 @@ bool BerkeleyBatch::HasKey(DataStream&& key)
|
||||||
bool BerkeleyBatch::ErasePrefix(Span<const std::byte> prefix)
|
bool BerkeleyBatch::ErasePrefix(Span<const std::byte> prefix)
|
||||||
{
|
{
|
||||||
if (!TxnBegin()) return false;
|
if (!TxnBegin()) return false;
|
||||||
auto cursor{std::make_unique<BerkeleyCursor>(m_database, this)};
|
auto cursor{std::make_unique<BerkeleyCursor>(m_database, *this)};
|
||||||
// const_cast is safe below even though prefix_key is an in/out parameter,
|
// const_cast is safe below even though prefix_key is an in/out parameter,
|
||||||
// because we are not using the DB_DBT_USERMEM flag, so BDB will allocate
|
// because we are not using the DB_DBT_USERMEM flag, so BDB will allocate
|
||||||
// and return a different output data pointer
|
// and return a different output data pointer
|
||||||
|
|
|
@ -192,7 +192,7 @@ private:
|
||||||
Dbc* m_cursor;
|
Dbc* m_cursor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BerkeleyCursor(BerkeleyDatabase& database, BerkeleyBatch* batch=nullptr);
|
explicit BerkeleyCursor(BerkeleyDatabase& database, const BerkeleyBatch& batch);
|
||||||
~BerkeleyCursor() override;
|
~BerkeleyCursor() override;
|
||||||
|
|
||||||
Status Next(DataStream& key, DataStream& value) override;
|
Status Next(DataStream& key, DataStream& value) override;
|
||||||
|
|
Loading…
Add table
Reference in a new issue