mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-03 09:56:38 -05:00
Exercise non-DIRTY spent coins in caches in fuzz test
This commit is contained in:
parent
59e6828bb5
commit
561848aaf2
1 changed files with 18 additions and 8 deletions
|
@ -133,7 +133,13 @@ struct CacheLevel
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Class for the base of the hierarchy (roughly simulating a memory-backed CCoinsViewDB). */
|
/** Class for the base of the hierarchy (roughly simulating a memory-backed CCoinsViewDB).
|
||||||
|
*
|
||||||
|
* The initial state consists of the empty UTXO set, though coins whose output index
|
||||||
|
* is 3 (mod 5) always have GetCoin() succeed (but returning an IsSpent() coin unless a UTXO
|
||||||
|
* exists). Coins whose output index is 4 (mod 5) have GetCoin() always succeed after being spent.
|
||||||
|
* This exercises code paths with spent, non-DIRTY cache entries.
|
||||||
|
*/
|
||||||
class CoinsViewBottom final : public CCoinsView
|
class CoinsViewBottom final : public CCoinsView
|
||||||
{
|
{
|
||||||
std::map<COutPoint, Coin> m_data;
|
std::map<COutPoint, Coin> m_data;
|
||||||
|
@ -143,6 +149,10 @@ public:
|
||||||
{
|
{
|
||||||
auto it = m_data.find(outpoint);
|
auto it = m_data.find(outpoint);
|
||||||
if (it == m_data.end()) {
|
if (it == m_data.end()) {
|
||||||
|
if ((outpoint.n % 5) == 3) {
|
||||||
|
coin.Clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
coin = it->second;
|
coin = it->second;
|
||||||
|
@ -164,7 +174,7 @@ public:
|
||||||
{
|
{
|
||||||
for (auto it = data.begin(); it != data.end(); it = erase ? data.erase(it) : std::next(it)) {
|
for (auto it = data.begin(); it != data.end(); it = erase ? data.erase(it) : std::next(it)) {
|
||||||
if (it->second.flags & CCoinsCacheEntry::DIRTY) {
|
if (it->second.flags & CCoinsCacheEntry::DIRTY) {
|
||||||
if (it->second.coin.IsSpent()) {
|
if (it->second.coin.IsSpent() && (it->first.n % 5) != 4) {
|
||||||
m_data.erase(it->first);
|
m_data.erase(it->first);
|
||||||
} else if (erase) {
|
} else if (erase) {
|
||||||
m_data[it->first] = std::move(it->second.coin);
|
m_data[it->first] = std::move(it->second.coin);
|
||||||
|
@ -173,10 +183,10 @@ public:
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* For non-dirty entries being written, compare them with what we have. */
|
/* For non-dirty entries being written, compare them with what we have. */
|
||||||
if (it->second.coin.IsSpent()) {
|
|
||||||
assert(m_data.count(it->first) == 0);
|
|
||||||
} else {
|
|
||||||
auto it2 = m_data.find(it->first);
|
auto it2 = m_data.find(it->first);
|
||||||
|
if (it->second.coin.IsSpent()) {
|
||||||
|
assert(it2 == m_data.end() || it2->second.IsSpent());
|
||||||
|
} else {
|
||||||
assert(it2 != m_data.end());
|
assert(it2 != m_data.end());
|
||||||
assert(it->second.coin.out == it2->second.out);
|
assert(it->second.coin.out == it2->second.out);
|
||||||
assert(it->second.coin.fCoinBase == it2->second.fCoinBase);
|
assert(it->second.coin.fCoinBase == it2->second.fCoinBase);
|
||||||
|
@ -262,9 +272,9 @@ FUZZ_TARGET(coinscache_sim)
|
||||||
auto real = caches.back()->GetCoin(data.outpoints[outpointidx], realcoin);
|
auto real = caches.back()->GetCoin(data.outpoints[outpointidx], realcoin);
|
||||||
// Compare results.
|
// Compare results.
|
||||||
if (!sim.has_value()) {
|
if (!sim.has_value()) {
|
||||||
assert(!real);
|
assert(!real || realcoin.IsSpent());
|
||||||
} else {
|
} else {
|
||||||
assert(!realcoin.IsSpent());
|
assert(real && !realcoin.IsSpent());
|
||||||
const auto& simcoin = data.coins[sim->first];
|
const auto& simcoin = data.coins[sim->first];
|
||||||
assert(realcoin.out == simcoin.out);
|
assert(realcoin.out == simcoin.out);
|
||||||
assert(realcoin.fCoinBase == simcoin.fCoinBase);
|
assert(realcoin.fCoinBase == simcoin.fCoinBase);
|
||||||
|
@ -457,9 +467,9 @@ FUZZ_TARGET(coinscache_sim)
|
||||||
bool real = bottom.GetCoin(data.outpoints[outpointidx], realcoin);
|
bool real = bottom.GetCoin(data.outpoints[outpointidx], realcoin);
|
||||||
auto sim = lookup(outpointidx, 0);
|
auto sim = lookup(outpointidx, 0);
|
||||||
if (!sim.has_value()) {
|
if (!sim.has_value()) {
|
||||||
assert(!real);
|
assert(!real || realcoin.IsSpent());
|
||||||
} else {
|
} else {
|
||||||
assert(!realcoin.IsSpent());
|
assert(real && !realcoin.IsSpent());
|
||||||
assert(realcoin.out == data.coins[sim->first].out);
|
assert(realcoin.out == data.coins[sim->first].out);
|
||||||
assert(realcoin.fCoinBase == data.coins[sim->first].fCoinBase);
|
assert(realcoin.fCoinBase == data.coins[sim->first].fCoinBase);
|
||||||
assert(realcoin.nHeight == sim->second);
|
assert(realcoin.nHeight == sim->second);
|
||||||
|
|
Loading…
Add table
Reference in a new issue