31#include <unordered_map>
74 template<
typename Stream>
82 template<
typename Stream>
99 return memusage::DynamicUsage(
out.scriptPubKey);
141 if (!pair.second.m_flags) {
142 Assume(!pair.second.m_prev && !pair.second.m_next);
143 pair.second.m_prev = sentinel.second.m_prev;
144 pair.second.m_next = &sentinel;
145 sentinel.second.m_prev = &pair;
146 pair.second.m_prev->second.m_next = &pair;
148 Assume(pair.second.m_prev && pair.second.m_next);
149 pair.second.m_flags |= flags;
214 Assume(&pair.second ==
this);
255 return m_hasher.
Hash(
id.hash.ToUint256(), uint64_t{id.n});
270 std::equal_to<COutPoint>,
320 bool will_erase) noexcept
329 const auto next_entry{current.second.Next()};
334 if (current.second.coin.IsSpent()) {
335 assert(current.second.coin.DynamicMemoryUsage() == 0);
336 m_map.erase(current.first);
338 current.second.SetClean();
474 virtual void Reset() noexcept;
543 virtual
void Flush(
bool reallocate_cache = true);
671 mutable std::optional<Coin>
coin{std::nullopt};
680 Assert(!other.ready.test(std::memory_order_relaxed));
694 const auto i{
m_input_head.fetch_add(1, std::memory_order_relaxed)};
695 if (i >=
m_inputs.size())
return false;
700 Assert(!input.ready.test_and_set(std::memory_order_release));
701 input.ready.notify_one();
718 for (
auto& future :
m_futures) future.wait();
733 input.ready.wait(
false, std::memory_order_acquire);
735 return std::move(input.coin);
758 bool deterministic =
false) noexcept
769 void Flush(
bool reallocate_cache =
true)
override
772 LogWarning(
"Block %s input prevout prefetch queue was not fully consumed; inputs were accessed out of order, so prefetching degraded to serial lookups for this block.",
GetBestBlock().
ToString());
std::string ToString(const T &t)
Locale-independent version of std::to_string.
#define Assert(val)
Identity function.
#define Assume(val)
Assume is the identity function.
bool HaveCoin(const COutPoint &outpoint) const override
size_t EstimateSize() const override
Estimate database size.
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
std::optional< Coin > PeekCoin(const COutPoint &outpoint) const override
CCoinsViewBacked(CCoinsView *in_view)
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
void BatchWrite(CoinsViewCacheCursor &cursor, const uint256 &block_hash) override
void SetBackend(CCoinsView &in_view)
std::vector< uint256 > GetHeadBlocks() const override
CCoinsViewCache & m_cache
ResetGuard(const ResetGuard &)=delete
ResetGuard & operator=(ResetGuard &&)=delete
ResetGuard(ResetGuard &&)=delete
ResetGuard & operator=(const ResetGuard &)=delete
ResetGuard(CCoinsViewCache &cache LIFETIMEBOUND) noexcept
CCoinsView that adds a memory cache for transactions to another CCoinsView.
void Sync()
Push the modifications applied to this cache to its base while retaining the contents of this cache (...
const bool m_deterministic
size_t GetDirtyCount() const noexcept
Number of dirty cache entries (transaction outputs).
CCoinsMapMemoryResource m_cache_coins_memory_resource
bool SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr)
Spend a coin.
uint256 m_block_hash
Make mutable so that we can "fill the cache" even from Get-methods declared as "const".
ResetGuard CreateResetGuard() noexcept
Create a scoped guard that will call Reset() on this cache when it goes out of scope.
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
void EmplaceCoinInternalDANGER(const COutPoint &outpoint, Coin &&coin)
Emplace a coin into cacheCoins without performing any checks, marking the emplaced coin as dirty.
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.
virtual std::optional< Coin > FetchCoinFromBase(const COutPoint &outpoint) const
CCoinsViewCache(CCoinsView *in_base, bool deterministic=false)
virtual void Flush(bool reallocate_cache=true)
Push the modifications applied to this cache to its base and wipe local state.
void SetBestBlock(const uint256 &block_hash)
virtual void Reset() noexcept
Discard all modifications made to this cache without flushing to the base view.
unsigned int GetCacheSize() const
Size of the cache (in number of transaction outputs).
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
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.
CoinsCachePair m_sentinel
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes).
void BatchWrite(CoinsViewCacheCursor &cursor, const uint256 &block_hash) override
std::optional< Coin > PeekCoin(const COutPoint &outpoint) const override
bool HaveCoin(const COutPoint &outpoint) const override
void SanityCheck() const
Run an internal sanity check on the cache data structure. */.
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
const uint256 & GetBestBlock() const
Get best block at the time this cursor was created.
virtual bool Valid() const =0
CCoinsViewCursor(const uint256 &in_block_hash)
virtual ~CCoinsViewCursor()=default
virtual bool GetKey(COutPoint &key) const =0
virtual bool GetValue(Coin &coin) const =0
void AddReadErrCallback(std::function< void()> f)
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
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
CCoinsViewErrorCatcher(CCoinsView *view)
std::optional< Coin > PeekCoin(const COutPoint &outpoint) const override
Pure abstract view on the open txout dataset.
virtual size_t EstimateSize() const =0
Estimate database size.
virtual std::vector< uint256 > GetHeadBlocks() const =0
virtual std::optional< Coin > PeekCoin(const COutPoint &outpoint) const =0
virtual std::optional< Coin > GetCoin(const COutPoint &outpoint) const =0
virtual ~CCoinsView()=default
As we use CCoinsViews polymorphically, have a virtual destructor.
virtual void BatchWrite(CoinsViewCacheCursor &cursor, const uint256 &block_hash)=0
virtual bool HaveCoin(const COutPoint &outpoint) const =0
virtual uint256 GetBestBlock() const =0
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.
An output of a transaction.
void Serialize(Stream &s) const
Coin(CTxOut &&outIn, int nHeightIn, bool fCoinBaseIn)
construct a Coin from a CTxOut and height/coinbase information.
CTxOut out
unspent transaction output
bool IsSpent() const
Either this coin never existed (see e.g.
Coin(const CTxOut &outIn, int nHeightIn, bool fCoinBaseIn)
bool fCoinBase
whether containing transaction was a coinbase
void Unserialize(Stream &s)
uint32_t nHeight
at which height this containing transaction was included in the active block chain
size_t DynamicMemoryUsage() const
CoinsViewEmpty & operator=(const CoinsViewEmpty &)=delete
size_t EstimateSize() const override
Estimate database size.
void BatchWrite(CoinsViewCacheCursor &cursor, const uint256 &) override
bool HaveCoin(const COutPoint &outpoint) const override
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
std::optional< Coin > PeekCoin(const COutPoint &outpoint) const override
std::optional< Coin > GetCoin(const COutPoint &) const override
CoinsViewEmpty(const CoinsViewEmpty &)=delete
static CoinsViewEmpty & Get()
std::vector< uint256 > GetHeadBlocks() const override
uint32_t m_input_tail
The latest input not yet accessed by a consumer. Only the main thread increments this.
void StopFetching() noexcept
std::vector< std::future< void > > m_futures
void SetBackend(CCoinsView &)=delete
Swapping the backend or writing through to it with Sync() is not supported while fetching.
std::atomic_uint32_t m_input_head
The latest input not yet being fetched. Workers atomically increment this when fetching.
CoinsViewOverlay(CCoinsView *in_base, std::shared_ptr< ThreadPool > thread_pool, bool deterministic=false) noexcept
std::shared_ptr< ThreadPool > m_thread_pool
Non-null. May have zero workers when input fetching is disabled.
bool ProcessInput() noexcept
Claim and fetch the next input in the queue.
~CoinsViewOverlay() noexcept override
ResetGuard StartFetching(const CBlock &block LIFETIMEBOUND) noexcept
Start fetching inputs from block.
bool AllInputsConsumed() const noexcept
Verify that all parallel fetched input prevouts have been consumed.
std::optional< Coin > FetchCoinFromBase(const COutPoint &outpoint) const override
void Reset() noexcept override
void Flush(bool reallocate_cache=true) override
Push the modifications applied to this cache to its base and wipe local state.
std::vector< InputToFetch > m_inputs
Must only be mutated when m_futures is empty. Elements may be mutated when m_futures is not empty.
Forwards all allocations/deallocations to the PoolResource.
SipHash-1-3-UJ based hasher for the coins cache and related coins containers.
const SipHasher13UJ m_hasher
size_t operator()(const COutPoint &id) const noexcept
Hash an outpoint as its txid jumbo block followed by the zero-extended index as one normal block.
SaltedCoinsCacheHasher(bool deterministic=false)
size_t operator()(const Txid &id) const noexcept
Hash a transaction ID, itself a cryptographic hash, as one jumbo block.
A custom weaker variant of SipHash-1-3 without padding, and supporting "jumbo" inputs.
ALWAYS_INLINE uint64_t Hash(const uint256 &hash) const noexcept
Hash a jumbo block after the data written so far and finalize without modifying the object.
Fixed-size thread pool for running arbitrary tasks concurrently.
const Coin & AccessByTxid(const CCoinsViewCache &view, const Txid &txid)
void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight, bool check_for_overwrite)
std::unordered_map< COutPoint, CCoinsCacheEntry, SaltedCoinsCacheHasher, 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...
std::pair< const COutPoint, CCoinsCacheEntry > CoinsCachePair
CCoinsMap::allocator_type::ResourceType CCoinsMapMemoryResource
constexpr bool TrySub(T &i, const U j) noexcept
A Coin in one level of the coins database caching hierarchy.
CCoinsCacheEntry() noexcept=default
@ FRESH
FRESH means the parent cache does not have this coin or that it is a spent coin in the parent cache.
@ DIRTY
DIRTY means the CCoinsCacheEntry is potentially different from the version in the parent cache.
static void SetFresh(CoinsCachePair &pair, CoinsCachePair &sentinel) noexcept
static void AddFlags(uint8_t flags, CoinsCachePair &pair, CoinsCachePair &sentinel) noexcept
Adding a flag requires a reference to the sentinel of the flagged pair linked list.
bool IsFresh() const noexcept
static void SetDirty(CoinsCachePair &pair, CoinsCachePair &sentinel) noexcept
void SelfRef(CoinsCachePair &pair) noexcept
Only use this for initializing the linked list sentinel.
bool IsDirty() const noexcept
CoinsCachePair * m_prev
These are used to create a doubly linked list of flagged entries.
CoinsCachePair * Next() const noexcept
Only call Next when this entry is DIRTY, FRESH, or both.
CoinsCachePair * Prev() const noexcept
Only call Prev when this entry is DIRTY, FRESH, or both.
Cursor for iterating over the linked list of flagged entries in CCoinsViewCache.
CoinsCachePair & m_sentinel
CoinsCachePair * NextAndMaybeErase(CoinsCachePair ¤t) noexcept
Return the next entry after current, possibly erasing current.
size_t GetTotalCount() const noexcept
bool WillErase(CoinsCachePair ¤t) const noexcept
size_t GetDirtyCount() const noexcept
CoinsCachePair * Begin() const noexcept
CoinsViewCacheCursor(size_t &dirty_count LIFETIMEBOUND, CoinsCachePair &sentinel LIFETIMEBOUND, CCoinsMap &map LIFETIMEBOUND, bool will_erase) noexcept
CoinsCachePair * End() const noexcept
transaction_identifier< false > Txid
Txid commits to all transaction fields except the witness.