diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index f4935c4f357..9b1d043b335 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -200,6 +200,11 @@ void CDBBatch::EraseImpl(std::span key) size_estimate += 2 + (slKey.size() > 127) + slKey.size(); } +size_t CDBBatch::ApproximateSize() const +{ + return m_impl_batch->batch.ApproximateSize(); +} + struct LevelDBContext { //! custom environment this database is using (may be nullptr in case of default environment) leveldb::Env* penv; diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 1ff7dc1d2ee..6dd8575b55b 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -119,7 +119,8 @@ public: ssKey.clear(); } - size_t SizeEstimate() const { return size_estimate; } + size_t ApproximateSize() const; + size_t SizeEstimate() const { return size_estimate; } // TODO replace with ApproximateSize }; class CDBIterator diff --git a/src/txdb.cpp b/src/txdb.cpp index 1622039d63b..a1e2aa7feb6 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -113,24 +113,39 @@ bool CCoinsViewDB::BatchWrite(CoinsViewCacheCursor& cursor, const uint256 &hashB // transition from old_tip to hashBlock. // A vector is used for future extensibility, as we may want to support // interrupting after partial writes from multiple independent reorgs. + assert(batch.ApproximateSize() == batch.SizeEstimate()); // TODO remove batch.Erase(DB_BEST_BLOCK); + assert(batch.ApproximateSize() == batch.SizeEstimate()); // TODO remove batch.Write(DB_HEAD_BLOCKS, Vector(hashBlock, old_tip)); + assert(batch.ApproximateSize() == batch.SizeEstimate()); // TODO remove for (auto it{cursor.Begin()}; it != cursor.End();) { if (it->second.IsDirty()) { CoinEntry entry(&it->first); - if (it->second.coin.IsSpent()) + if (it->second.coin.IsSpent()) { + assert(batch.ApproximateSize() == batch.SizeEstimate()); // TODO remove batch.Erase(entry); - else + assert(batch.ApproximateSize() == batch.SizeEstimate()); // TODO remove + } else { + assert(batch.ApproximateSize() == batch.SizeEstimate()); // TODO remove batch.Write(entry, it->second.coin); + assert(batch.ApproximateSize() == batch.SizeEstimate()); // TODO remove + } + changed++; } count++; it = cursor.NextAndMaybeErase(*it); + assert(batch.ApproximateSize() == batch.SizeEstimate()); // TODO remove if (batch.SizeEstimate() > m_options.batch_write_bytes) { LogDebug(BCLog::COINDB, "Writing partial batch of %.2f MiB\n", batch.SizeEstimate() * (1.0 / 1048576.0)); + + assert(batch.ApproximateSize() == batch.SizeEstimate()); // TODO remove m_db->WriteBatch(batch); + assert(batch.ApproximateSize() == batch.SizeEstimate()); // TODO remove batch.Clear(); + assert(batch.ApproximateSize() == batch.SizeEstimate()); // TODO remove + if (m_options.simulate_crash_ratio) { static FastRandomContext rng; if (rng.randrange(m_options.simulate_crash_ratio) == 0) { @@ -142,11 +157,15 @@ bool CCoinsViewDB::BatchWrite(CoinsViewCacheCursor& cursor, const uint256 &hashB } // In the last batch, mark the database as consistent with hashBlock again. + assert(batch.ApproximateSize() == batch.SizeEstimate()); // TODO remove batch.Erase(DB_HEAD_BLOCKS); + assert(batch.ApproximateSize() == batch.SizeEstimate()); // TODO remove batch.Write(DB_BEST_BLOCK, hashBlock); + assert(batch.ApproximateSize() == batch.SizeEstimate()); // TODO remove LogDebug(BCLog::COINDB, "Writing final batch of %.2f MiB\n", batch.SizeEstimate() * (1.0 / 1048576.0)); bool ret = m_db->WriteBatch(batch); + assert(batch.ApproximateSize() == batch.SizeEstimate()); // TODO remove LogDebug(BCLog::COINDB, "Committed %u changed transaction outputs (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count); return ret; }