Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
502/**503* Return a reference to Coin in the cache, or coinEmpty if not found. This is504* more efficient than GetCoin.505*506* Generally, do not hold the reference returned for more than a short scope.507* While the current implementation allows for modifications to the contents508* of the cache while holding the reference, this behavior should not be relied509* on! To be safe, best to not hold the returned reference through any other510* calls to this cache.511*/512const Coin& AccessCoin(const COutPoint &output) const;514/**515* Add a coin. Set possible_overwrite to true if an unspent version may516* already exist in the cache.517*/518void AddCoin(const COutPoint& outpoint, Coin&& coin, bool possible_overwrite);520/**521* Emplace a coin into cacheCoins without performing any checks, marking522* the emplaced coin as dirty.523*524* NOT FOR GENERAL USE. Used only when loading coins from a UTXO snapshot.525* @sa ChainstateManager::PopulateAndValidateSnapshot()526*/527void EmplaceCoinInternalDANGER(const COutPoint& outpoint, Coin&& coin);529/**530* Spend a coin. Pass moveto in order to get the deleted data.531* If no unspent output exists for the passed outpoint, this call532* has no effect.533*/534bool SpendCoin(const COutPoint &outpoint, Coin* moveto = nullptr);536/**537* Push the modifications applied to this cache to its base and wipe local state.538* Failure to call this method or Sync() before destruction will cause the changes539* to be forgotten.540* If reallocate_cache is false, the cache will retain the same memory footprint541* after flushing and should be destroyed to deallocate.542*/543virtual void Flush(bool reallocate_cache = true);545/**546* Push the modifications applied to this cache to its base while retaining547* the contents of this cache (except for spent coins, which we erase).548* Failure to call this method or Flush() before destruction will cause the changes549* to be forgotten.550*/551void Sync();553/**554* Removes the UTXO with the given outpoint from the cache, if it is555* not modified.556*/557void Uncache(const COutPoint &outpoint);559//! Size of the cache (in number of transaction outputs)560unsigned int GetCacheSize() const;562//! Number of dirty cache entries (transaction outputs)563size_t GetDirtyCount() const noexcept { return m_dirty_count; }565//! Calculate the size of the cache (in bytes)566size_t DynamicMemoryUsage() const;568//! Check whether all prevouts of the transaction are present in the UTXO set represented by this view569bool HaveInputs(const CTransaction& tx) const;571//! Run an internal sanity check on the cache data structure. */572void SanityCheck() const;574class ResetGuard575{576private:577friend CCoinsViewCache;578CCoinsViewCache& m_cache;579explicit ResetGuard(CCoinsViewCache& cache LIFETIMEBOUND) noexcept : m_cache{cache} {}581public:582ResetGuard(const ResetGuard&) = delete;583ResetGuard& operator=(const ResetGuard&) = delete;584ResetGuard(ResetGuard&&) = delete;585ResetGuard& operator=(ResetGuard&&) = delete;587~ResetGuard() { m_cache.Reset(); }588};590//! Create a scoped guard that will call `Reset()` on this cache when it goes out of scope.591[[nodiscard]] ResetGuard CreateResetGuard() noexcept { return ResetGuard{*this}; }592};594/**595* CCoinsViewCache subclass that asynchronously fetches most block input prevouts in parallel during ConnectBlock596* without mutating the base cache. This is achieved by fetching coins from the base view using PeekCoin() instead of597* GetCoin(), so intermediate CCoinsViewCache layers are not filled.598*599* Used during ConnectBlock() as an ephemeral, resettable top-level view that is flushed only on success, so invalid600* blocks don't pollute the underlying cache.601*602* While this class uses threads internally to fetch coins, externally it is only safe to call its methods from a603* single "main" thread. It assumes StartFetching, StopFetching, FetchCoinFromBase, Flush and Reset will all only be604* called from the main thread.605*606* When a block is passed to StartFetching, the inputs of the block are flattened into a vector of InputToFetch607* objects. StartFetching then submits worker tasks to a ThreadPool and keeps the returned futures alive until fetching608* is stopped.609*610* ProcessInput() atomically fetches and increments m_input_head, so each thread can only access a single element of the611* m_inputs vector at a time. Workers race to claim inputs, so they may fetch elements in any order. If the fetched612* index is greater than or equal to the size of m_inputs, no more inputs can be fetched and false is returned.613*614* The worker claims the InputToFetch at this index, fetches the coin with base->PeekCoin() and moves it into the615* InputToFetch object. The ready flag is then set with a release memory order. This allows the ready flag to be616* used as a memory fence, guaranteeing the coin being written to the object will have happened before another617* thread tests the flag with an acquire memory order.618* This assumes all base->PeekCoin() paths are safe for concurrent readers.619*620* The main thread is the only consumer of the fetched coins. FetchCoinFromBase is called when a coin is requested on621* the main thread and is not already in the cache. It checks whether the next unconsumed entry in m_inputs has the622* requested outpoint. On a match, m_input_tail is advanced and the entry's ready flag is waited on with an acquire623* memory order until a worker has finished fetching it. The coin is then moved out and returned.624*625* StopFetching() is called in Flush() and in Reset() (the per-block teardown) so workers stop before the block they626* reference goes away. It stops fetching by moving m_input_head to the end of m_inputs (so workers quickly exit),627* then waits for all futures to complete and clears the per-block state (m_inputs and the head/tail counters).628*629* Workers advance m_input_head to fetch inputs. Main thread advances m_input_tail to consume.630*631* Before workers start:632*633* m_input_head634* m_input_tail635* │636* ▼637* ┌─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐638* m_inputs: │ waiting │ waiting │ waiting │ waiting │ waiting │ waiting │ waiting │ waiting │ waiting │639* │ │ │ │ │ │ │ │ │ │640* └─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘641*642* After workers start:643*644* Worker 2 Worker 0 Worker 3 Worker 1 m_input_head645* │ │ │ │ │646* ▼ ▼ ▼ ▼ ▼647* ┌─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐648* m_inputs: │ ready │ ready │fetching │ ready │fetching │fetching │fetching │ waiting │ waiting │649* │consumed │ ✓ │ ● │ ✓ │ ● │ ● │ ● │ │ │650* └─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘651* ▲652* │653* m_input_tail654*/655class CoinsViewOverlay : public CCoinsViewCache656{657private:658//! The latest input not yet being fetched. Workers atomically increment this when fetching.659std::atomic_uint32_t m_input_head{0};660//! The latest input not yet accessed by a consumer. Only the main thread increments this.661mutable uint32_t m_input_tail{0};663//! The inputs of the block which is being fetched.664struct InputToFetch {665//! Workers set this after setting the coin. The main thread tests this before reading the coin.666std::atomic_flag ready{};667//! The outpoint of the input to fetch.668const COutPoint& outpoint;669//! The coin that workers will fetch and main thread will insert into cache.670//! Mutable so it can be moved in FetchCoinFromBase.671mutable std::optional<Coin> coin{std::nullopt};673explicit InputToFetch(const COutPoint& o LIFETIMEBOUND) noexcept : outpoint{o} {}675//! Move ctor is required for resizing m_inputs in StartFetching. Elements will never move once parallel tasks676//! are started, so we can assert that coin is nullopt and ready is false.677InputToFetch(InputToFetch&& other) noexcept : outpoint{other.outpoint}678{679Assert(!other.coin);680Assert(!other.ready.test(std::memory_order_relaxed));681}682};683//! Must only be mutated when m_futures is empty. Elements may be mutated when m_futures is not empty.684std::vector<InputToFetch> m_inputs{};686/**687* Claim and fetch the next input in the queue.688*689* @return true if an input prevout was fetched690* @return false if there are no more input prevouts in the queue to fetch691*/692bool ProcessInput() noexcept693{694const auto i{m_input_head.fetch_add(1, std::memory_order_relaxed)};695if (i >= m_inputs.size()) return false;697auto& input{m_inputs[i]};698input.coin = base->PeekCoin(input.outpoint);699// Use release so writing coin above happens before the main thread acquires.700Assert(!input.ready.test_and_set(std::memory_order_release));701input.ready.notify_one();702return true;703}705//! Stop all worker threads and clear fetching data.706//! Calling this is idempotent, and may safely be called if not fetching.707void StopFetching() noexcept708{709if (m_futures.empty()) {710Assert(m_inputs.empty());711Assert(m_input_head.load(std::memory_order_relaxed) == 0);712Assert(m_input_tail == 0);713return;714}715// Skip fetching the rest of the inputs by moving the head to the end.716m_input_head.store(m_inputs.size(), std::memory_order_relaxed);717// Wait for all threads to stop.718for (auto& future : m_futures) future.wait();719m_futures.clear();720m_inputs.clear();721m_input_head.store(0, std::memory_order_relaxed);722m_input_tail = 0;723}725std::optional<Coin> FetchCoinFromBase(const COutPoint& outpoint) const override726{727// This assumes ConnectBlock accesses all inputs in the same order as728// they are added to m_inputs in StartFetching.729if (m_input_tail < m_inputs.size() && m_inputs[m_input_tail].outpoint == outpoint) {730// We advance the tail since the input is cached and not accessed through this method again.731auto& input{m_inputs[m_input_tail++]};732// Wait until the coin is ready to be read. We need acquire so we match the worker thread's release.733input.ready.wait(/*old=*/false, std::memory_order_acquire);734// We can move the coin since we won't access this input again.735return std::move(input.coin);736}738// We will only get here for BIP30 checks, an invalid block, or if the threadpool has not been started.739return base->PeekCoin(outpoint);740}742//! Non-null. May have zero workers when input fetching is disabled.743std::shared_ptr<ThreadPool> m_thread_pool;744std::vector<std::future<void>> m_futures{};746protected:747//! StopFetching must be called here for two reasons: InputToFetch objects hold references to the748//! block's outpoints, so they must not outlive the block being connected; and when connecting a749//! block fails, workers must not keep fetching inputs for the block that was abandoned.750void Reset() noexcept override