LCOV - code coverage report
Current view: top level - src - coins.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 45 49 91.8 %
Date: 2020-09-26 01:30:44 Functions: 46 54 85.2 %

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

Generated by: LCOV version 1.15