Bitcoin Core 31.99.0
P2P Digital Currency
Classes | Public Member Functions | Protected Member Functions | Private Member Functions | Private Attributes | List of all members
CoinsViewOverlay Class Reference

CCoinsViewCache subclass that asynchronously fetches most block input prevouts in parallel during ConnectBlock without mutating the base cache. More...

#include <coins.h>

Inheritance diagram for CoinsViewOverlay:
[legend]
Collaboration diagram for CoinsViewOverlay:
[legend]

Classes

struct  InputToFetch
 The inputs of the block which is being fetched. More...
 

Public Member Functions

 CoinsViewOverlay (CCoinsView *in_base, std::shared_ptr< ThreadPool > thread_pool, bool deterministic=false) noexcept
 
 ~CoinsViewOverlay () noexcept override
 
ResetGuard StartFetching (const CBlock &block LIFETIMEBOUND) noexcept
 Start fetching inputs from block. More...
 
void Flush (bool reallocate_cache=true) override
 Push the modifications applied to this cache to its base and wipe local state. More...
 
bool AllInputsConsumed () const noexcept
 Verify that all parallel fetched input prevouts have been consumed. More...
 
- Public Member Functions inherited from CCoinsViewCache
 CCoinsViewCache (CCoinsView *in_base, bool deterministic=false)
 
 CCoinsViewCache (const CCoinsViewCache &)=delete
 By deleting the copy constructor, we prevent accidentally using it when one intends to create a cache on top of a base cache. More...
 
std::optional< CoinGetCoin (const COutPoint &outpoint) const override
 Retrieve the Coin (unspent transaction output) for a given outpoint. More...
 
std::optional< CoinPeekCoin (const COutPoint &outpoint) const override
 Retrieve the Coin (unspent transaction output) for a given outpoint, without caching results. More...
 
bool HaveCoin (const COutPoint &outpoint) const override
 Just check whether a given outpoint is unspent. More...
 
uint256 GetBestBlock () const override
 Retrieve the block hash whose state this CCoinsView currently represents. More...
 
void SetBestBlock (const uint256 &block_hash)
 
void BatchWrite (CoinsViewCacheCursor &cursor, const uint256 &block_hash) override
 Do a bulk modification (multiple Coin changes + BestBlock change). More...
 
bool HaveCoinInCache (const COutPoint &outpoint) const
 Check if we have the given utxo already loaded in this cache. More...
 
const CoinAccessCoin (const COutPoint &output) const
 Return a reference to Coin in the cache, or coinEmpty if not found. More...
 
void AddCoin (const COutPoint &outpoint, Coin &&coin, bool possible_overwrite)
 Add a coin. More...
 
void EmplaceCoinInternalDANGER (COutPoint &&outpoint, Coin &&coin)
 Emplace a coin into cacheCoins without performing any checks, marking the emplaced coin as dirty. More...
 
bool SpendCoin (const COutPoint &outpoint, Coin *moveto=nullptr)
 Spend a coin. More...
 
virtual void Flush (bool reallocate_cache=true)
 Push the modifications applied to this cache to its base and wipe local state. More...
 
void Sync ()
 Push the modifications applied to this cache to its base while retaining the contents of this cache (except for spent coins, which we erase). More...
 
void Uncache (const COutPoint &outpoint)
 Removes the UTXO with the given outpoint from the cache, if it is not modified. More...
 
unsigned int GetCacheSize () const
 Size of the cache (in number of transaction outputs) More...
 
size_t GetDirtyCount () const noexcept
 Number of dirty cache entries (transaction outputs) More...
 
size_t DynamicMemoryUsage () const
 Calculate the size of the cache (in bytes) More...
 
bool HaveInputs (const CTransaction &tx) const
 Check whether all prevouts of the transaction are present in the UTXO set represented by this view. More...
 
void ReallocateCache ()
 Force a reallocation of the cache map. More...
 
void SanityCheck () const
 Run an internal sanity check on the cache data structure. *‍/. More...
 
ResetGuard CreateResetGuard () noexcept
 Create a scoped guard that will call Reset() on this cache when it goes out of scope. More...
 
- Public Member Functions inherited from CCoinsViewBacked
 CCoinsViewBacked (CCoinsView *in_view)
 
void SetBackend (CCoinsView &in_view)
 
std::optional< CoinGetCoin (const COutPoint &outpoint) const override
 Retrieve the Coin (unspent transaction output) for a given outpoint. More...
 
std::optional< CoinPeekCoin (const COutPoint &outpoint) const override
 Retrieve the Coin (unspent transaction output) for a given outpoint, without caching results. More...
 
bool HaveCoin (const COutPoint &outpoint) const override
 Just check whether a given outpoint is unspent. More...
 
uint256 GetBestBlock () const override
 Retrieve the block hash whose state this CCoinsView currently represents. More...
 
std::vector< uint256GetHeadBlocks () const override
 Retrieve the range of blocks that may have been only partially written. More...
 
void BatchWrite (CoinsViewCacheCursor &cursor, const uint256 &block_hash) override
 Do a bulk modification (multiple Coin changes + BestBlock change). More...
 
size_t EstimateSize () const override
 Estimate database size. More...
 
- Public Member Functions inherited from CCoinsView
virtual ~CCoinsView ()=default
 As we use CCoinsViews polymorphically, have a virtual destructor. More...
 
virtual std::optional< CoinGetCoin (const COutPoint &outpoint) const =0
 Retrieve the Coin (unspent transaction output) for a given outpoint. More...
 
virtual std::optional< CoinPeekCoin (const COutPoint &outpoint) const =0
 Retrieve the Coin (unspent transaction output) for a given outpoint, without caching results. More...
 
virtual bool HaveCoin (const COutPoint &outpoint) const =0
 Just check whether a given outpoint is unspent. More...
 
virtual uint256 GetBestBlock () const =0
 Retrieve the block hash whose state this CCoinsView currently represents. More...
 
virtual std::vector< uint256GetHeadBlocks () const =0
 Retrieve the range of blocks that may have been only partially written. More...
 
virtual void BatchWrite (CoinsViewCacheCursor &cursor, const uint256 &block_hash)=0
 Do a bulk modification (multiple Coin changes + BestBlock change). More...
 
virtual size_t EstimateSize () const =0
 Estimate database size. More...
 

Protected Member Functions

void Reset () noexcept override
 Discard all modifications made to this cache without flushing to the base view. More...
 
virtual void Reset () noexcept
 Discard all modifications made to this cache without flushing to the base view. More...
 
virtual std::optional< CoinFetchCoinFromBase (const COutPoint &outpoint) const
 

Private Member Functions

bool ProcessInput () noexcept
 Claim and fetch the next input in the queue. More...
 
void StopFetching () noexcept
 Stop all worker threads and clear fetching data. More...
 
std::optional< CoinFetchCoinFromBase (const COutPoint &outpoint) const override
 

Private Attributes

std::atomic_uint32_t m_input_head {0}
 The latest input not yet being fetched. Workers atomically increment this when fetching. More...
 
uint32_t m_input_tail {0}
 The latest input not yet accessed by a consumer. Only the main thread increments this. More...
 
std::vector< InputToFetchm_inputs {}
 Must only be mutated when m_futures is empty. Elements may be mutated when m_futures is not empty. More...
 
std::shared_ptr< ThreadPoolm_thread_pool
 Non-null. May have zero workers when input fetching is disabled. More...
 
std::vector< std::future< void > > m_futures {}
 

Additional Inherited Members

- Protected Attributes inherited from CCoinsViewCache
uint256 m_block_hash
 Make mutable so that we can "fill the cache" even from Get-methods declared as "const". More...
 
CCoinsMapMemoryResource m_cache_coins_memory_resource {}
 
CoinsCachePair m_sentinel
 
CCoinsMap cacheCoins
 
size_t cachedCoinsUsage {0}
 
size_t m_dirty_count {0}
 
- Protected Attributes inherited from CCoinsViewBacked
CCoinsViewbase
 

Detailed Description

CCoinsViewCache subclass that asynchronously fetches most block input prevouts in parallel during ConnectBlock without mutating the base cache.

Only used in ConnectBlock to pass as an ephemeral view that can be reset if the block is invalid. It provides the same interface as CCoinsViewCache. It adds an additional StartFetching method to provide the block.

When a block is passed to StartFetching, the inputs of the block are flattened into a vector of InputToFetch objects. StartFetching then submits worker tasks to a ThreadPool and keeps the returned futures alive until fetching is stopped.

ProcessInput() atomically fetches and increments m_input_head, so each thread can only access a single element of the m_inputs vector at a time. Workers race to claim inputs, so they may fetch elements in any order. If the fetched index is greater than or equal to the size of m_inputs, no more inputs can be fetched and false is returned.

The worker claims the InputToFetch at this index, fetches the coin from the base cache and moves it into the InputToFetch object. The ready flag is then set with a release memory order. This allows the ready flag to be used as a memory fence, guaranteeing the coin being written to the object will have happened before another thread tests the flag with an acquire memory order. This assumes all base->PeekCoin() paths are safe for concurrent readers and do not mutate lower cache layers.

When a coin is requested from the cache on the main thread and is not already in cacheCoins map, FetchCoinFromBase checks whether the next unconsumed entry in m_inputs has the requested outpoint. On a match, m_input_tail is advanced and the entry's ready flag is waited on with an acquire memory order until a worker has finished fetching it. The coin is then moved out and returned. Since the main thread is the only consumer of validation results, it blocks on the specific input it needs rather than racing workers for other inputs.

StopFetching() is called in Flush() and in Reset() (the per-block teardown) so workers stop before the block they reference goes away. It stops fetching by moving m_input_head to the end of m_inputs (so workers quickly exit), then waits for all futures to complete and clears the per-block state (m_inputs and the head/tail counters).

  Workers advance m_input_head to fetch inputs. Main thread advances m_input_tail to consume.

  Before workers start:

            m_input_head
            m_input_tail
                 │
                 ▼
            ┌─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
  m_inputs: │ waiting │ waiting │ waiting │ waiting │ waiting │ waiting │ waiting │ waiting │ waiting │
            │         │         │         │         │         │         │         │         │         │
            └─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘

  After workers start:

                                  Worker 2            Worker 0  Worker 3  Worker 1  m_input_head
                                     │                   │         │         │         │
                                     ▼                   ▼         ▼         ▼         ▼
            ┌─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
  m_inputs: │  ready  │  ready  │fetching │  ready  │fetching │fetching │fetching │ waiting │ waiting │
            │consumed │    ✓    │    ●    │    ✓    │    ●    │    ●    │    ●    │         │         │
            └─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘
                           ▲
                           │
                      m_input_tail

Definition at line 616 of file coins.h.

Constructor & Destructor Documentation

◆ CoinsViewOverlay()

CoinsViewOverlay::CoinsViewOverlay ( CCoinsView in_base,
std::shared_ptr< ThreadPool thread_pool,
bool  deterministic = false 
)
inlineexplicitnoexcept

Definition at line 715 of file coins.h.

◆ ~CoinsViewOverlay()

CoinsViewOverlay::~CoinsViewOverlay ( )
inlineoverridenoexcept

Definition at line 722 of file coins.h.

Here is the call graph for this function:

Member Function Documentation

◆ AllInputsConsumed()

bool CoinsViewOverlay::AllInputsConsumed ( ) const
inlinenoexcept

Verify that all parallel fetched input prevouts have been consumed.

Definition at line 737 of file coins.h.

Here is the caller graph for this function:

◆ FetchCoinFromBase()

std::optional< Coin > CoinsViewOverlay::FetchCoinFromBase ( const COutPoint outpoint) const
inlineoverrideprivatevirtual

Reimplemented from CCoinsViewCache.

Definition at line 686 of file coins.h.

Here is the call graph for this function:

◆ Flush()

void CoinsViewOverlay::Flush ( bool  reallocate_cache = true)
inlineoverridevirtual

Push the modifications applied to this cache to its base and wipe local state.

Failure to call this method or Sync() before destruction will cause the changes to be forgotten. If reallocate_cache is false, the cache will retain the same memory footprint after flushing and should be destroyed to deallocate.

Reimplemented from CCoinsViewCache.

Definition at line 727 of file coins.h.

Here is the call graph for this function:

◆ ProcessInput()

bool CoinsViewOverlay::ProcessInput ( )
inlineprivatenoexcept

Claim and fetch the next input in the queue.

Returns
true if an input prevout was fetched
false if there are no more input prevouts in the queue to fetch

Definition at line 653 of file coins.h.

Here is the call graph for this function:

◆ Reset()

void CoinsViewOverlay::Reset ( )
inlineoverrideprotectedvirtualnoexcept

Discard all modifications made to this cache without flushing to the base view.

This can be used to efficiently reuse a cache instance across multiple operations.

Reimplemented from CCoinsViewCache.

Definition at line 708 of file coins.h.

Here is the call graph for this function:

◆ StartFetching()

CCoinsViewCache::ResetGuard CoinsViewOverlay::StartFetching ( const CBlock &block  LIFETIMEBOUND)
noexcept

Start fetching inputs from block.

Definition at line 369 of file coins.cpp.

Here is the call graph for this function:

◆ StopFetching()

void CoinsViewOverlay::StopFetching ( )
inlineprivatenoexcept

Stop all worker threads and clear fetching data.

Calling this is idempotent, and may safely be called if not fetching.

Definition at line 668 of file coins.h.

Here is the caller graph for this function:

Member Data Documentation

◆ m_futures

std::vector<std::future<void> > CoinsViewOverlay::m_futures {}
private

Definition at line 705 of file coins.h.

◆ m_input_head

std::atomic_uint32_t CoinsViewOverlay::m_input_head {0}
private

The latest input not yet being fetched. Workers atomically increment this when fetching.

Definition at line 620 of file coins.h.

◆ m_input_tail

uint32_t CoinsViewOverlay::m_input_tail {0}
mutableprivate

The latest input not yet accessed by a consumer. Only the main thread increments this.

Definition at line 622 of file coins.h.

◆ m_inputs

std::vector<InputToFetch> CoinsViewOverlay::m_inputs {}
private

Must only be mutated when m_futures is empty. Elements may be mutated when m_futures is not empty.

Definition at line 645 of file coins.h.

◆ m_thread_pool

std::shared_ptr<ThreadPool> CoinsViewOverlay::m_thread_pool
private

Non-null. May have zero workers when input fetching is disabled.

Definition at line 704 of file coins.h.


The documentation for this class was generated from the following files: