24 return GetCoin(outpoint).has_value();
49 const auto [
ret, inserted] =
cacheCoins.try_emplace(outpoint);
52 ret->second.coin = std::move(*coin);
54 if (
ret->second.coin.IsSpent()) {
68 if (
auto it{
FetchCoin(outpoint)}; it !=
cacheCoins.end() && !it->second.coin.IsSpent())
return it->second.coin;
74 if (coin.out.scriptPubKey.IsUnspendable())
return;
75 CCoinsMap::iterator it;
77 std::tie(it, inserted) =
cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::tuple<>());
79 if (!possible_overwrite) {
80 if (!it->second.coin.IsSpent()) {
81 throw std::logic_error(
"Attempted to overwrite an unspent coin (when possible_overwrite is false)");
96 fresh = !it->second.IsDirty();
101 it->second.coin = std::move(coin);
107 (uint32_t)outpoint.
n,
108 (uint32_t)it->second.coin.nHeight,
109 (int64_t)it->second.coin.out.nValue,
110 (
bool)it->second.coin.IsCoinBase());
114 const auto mem_usage{coin.DynamicMemoryUsage()};
115 auto [it, inserted] =
cacheCoins.try_emplace(std::move(outpoint), std::move(coin));
125 for (
size_t i = 0; i < tx.
vout.size(); ++i) {
126 bool overwrite = check_for_overwrite ? cache.
HaveCoin(
COutPoint(txid, i)) : fCoinbase;
134 CCoinsMap::iterator it =
FetchCoin(outpoint);
139 (uint32_t)outpoint.
n,
140 (uint32_t)it->second.coin.nHeight,
141 (int64_t)it->second.coin.out.nValue,
142 (
bool)it->second.coin.IsCoinBase());
144 *moveout = std::move(it->second.coin);
146 if (it->second.IsFresh()) {
150 it->second.coin.Clear();
158 CCoinsMap::const_iterator it =
FetchCoin(outpoint);
162 return it->second.coin;
167 CCoinsMap::const_iterator it =
FetchCoin(outpoint);
168 return (it !=
cacheCoins.end() && !it->second.coin.IsSpent());
172 CCoinsMap::const_iterator it =
cacheCoins.find(outpoint);
173 return (it !=
cacheCoins.end() && !it->second.coin.IsSpent());
189 if (!it->second.IsDirty()) {
192 CCoinsMap::iterator itUs =
cacheCoins.find(it->first);
196 if (!(it->second.IsFresh() && it->second.coin.IsSpent())) {
199 itUs =
cacheCoins.try_emplace(it->first).first;
201 assert(entry.coin.DynamicMemoryUsage() == 0);
205 entry.coin = std::move(it->second.coin);
207 entry.coin = it->second.coin;
218 if (it->second.IsFresh() && !itUs->second.coin.IsSpent()) {
223 throw std::logic_error(
"FRESH flag misapplied to coin that exists in parent cache");
226 if (itUs->second.IsFresh() && it->second.coin.IsSpent()) {
237 itUs->second.coin = std::move(it->second.coin);
239 itUs->second.coin = it->second.coin;
272 throw std::logic_error(
"Not all unspent flagged entries were cleared");
280 CCoinsMap::iterator it =
cacheCoins.find(hash);
281 if (it !=
cacheCoins.end() && !it->second.IsDirty() && !it->second.IsFresh()) {
286 (uint32_t)it->second.coin.nHeight,
287 (int64_t)it->second.coin.out.nValue,
288 (
bool)it->second.coin.IsCoinBase());
300 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
321 size_t recomputed_usage = 0;
322 size_t count_flagged = 0;
325 if (entry.IsDirty()) attr |= 1;
326 if (entry.IsFresh()) attr |= 2;
327 if (entry.coin.IsSpent()) attr |= 4;
329 assert(attr != 2 && attr != 4 && attr != 7);
332 recomputed_usage += entry.coin.DynamicMemoryUsage();
335 if (entry.IsDirty() || entry.IsFresh()) ++count_flagged;
338 size_t count_linked = 0;
341 assert(it->second.Next()->second.Prev() == it);
342 assert(it->second.Prev()->second.Next() == it);
344 assert(it->second.IsDirty() || it->second.IsFresh());
348 assert(count_linked == count_flagged);
360 if (!alternate.
IsSpent())
return alternate;
366template <
typename ReturnType,
typename Func>
371 }
catch(
const std::runtime_error& e) {
372 for (
const auto& f : err_callbacks) {
375 LogError(
"Error reading from database: %s\n", e.what());
CCoinsView backed by another CCoinsView.
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
size_t EstimateSize() const override
Estimate database size (0 if not implemented)
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
bool BatchWrite(CoinsViewCacheCursor &cursor, const uint256 &hashBlock) override
Do a bulk modification (multiple Coin changes + BestBlock change).
void SetBackend(CCoinsView &viewIn)
std::unique_ptr< CCoinsViewCursor > Cursor() const override
Get a cursor to iterate over the whole state.
std::vector< uint256 > GetHeadBlocks() const override
Retrieve the range of blocks that may have been only partially written.
CCoinsViewBacked(CCoinsView *viewIn)
CCoinsView that adds a memory cache for transactions to another CCoinsView.
CCoinsViewCache(CCoinsView *baseIn, bool deterministic=false)
const bool m_deterministic
uint256 hashBlock
Make mutable so that we can "fill the cache" even from Get-methods declared as "const".
CCoinsMapMemoryResource m_cache_coins_memory_resource
bool SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr)
Spend a coin.
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
bool HaveInputs(const CTransaction &tx) const
Check whether all prevouts of the transaction are present in the UTXO set represented by this view.
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool possible_overwrite)
Add a coin.
bool BatchWrite(CoinsViewCacheCursor &cursor, const uint256 &hashBlock) override
Do a bulk modification (multiple Coin changes + BestBlock change).
unsigned int GetCacheSize() const
Calculate the size of the cache (in number of transaction outputs)
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
void SetBestBlock(const uint256 &hashBlock)
CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
bool Flush()
Push the modifications applied to this cache to its base and wipe local state.
CoinsCachePair m_sentinel
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes)
bool Sync()
Push the modifications applied to this cache to its base while retaining the contents of this cache (...
void EmplaceCoinInternalDANGER(COutPoint &&outpoint, Coin &&coin)
Emplace a coin into cacheCoins without performing any checks, marking the emplaced coin as dirty.
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
void SanityCheck() const
Run an internal sanity check on the cache data structure. */.
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
void ReallocateCache()
Force a reallocation of the cache map.
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
std::vector< std::function< void()> > m_err_callbacks
A list of callbacks to execute upon leveldb read error.
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
Abstract view on the open txout dataset.
virtual std::optional< Coin > GetCoin(const COutPoint &outpoint) const
Retrieve the Coin (unspent transaction output) for a given outpoint.
virtual std::vector< uint256 > GetHeadBlocks() const
Retrieve the range of blocks that may have been only partially written.
virtual bool BatchWrite(CoinsViewCacheCursor &cursor, const uint256 &hashBlock)
Do a bulk modification (multiple Coin changes + BestBlock change).
virtual bool HaveCoin(const COutPoint &outpoint) const
Just check whether a given outpoint is unspent.
virtual size_t EstimateSize() const
Estimate database size (0 if not implemented)
virtual std::unique_ptr< CCoinsViewCursor > Cursor() const
Get a cursor to iterate over the whole state.
virtual uint256 GetBestBlock() const
Retrieve the block hash whose state this CCoinsView currently represents.
An outpoint - a combination of a transaction hash and an index n into its vout.
The basic transaction that is broadcasted on the network and contained in blocks.
const std::vector< CTxOut > vout
const Txid & GetHash() const LIFETIMEBOUND
const std::vector< CTxIn > vin
An output of a transaction.
bool IsSpent() const
Either this coin never existed (see e.g.
constexpr bool IsNull() const
constexpr const std::byte * data() const
static const size_t MIN_TRANSACTION_OUTPUT_WEIGHT
static const Coin coinEmpty
TRACEPOINT_SEMAPHORE(utxocache, add)
static const size_t MAX_OUTPUTS_PER_BLOCK
static ReturnType ExecuteBackedWrapper(Func func, const std::vector< std::function< void()> > &err_callbacks)
const Coin & AccessByTxid(const CCoinsViewCache &view, const Txid &txid)
Utility function to find any unspent output with a given txid.
void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight, bool check_for_overwrite)
Utility function to add all of a transaction's outputs to a cache.
std::unordered_map< COutPoint, CCoinsCacheEntry, SaltedOutpointHasher, std::equal_to< COutPoint >, PoolAllocator< CoinsCachePair, sizeof(CoinsCachePair)+sizeof(void *) *4 > > CCoinsMap
PoolAllocator's MAX_BLOCK_SIZE_BYTES parameter here uses sizeof the data, and adds the size of 4 poin...
CCoinsMap::allocator_type::ResourceType CCoinsMapMemoryResource
static const unsigned int MAX_BLOCK_WEIGHT
The maximum allowed weight for a block, see BIP 141 (network rule)
static const int WITNESS_SCALE_FACTOR
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
bool Func(const std::string &str, std::span< const char > &sp)
Parse a function call.
size_t GetSerializeSize(const T &t)
A Coin in one level of the coins database caching hierarchy.
static void SetFresh(CoinsCachePair &pair, CoinsCachePair &sentinel) noexcept
static void SetDirty(CoinsCachePair &pair, CoinsCachePair &sentinel) noexcept
Cursor for iterating over the linked list of flagged entries in CCoinsViewCache.
CoinsCachePair * NextAndMaybeErase(CoinsCachePair ¤t) noexcept
Return the next entry after current, possibly erasing current.
bool WillErase(CoinsCachePair ¤t) const noexcept
CoinsCachePair * Begin() const noexcept
CoinsCachePair * End() const noexcept
#define TRACEPOINT(context,...)
consteval auto _(util::TranslatedLiteral str)