LCOV - code coverage report
Current view: top level - src - coins.h (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 17 40 42.5 %
Date: 2023-09-26 12:08:55 Functions: 20 39 51.3 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2022 The Bitcoin Core developers
       3             : // Distributed under the MIT software license, see the accompanying
       4             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #ifndef BITCOIN_COINS_H
       7             : #define BITCOIN_COINS_H
       8             : 
       9             : #include <compressor.h>
      10             : #include <core_memusage.h>
      11             : #include <memusage.h>
      12             : #include <primitives/transaction.h>
      13             : #include <serialize.h>
      14             : #include <support/allocators/pool.h>
      15             : #include <uint256.h>
      16             : #include <util/hasher.h>
      17             : 
      18             : #include <assert.h>
      19             : #include <stdint.h>
      20             : 
      21             : #include <functional>
      22             : #include <unordered_map>
      23             : 
      24             : /**
      25             :  * A UTXO entry.
      26             :  *
      27             :  * Serialized format:
      28             :  * - VARINT((coinbase ? 1 : 0) | (height << 1))
      29             :  * - the non-spent CTxOut (via TxOutCompression)
      30             :  */
      31             : class Coin
      32             : {
      33             : public:
      34             :     //! unspent transaction output
      35             :     CTxOut out;
      36             : 
      37             :     //! whether containing transaction was a coinbase
      38             :     unsigned int fCoinBase : 1;
      39             : 
      40             :     //! at which height this containing transaction was included in the active block chain
      41             :     uint32_t nHeight : 31;
      42             : 
      43             :     //! construct a Coin from a CTxOut and height/coinbase information.
      44             :     Coin(CTxOut&& outIn, int nHeightIn, bool fCoinBaseIn) : out(std::move(outIn)), fCoinBase(fCoinBaseIn), nHeight(nHeightIn) {}
      45       89676 :     Coin(const CTxOut& outIn, int nHeightIn, bool fCoinBaseIn) : out(outIn), fCoinBase(fCoinBaseIn),nHeight(nHeightIn) {}
      46             : 
      47        4665 :     void Clear() {
      48        4665 :         out.SetNull();
      49        4665 :         fCoinBase = false;
      50        4665 :         nHeight = 0;
      51        4665 :     }
      52             : 
      53             :     //! empty constructor
      54      241538 :     Coin() : fCoinBase(false), nHeight(0) { }
      55             : 
      56       41948 :     bool IsCoinBase() const {
      57       41948 :         return fCoinBase;
      58             :     }
      59             : 
      60             :     template<typename Stream>
      61           0 :     void Serialize(Stream &s) const {
      62           0 :         assert(!IsSpent());
      63           0 :         uint32_t code = nHeight * uint32_t{2} + fCoinBase;
      64           0 :         ::Serialize(s, VARINT(code));
      65           0 :         ::Serialize(s, Using<TxOutCompression>(out));
      66           0 :     }
      67             : 
      68             :     template<typename Stream>
      69           0 :     void Unserialize(Stream &s) {
      70           0 :         uint32_t code = 0;
      71           0 :         ::Unserialize(s, VARINT(code));
      72           0 :         nHeight = code >> 1;
      73           0 :         fCoinBase = code & 1;
      74           0 :         ::Unserialize(s, Using<TxOutCompression>(out));
      75           0 :     }
      76             : 
      77             :     /** Either this coin never existed (see e.g. coinEmpty in coins.cpp), or it
      78             :       * did exist and has been spent.
      79             :       */
      80      551922 :     bool IsSpent() const {
      81      551922 :         return out.IsNull();
      82             :     }
      83             : 
      84      147995 :     size_t DynamicMemoryUsage() const {
      85      147995 :         return memusage::DynamicUsage(out.scriptPubKey);
      86             :     }
      87             : };
      88             : 
      89             : /**
      90             :  * A Coin in one level of the coins database caching hierarchy.
      91             :  *
      92             :  * A coin can either be:
      93             :  * - unspent or spent (in which case the Coin object will be nulled out - see Coin.Clear())
      94             :  * - DIRTY or not DIRTY
      95             :  * - FRESH or not FRESH
      96             :  *
      97             :  * Out of these 2^3 = 8 states, only some combinations are valid:
      98             :  * - unspent, FRESH, DIRTY (e.g. a new coin created in the cache)
      99             :  * - unspent, not FRESH, DIRTY (e.g. a coin changed in the cache during a reorg)
     100             :  * - unspent, not FRESH, not DIRTY (e.g. an unspent coin fetched from the parent cache)
     101             :  * - spent, FRESH, not DIRTY (e.g. a spent coin fetched from the parent cache)
     102             :  * - spent, not FRESH, DIRTY (e.g. a coin is spent and spentness needs to be flushed to the parent)
     103             :  */
     104             : struct CCoinsCacheEntry
     105             : {
     106             :     Coin coin; // The actual cached data.
     107             :     unsigned char flags;
     108             : 
     109             :     enum Flags {
     110             :         /**
     111             :          * DIRTY means the CCoinsCacheEntry is potentially different from the
     112             :          * version in the parent cache. Failure to mark a coin as DIRTY when
     113             :          * it is potentially different from the parent cache will cause a
     114             :          * consensus failure, since the coin's state won't get written to the
     115             :          * parent when the cache is flushed.
     116             :          */
     117             :         DIRTY = (1 << 0),
     118             :         /**
     119             :          * FRESH means the parent cache does not have this coin or that it is a
     120             :          * spent coin in the parent cache. If a FRESH coin in the cache is
     121             :          * later spent, it can be deleted entirely and doesn't ever need to be
     122             :          * flushed to the parent. This is a performance optimization. Marking a
     123             :          * coin as FRESH when it exists unspent in the parent cache will cause a
     124             :          * consensus failure, since it might not be deleted from the parent
     125             :          * when this cache is flushed.
     126             :          */
     127             :         FRESH = (1 << 1),
     128             :     };
     129             : 
     130       44458 :     CCoinsCacheEntry() : flags(0) {}
     131       80225 :     explicit CCoinsCacheEntry(Coin&& coin_) : coin(std::move(coin_)), flags(0) {}
     132           0 :     CCoinsCacheEntry(Coin&& coin_, unsigned char flag) : coin(std::move(coin_)), flags(flag) {}
     133             : };
     134             : 
     135             : /**
     136             :  * PoolAllocator's MAX_BLOCK_SIZE_BYTES parameter here uses sizeof the data, and adds the size
     137             :  * of 4 pointers. We do not know the exact node size used in the std::unordered_node implementation
     138             :  * because it is implementation defined. Most implementations have an overhead of 1 or 2 pointers,
     139             :  * so nodes can be connected in a linked list, and in some cases the hash value is stored as well.
     140             :  * Using an additional sizeof(void*)*4 for MAX_BLOCK_SIZE_BYTES should thus be sufficient so that
     141             :  * all implementations can allocate the nodes from the PoolAllocator.
     142             :  */
     143             : using CCoinsMap = std::unordered_map<COutPoint,
     144             :                                      CCoinsCacheEntry,
     145             :                                      SaltedOutpointHasher,
     146             :                                      std::equal_to<COutPoint>,
     147             :                                      PoolAllocator<std::pair<const COutPoint, CCoinsCacheEntry>,
     148             :                                                    sizeof(std::pair<const COutPoint, CCoinsCacheEntry>) + sizeof(void*) * 4,
     149             :                                                    alignof(void*)>>;
     150             : 
     151             : using CCoinsMapMemoryResource = CCoinsMap::allocator_type::ResourceType;
     152             : 
     153             : /** Cursor for iterating over CoinsView state */
     154             : class CCoinsViewCursor
     155             : {
     156             : public:
     157           0 :     CCoinsViewCursor(const uint256 &hashBlockIn): hashBlock(hashBlockIn) {}
     158           0 :     virtual ~CCoinsViewCursor() {}
     159             : 
     160             :     virtual bool GetKey(COutPoint &key) const = 0;
     161             :     virtual bool GetValue(Coin &coin) const = 0;
     162             : 
     163             :     virtual bool Valid() const = 0;
     164             :     virtual void Next() = 0;
     165             : 
     166             :     //! Get best block at the time this cursor was created
     167             :     const uint256 &GetBestBlock() const { return hashBlock; }
     168             : private:
     169             :     uint256 hashBlock;
     170             : };
     171             : 
     172             : /** Abstract view on the open txout dataset. */
     173             : class CCoinsView
     174             : {
     175             : public:
     176             :     /** Retrieve the Coin (unspent transaction output) for a given outpoint.
     177             :      *  Returns true only when an unspent coin was found, which is returned in coin.
     178             :      *  When false is returned, coin's value is unspecified.
     179             :      */
     180             :     virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const;
     181             : 
     182             :     //! Just check whether a given outpoint is unspent.
     183             :     virtual bool HaveCoin(const COutPoint &outpoint) const;
     184             : 
     185             :     //! Retrieve the block hash whose state this CCoinsView currently represents
     186             :     virtual uint256 GetBestBlock() const;
     187             : 
     188             :     //! Retrieve the range of blocks that may have been only partially written.
     189             :     //! If the database is in a consistent state, the result is the empty vector.
     190             :     //! Otherwise, a two-element vector is returned consisting of the new and
     191             :     //! the old block hash, in that order.
     192             :     virtual std::vector<uint256> GetHeadBlocks() const;
     193             : 
     194             :     //! Do a bulk modification (multiple Coin changes + BestBlock change).
     195             :     //! The passed mapCoins can be modified.
     196             :     virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, bool erase = true);
     197             : 
     198             :     //! Get a cursor to iterate over the whole state
     199             :     virtual std::unique_ptr<CCoinsViewCursor> Cursor() const;
     200             : 
     201             :     //! As we use CCoinsViews polymorphically, have a virtual destructor
     202       57924 :     virtual ~CCoinsView() {}
     203             : 
     204             :     //! Estimate database size (0 if not implemented)
     205           0 :     virtual size_t EstimateSize() const { return 0; }
     206             : };
     207             : 
     208             : 
     209             : /** CCoinsView backed by another CCoinsView */
     210             : class CCoinsViewBacked : public CCoinsView
     211             : {
     212             : protected:
     213             :     CCoinsView *base;
     214             : 
     215             : public:
     216             :     CCoinsViewBacked(CCoinsView *viewIn);
     217             :     bool GetCoin(const COutPoint &outpoint, Coin &coin) const override;
     218             :     bool HaveCoin(const COutPoint &outpoint) const override;
     219             :     uint256 GetBestBlock() const override;
     220             :     std::vector<uint256> GetHeadBlocks() const override;
     221             :     void SetBackend(CCoinsView &viewIn);
     222             :     bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, bool erase = true) override;
     223             :     std::unique_ptr<CCoinsViewCursor> Cursor() const override;
     224             :     size_t EstimateSize() const override;
     225             : };
     226             : 
     227             : 
     228             : /** CCoinsView that adds a memory cache for transactions to another CCoinsView */
     229             : class CCoinsViewCache : public CCoinsViewBacked
     230             : {
     231             : private:
     232             :     const bool m_deterministic;
     233             : 
     234             : protected:
     235             :     /**
     236             :      * Make mutable so that we can "fill the cache" even from Get-methods
     237             :      * declared as "const".
     238             :      */
     239             :     mutable uint256 hashBlock;
     240             :     mutable CCoinsMapMemoryResource m_cache_coins_memory_resource{};
     241             :     mutable CCoinsMap cacheCoins;
     242             : 
     243             :     /* Cached dynamic memory usage for the inner Coin objects. */
     244             :     mutable size_t cachedCoinsUsage{0};
     245             : 
     246             : public:
     247             :     CCoinsViewCache(CCoinsView *baseIn, bool deterministic = false);
     248             : 
     249             :     /**
     250             :      * By deleting the copy constructor, we prevent accidentally using it when one intends to create a cache on top of a base cache.
     251             :      */
     252             :     CCoinsViewCache(const CCoinsViewCache &) = delete;
     253             : 
     254             :     // Standard CCoinsView methods
     255             :     bool GetCoin(const COutPoint &outpoint, Coin &coin) const override;
     256             :     bool HaveCoin(const COutPoint &outpoint) const override;
     257             :     uint256 GetBestBlock() const override;
     258             :     void SetBestBlock(const uint256 &hashBlock);
     259             :     bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, bool erase = true) override;
     260           0 :     std::unique_ptr<CCoinsViewCursor> Cursor() const override {
     261           0 :         throw std::logic_error("CCoinsViewCache cursor iteration not supported.");
     262           0 :     }
     263             : 
     264             :     /**
     265             :      * Check if we have the given utxo already loaded in this cache.
     266             :      * The semantics are the same as HaveCoin(), but no calls to
     267             :      * the backing CCoinsView are made.
     268             :      */
     269             :     bool HaveCoinInCache(const COutPoint &outpoint) const;
     270             : 
     271             :     /**
     272             :      * Return a reference to Coin in the cache, or coinEmpty if not found. This is
     273             :      * more efficient than GetCoin.
     274             :      *
     275             :      * Generally, do not hold the reference returned for more than a short scope.
     276             :      * While the current implementation allows for modifications to the contents
     277             :      * of the cache while holding the reference, this behavior should not be relied
     278             :      * on! To be safe, best to not hold the returned reference through any other
     279             :      * calls to this cache.
     280             :      */
     281             :     const Coin& AccessCoin(const COutPoint &output) const;
     282             : 
     283             :     /**
     284             :      * Add a coin. Set possible_overwrite to true if an unspent version may
     285             :      * already exist in the cache.
     286             :      */
     287             :     void AddCoin(const COutPoint& outpoint, Coin&& coin, bool possible_overwrite);
     288             : 
     289             :     /**
     290             :      * Emplace a coin into cacheCoins without performing any checks, marking
     291             :      * the emplaced coin as dirty.
     292             :      *
     293             :      * NOT FOR GENERAL USE. Used only when loading coins from a UTXO snapshot.
     294             :      * @sa ChainstateManager::PopulateAndValidateSnapshot()
     295             :      */
     296             :     void EmplaceCoinInternalDANGER(COutPoint&& outpoint, Coin&& coin);
     297             : 
     298             :     /**
     299             :      * Spend a coin. Pass moveto in order to get the deleted data.
     300             :      * If no unspent output exists for the passed outpoint, this call
     301             :      * has no effect.
     302             :      */
     303             :     bool SpendCoin(const COutPoint &outpoint, Coin* moveto = nullptr);
     304             : 
     305             :     /**
     306             :      * Push the modifications applied to this cache to its base and wipe local state.
     307             :      * Failure to call this method or Sync() before destruction will cause the changes
     308             :      * to be forgotten.
     309             :      * If false is returned, the state of this cache (and its backing view) will be undefined.
     310             :      */
     311             :     bool Flush();
     312             : 
     313             :     /**
     314             :      * Push the modifications applied to this cache to its base while retaining
     315             :      * the contents of this cache (except for spent coins, which we erase).
     316             :      * Failure to call this method or Flush() before destruction will cause the changes
     317             :      * to be forgotten.
     318             :      * If false is returned, the state of this cache (and its backing view) will be undefined.
     319             :      */
     320             :     bool Sync();
     321             : 
     322             :     /**
     323             :      * Removes the UTXO with the given outpoint from the cache, if it is
     324             :      * not modified.
     325             :      */
     326             :     void Uncache(const COutPoint &outpoint);
     327             : 
     328             :     //! Calculate the size of the cache (in number of transaction outputs)
     329             :     unsigned int GetCacheSize() const;
     330             : 
     331             :     //! Calculate the size of the cache (in bytes)
     332             :     size_t DynamicMemoryUsage() const;
     333             : 
     334             :     //! Check whether all prevouts of the transaction are present in the UTXO set represented by this view
     335             :     bool HaveInputs(const CTransaction& tx) const;
     336             : 
     337             :     //! Force a reallocation of the cache map. This is required when downsizing
     338             :     //! the cache because the map's allocator may be hanging onto a lot of
     339             :     //! memory despite having called .clear().
     340             :     //!
     341             :     //! See: https://stackoverflow.com/questions/42114044/how-to-release-unordered-map-memory
     342             :     void ReallocateCache();
     343             : 
     344             :     //! Run an internal sanity check on the cache data structure. */
     345             :     void SanityCheck() const;
     346             : 
     347             : private:
     348             :     /**
     349             :      * @note this is marked const, but may actually append to `cacheCoins`, increasing
     350             :      * memory usage.
     351             :      */
     352             :     CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const;
     353             : };
     354             : 
     355             : //! Utility function to add all of a transaction's outputs to a cache.
     356             : //! When check is false, this assumes that overwrites are only possible for coinbase transactions.
     357             : //! When check is true, the underlying view may be queried to determine whether an addition is
     358             : //! an overwrite.
     359             : // TODO: pass in a boolean to limit these possible overwrites to known
     360             : // (pre-BIP34) cases.
     361             : void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight, bool check = false);
     362             : 
     363             : //! Utility function to find any unspent output with a given txid.
     364             : //! This function can be quite expensive because in the event of a transaction
     365             : //! which is not found in the cache, it can cause up to MAX_OUTPUTS_PER_BLOCK
     366             : //! lookups to database, so it should be used with care.
     367             : const Coin& AccessByTxid(const CCoinsViewCache& cache, const uint256& txid);
     368             : 
     369             : /**
     370             :  * This is a minimally invasive approach to shutdown on LevelDB read errors from the
     371             :  * chainstate, while keeping user interface out of the common library, which is shared
     372             :  * between bitcoind, and bitcoin-qt and non-server tools.
     373             :  *
     374             :  * Writes do not need similar protection, as failure to write is handled by the caller.
     375             : */
     376             : class CCoinsViewErrorCatcher final : public CCoinsViewBacked
     377             : {
     378             : public:
     379           1 :     explicit CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {}
     380             : 
     381           0 :     void AddReadErrCallback(std::function<void()> f) {
     382           0 :         m_err_callbacks.emplace_back(std::move(f));
     383           0 :     }
     384             : 
     385             :     bool GetCoin(const COutPoint &outpoint, Coin &coin) const override;
     386             : 
     387             : private:
     388             :     /** A list of callbacks to execute upon leveldb read error. */
     389             :     std::vector<std::function<void()>> m_err_callbacks;
     390             : 
     391             : };
     392             : 
     393             : #endif // BITCOIN_COINS_H

Generated by: LCOV version 1.14