mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-06-24 16:01:26 +02:00
Add CCoinsViewCache::SanityCheck() and use it in fuzz test
This commit is contained in:
parent
3c9cea1340
commit
b0ff310840
@ -314,6 +314,23 @@ void CCoinsViewCache::ReallocateCache()
|
|||||||
::new (&cacheCoins) CCoinsMap();
|
::new (&cacheCoins) CCoinsMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CCoinsViewCache::SanityCheck() const
|
||||||
|
{
|
||||||
|
size_t recomputed_usage = 0;
|
||||||
|
for (const auto& [_, entry] : cacheCoins) {
|
||||||
|
unsigned attr = 0;
|
||||||
|
if (entry.flags & CCoinsCacheEntry::DIRTY) attr |= 1;
|
||||||
|
if (entry.flags & CCoinsCacheEntry::FRESH) attr |= 2;
|
||||||
|
if (entry.coin.IsSpent()) attr |= 4;
|
||||||
|
// Only 5 combinations are possible.
|
||||||
|
assert(attr != 2 && attr != 4 && attr != 7);
|
||||||
|
|
||||||
|
// Recompute cachedCoinsUsage.
|
||||||
|
recomputed_usage += entry.coin.DynamicMemoryUsage();
|
||||||
|
}
|
||||||
|
assert(recomputed_usage == cachedCoinsUsage);
|
||||||
|
}
|
||||||
|
|
||||||
static const size_t MIN_TRANSACTION_OUTPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxOut(), PROTOCOL_VERSION);
|
static const size_t MIN_TRANSACTION_OUTPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxOut(), PROTOCOL_VERSION);
|
||||||
static const size_t MAX_OUTPUTS_PER_BLOCK = MAX_BLOCK_WEIGHT / MIN_TRANSACTION_OUTPUT_WEIGHT;
|
static const size_t MAX_OUTPUTS_PER_BLOCK = MAX_BLOCK_WEIGHT / MIN_TRANSACTION_OUTPUT_WEIGHT;
|
||||||
|
|
||||||
|
@ -320,6 +320,9 @@ public:
|
|||||||
//! See: https://stackoverflow.com/questions/42114044/how-to-release-unordered-map-memory
|
//! See: https://stackoverflow.com/questions/42114044/how-to-release-unordered-map-memory
|
||||||
void ReallocateCache();
|
void ReallocateCache();
|
||||||
|
|
||||||
|
//! Run an internal sanity check on the cache data structure. */
|
||||||
|
void SanityCheck() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @note this is marked const, but may actually append to `cacheCoins`, increasing
|
* @note this is marked const, but may actually append to `cacheCoins`, increasing
|
||||||
|
@ -51,7 +51,8 @@ struct PrecomputedData
|
|||||||
const uint8_t ser[4] = {uint8_t(i), uint8_t(i >> 8), uint8_t(i >> 16), uint8_t(i >> 24)};
|
const uint8_t ser[4] = {uint8_t(i), uint8_t(i >> 8), uint8_t(i >> 16), uint8_t(i >> 24)};
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
CSHA256().Write(PREFIX_S, 1).Write(ser, sizeof(ser)).Finalize(hash.begin());
|
CSHA256().Write(PREFIX_S, 1).Write(ser, sizeof(ser)).Finalize(hash.begin());
|
||||||
/* Convert hash to scriptPubkeys. */
|
/* Convert hash to scriptPubkeys (of different lengths, so SanityCheck's cached memory
|
||||||
|
* usage check has a chance to detect mismatches). */
|
||||||
switch (i % 5U) {
|
switch (i % 5U) {
|
||||||
case 0: /* P2PKH */
|
case 0: /* P2PKH */
|
||||||
coins[i].out.scriptPubKey.resize(25);
|
coins[i].out.scriptPubKey.resize(25);
|
||||||
@ -381,6 +382,7 @@ FUZZ_TARGET(coinscache_sim)
|
|||||||
|
|
||||||
[&]() { // Remove a cache level.
|
[&]() { // Remove a cache level.
|
||||||
// Apply to real caches (this reduces caches.size(), implicitly doing the same on the simulation data).
|
// Apply to real caches (this reduces caches.size(), implicitly doing the same on the simulation data).
|
||||||
|
caches.back()->SanityCheck();
|
||||||
caches.pop_back();
|
caches.pop_back();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -420,6 +422,11 @@ FUZZ_TARGET(coinscache_sim)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanity check all the remaining caches
|
||||||
|
for (const auto& cache : caches) {
|
||||||
|
cache->SanityCheck();
|
||||||
|
}
|
||||||
|
|
||||||
// Full comparison between caches and simulation data, from bottom to top,
|
// Full comparison between caches and simulation data, from bottom to top,
|
||||||
// as AccessCoin on a higher cache may affect caches below it.
|
// as AccessCoin on a higher cache may affect caches below it.
|
||||||
for (unsigned sim_idx = 1; sim_idx <= caches.size(); ++sim_idx) {
|
for (unsigned sim_idx = 1; sim_idx <= caches.size(); ++sim_idx) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user