mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-12 21:52:53 +02:00
dbwrapper: guard CDBBatch scratch streams
`CDBBatch` already owns key and value serialization buffers, but manually reserved and cleared them on each call. Reserve those scratch buffers once in the constructor, then guard `Write()` and `Erase()` use with `ScopedDataStreamUsage`, requiring empty streams on entry and clearing them on every exit path. `WriteImpl()` and `EraseImpl()` pass the bytes immediately to LevelDB's write batch, which copies them and does not retain pointers. `Clear()` now asserts the guards left both scratch streams clean. Co-authored-by: Andrew Toth <andrewstoth@gmail.com>
This commit is contained in:
@@ -163,6 +163,8 @@ CDBBatch::CDBBatch(const CDBWrapper& _parent)
|
||||
: parent{_parent},
|
||||
m_impl_batch{std::make_unique<CDBBatch::WriteBatchImpl>()}
|
||||
{
|
||||
m_key_scratch.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
|
||||
m_value_scratch.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
|
||||
Clear();
|
||||
};
|
||||
|
||||
@@ -171,13 +173,15 @@ CDBBatch::~CDBBatch() = default;
|
||||
void CDBBatch::Clear()
|
||||
{
|
||||
m_impl_batch->batch.Clear();
|
||||
assert(m_key_scratch.empty());
|
||||
assert(m_value_scratch.empty());
|
||||
}
|
||||
|
||||
void CDBBatch::WriteImpl(std::span<const std::byte> key, DataStream& ssValue)
|
||||
void CDBBatch::WriteImpl(std::span<const std::byte> key, DataStream& value)
|
||||
{
|
||||
leveldb::Slice slKey(CharCast(key.data()), key.size());
|
||||
dbwrapper_private::GetObfuscation(parent)(ssValue);
|
||||
leveldb::Slice slValue(CharCast(ssValue.data()), ssValue.size());
|
||||
dbwrapper_private::GetObfuscation(parent)(value);
|
||||
leveldb::Slice slValue(CharCast(value.data()), value.size());
|
||||
m_impl_batch->batch.Put(slKey, slValue);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user