Repository: bitcoin/bitcoin
File: src/test/fuzz/coins_view.cpp (C++)

Code before:
#include <algorithm>
#include <cstdint>
#include <functional>
#include <limits>
#include <memory>
#include <optional>
#include <ranges>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>

namespace {
const Coin EMPTY_COIN{};

bool operator==(const Coin& a, const Coin& b)
{
    if (a.IsSpent() && b.IsSpent()) return true;
    return a.fCoinBase == b.fCoinBase && a.nHeight == b.nHeight && a.out == b.out;
}

/**
 * MutationGuardCoinsViewCache asserts that nothing mutates cacheCoins until
 * BatchWrite is called. It keeps a snapshot of the cacheCoins state, which it
 * uses for the assertion in BatchWrite. After the call to the superclass
 * CCoinsViewCache::BatchWrite returns, it recomputes the snaphshot at that
 * moment.
 */
class MutationGuardCoinsViewCache final : public CCoinsViewCache
{
private:
    struct CacheCoinSnapshot {
        COutPoint outpoint;
        bool dirty{false};
        bool fresh{false};
        Coin coin;
        bool operator==(const CacheCoinSnapshot&) const = default;
    };

    std::vector<CacheCoinSnapshot> ComputeCacheCoinsSnapshot() const
    {
        std::vector<CacheCoinSnapshot> snapshot;
        snapshot.reserve(cacheCoins.size());

        for (const auto& [outpoint, entry] : cacheCoins) {
            snapshot.emplace_back(outpoint, entry.IsDirty(), entry.IsFresh(), entry.coin);
        }

        std::ranges::sort(snapshot, std::less<>{}, &CacheCoinSnapshot::outpoint);
        return snapshot;
    }

Review comment (performance):
Possible typos and grammar issues:

    snaphshot -> snapshot [typo in comment: "recomputes the snaphshot at that moment" makes "snapshot" misspelled]
    snaphshot -> snapshot [typo in comment: "ComputeCacheCoinsSnapshot()" description: "keeps a snapshot ... which it uses for the assertion in BatchWrite. After the call ... it recomputes the snaphshot" — same misspelling repeated]
    excercise -> exercise [typo in comment: "This allows us to excercise all methods" — "excercise" is misspelled]

2026-02-12 14:55:06

Code after:
#include <algorithm>
#include <cstdint>
#include <functional>
#include <limits>
#include <memory>
#include <optional>
#include <ranges>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>

namespace {
const Coin EMPTY_COIN{};

bool operator==(const Coin& a, const Coin& b)
{
    if (a.IsSpent() && b.IsSpent()) return true;
    return a.fCoinBase == b.fCoinBase && a.nHeight == b.nHeight && a.out == b.out;
}

/**
 * MutationGuardCoinsViewCache asserts that nothing mutates cacheCoins until
 * BatchWrite is called. It keeps a snapshot of the cacheCoins state, which it
 * uses for the assertion in BatchWrite. After the call to the superclass
 * CCoinsViewCache::BatchWrite returns, it recomputes the snapshot at that
 * moment.
 */
class MutationGuardCoinsViewCache final : public CCoinsViewCache
{
private:
    struct CacheCoinSnapshot {
        COutPoint outpoint;
        bool dirty{false};
        bool fresh{false};
        Coin coin;
        bool operator==(const CacheCoinSnapshot&) const = default;
    };

    std::vector<CacheCoinSnapshot> ComputeCacheCoinsSnapshot() const
    {
        std::vector<CacheCoinSnapshot> snapshot;
        snapshot.reserve(cacheCoins.size());

        for (const auto& [outpoint, entry] : cacheCoins) {
            snapshot.emplace_back(outpoint, entry.IsDirty(), entry.IsFresh(), entry.coin);
        }

        std::ranges::sort(snapshot, std::less<>{}, &CacheCoinSnapshot::outpoint);
        return snapshot;
    }