// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2019 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_COINS_H #define BITCOIN_COINS_H #include #include #include #include #include #include #include #include #include #include #include /** * A UTXO entry. * * Serialized format: * - VARINT((coinbase ? 1 : 0) | (height << 1)) * - the non-spent CTxOut (via CTxOutCompressor) */ class Coin { public: //! unspent transaction output CTxOut out; //! whether containing transaction was a coinbase unsigned int fCoinBase : 1; //! at which height this containing transaction was included in the active block chain uint32_t nHeight : 31; //! construct a Coin from a CTxOut and height/coinbase information. Coin(CTxOut&& outIn, int nHeightIn, bool fCoinBaseIn) : out(std::move(outIn)), fCoinBase(fCoinBaseIn), nHeight(nHeightIn) {} Coin(const CTxOut& outIn, int nHeightIn, bool fCoinBaseIn) : out(outIn), fCoinBase(fCoinBaseIn),nHeight(nHeightIn) {} void Clear() { out.SetNull(); fCoinBase = false; nHeight = 0; } //! empty constructor Coin() : fCoinBase(false), nHeight(0) { } bool IsCoinBase() const { return fCoinBase; } template void Serialize(Stream &s) const { assert(!IsSpent()); uint32_t code = nHeight * 2 + fCoinBase; ::Serialize(s, VARINT(code)); ::Serialize(s, CTxOutCompressor(REF(out))); } template void Unserialize(Stream &s) { uint32_t code = 0; ::Unserialize(s, VARINT(code)); nHeight = code >> 1; fCoinBase = code & 1; ::Unserialize(s, CTxOutCompressor(out)); } bool IsSpent() const { return out.IsNull(); } size_t DynamicMemoryUsage() const { return memusage::DynamicUsage(out.scriptPubKey); } }; class SaltedOutpointHasher { private: /** Salt */ const uint64_t k0, k1; public: SaltedOutpointHasher(); /** * This *must* return size_t. With Boost 1.46 on 32-bit systems the * unordered_map will behave unpredictably if the custom hasher returns a * uint64_t, resulting in failures when syncing the chain (#4634). * * Having the hash noexcept allows libstdc++'s unordered_map to recalculate * the hash during rehash, so it does not have to cache the value. This * reduces node's memory by sizeof(size_t). The required recalculation has * a slight performance penalty (around 1.6%), but this is compensated by * memory savings of about 9% which allow for a larger dbcache setting. * * @see https://gcc.gnu.org/onlinedocs/gcc-9.2.0/libstdc++/manual/manual/unordered_associative.html */ size_t operator()(const COutPoint& id) const noexcept { return SipHashUint256Extra(k0, k1, id.hash, id.n); } }; struct CCoinsCacheEntry { Coin coin; // The actual cached data. unsigned char flags; enum Flags { DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view. FRESH = (1 << 1), // The parent view does not have this entry (or it is pruned). /* Note that FRESH is a performance optimization with which we can * erase coins that are fully spent if we know we do not need to * flush the changes to the parent cache. It is always safe to * not mark FRESH if that condition is not guaranteed. */ }; CCoinsCacheEntry() : flags(0) {} explicit CCoinsCacheEntry(Coin&& coin_) : coin(std::move(coin_)), flags(0) {} }; typedef std::unordered_map CCoinsMap; /** Cursor for iterating over CoinsView state */ class CCoinsViewCursor { public: CCoinsViewCursor(const uint256 &hashBlockIn): hashBlock(hashBlockIn) {} virtual ~CCoinsViewCursor() {} virtual bool GetKey(COutPoint &key) const = 0; virtual bool GetValue(Coin &coin) const = 0; virtual unsigned int GetValueSize() const = 0; virtual bool Valid() const = 0; virtual void Next() = 0; //! Get best block at the time this cursor was created const uint256 &GetBestBlock() const { return hashBlock; } private: uint256 hashBlock; }; /** Abstract view on the open txout dataset. */ class CCoinsView { public: /** Retrieve the Coin (unspent transaction output) for a given outpoint. * Returns true only when an unspent coin was found, which is returned in coin. * When false is returned, coin's value is unspecified. */ virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const; //! Just check whether a given outpoint is unspent. virtual bool HaveCoin(const COutPoint &outpoint) const; //! Retrieve the block hash whose state this CCoinsView currently represents virtual uint256 GetBestBlock() const; //! Retrieve the range of blocks that may have been only partially written. //! If the database is in a consistent state, the result is the empty vector. //! Otherwise, a two-element vector is returned consisting of the new and //! the old block hash, in that order. virtual std::vector GetHeadBlocks() const; //! Do a bulk modification (multiple Coin changes + BestBlock change). //! The passed mapCoins can be modified. virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); //! Get a cursor to iterate over the whole state virtual CCoinsViewCursor *Cursor() const; //! As we use CCoinsViews polymorphically, have a virtual destructor virtual ~CCoinsView() {} //! Estimate database size (0 if not implemented) virtual size_t EstimateSize() const { return 0; } }; /** CCoinsView backed by another CCoinsView */ class CCoinsViewBacked : public CCoinsView { protected: CCoinsView *base; public: CCoinsViewBacked(CCoinsView *viewIn); bool GetCoin(const COutPoint &outpoint, Coin &coin) const override; bool HaveCoin(const COutPoint &outpoint) const override; uint256 GetBestBlock() const override; std::vector GetHeadBlocks() const override; void SetBackend(CCoinsView &viewIn); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override; CCoinsViewCursor *Cursor() const override; size_t EstimateSize() const override; }; /** CCoinsView that adds a memory cache for transactions to another CCoinsView */ class CCoinsViewCache : public CCoinsViewBacked { protected: /** * Make mutable so that we can "fill the cache" even from Get-methods * declared as "const". */ mutable uint256 hashBlock; mutable CCoinsMap cacheCoins; /* Cached dynamic memory usage for the inner Coin objects. */ mutable size_t cachedCoinsUsage; public: CCoinsViewCache(CCoinsView *baseIn); /** * By deleting the copy constructor, we prevent accidentally using it when one intends to create a cache on top of a base cache. */ CCoinsViewCache(const CCoinsViewCache &) = delete; // Standard CCoinsView methods bool GetCoin(const COutPoint &outpoint, Coin &coin) const override; bool HaveCoin(const COutPoint &outpoint) const override; uint256 GetBestBlock() const override; void SetBestBlock(const uint256 &hashBlock); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override; CCoinsViewCursor* Cursor() const override { throw std::logic_error("CCoinsViewCache cursor iteration not supported."); } /** * Check if we have the given utxo already loaded in this cache. * The semantics are the same as HaveCoin(), but no calls to * the backing CCoinsView are made. */ bool HaveCoinInCache(const COutPoint &outpoint) const; /** * Return a reference to Coin in the cache, or a pruned one if not found. This is * more efficient than GetCoin. * * Generally, do not hold the reference returned for more than a short scope. * While the current implementation allows for modifications to the contents * of the cache while holding the reference, this behavior should not be relied * on! To be safe, best to not hold the returned reference through any other * calls to this cache. */ const Coin& AccessCoin(const COutPoint &output) const; /** * Add a coin. Set potential_overwrite to true if a non-pruned version may * already exist. */ void AddCoin(const COutPoint& outpoint, Coin&& coin, bool potential_overwrite); /** * Spend a coin. Pass moveto in order to get the deleted data. * If no unspent output exists for the passed outpoint, this call * has no effect. */ bool SpendCoin(const COutPoint &outpoint, Coin* moveto = nullptr); /** * Push the modifications applied to this cache to its base. * Failure to call this method before destruction will cause the changes to be forgotten. * If false is returned, the state of this cache (and its backing view) will be undefined. */ bool Flush(); /** * Removes the UTXO with the given outpoint from the cache, if it is * not modified. */ void Uncache(const COutPoint &outpoint); //! Calculate the size of the cache (in number of transaction outputs) unsigned int GetCacheSize() const; //! Calculate the size of the cache (in bytes) size_t DynamicMemoryUsage() const; /** * Amount of bitcoins coming in to a transaction * Note that lightweight clients may not know anything besides the hash of previous transactions, * so may not be able to calculate this. * * @param[in] tx transaction for which we are checking input total * @return Sum of value of all inputs (scriptSigs) */ CAmount GetValueIn(const CTransaction& tx) const; //! Check whether all prevouts of the transaction are present in the UTXO set represented by this view bool HaveInputs(const CTransaction& tx) const; private: /** * @note this is marked const, but may actually append to `cacheCoins`, increasing * memory usage. */ CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const; }; //! Utility function to add all of a transaction's outputs to a cache. //! When check is false, this assumes that overwrites are only possible for coinbase transactions. //! When check is true, the underlying view may be queried to determine whether an addition is //! an overwrite. // TODO: pass in a boolean to limit these possible overwrites to known // (pre-BIP34) cases. void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight, bool check = false); //! Utility function to find any unspent output with a given txid. //! This function can be quite expensive because in the event of a transaction //! which is not found in the cache, it can cause up to MAX_OUTPUTS_PER_BLOCK //! lookups to database, so it should be used with care. const Coin& AccessByTxid(const CCoinsViewCache& cache, const uint256& txid); /** * This is a minimally invasive approach to shutdown on LevelDB read errors from the * chainstate, while keeping user interface out of the common library, which is shared * between bitcoind, and bitcoin-qt and non-server tools. * * Writes do not need similar protection, as failure to write is handled by the caller. */ class CCoinsViewErrorCatcher final : public CCoinsViewBacked { public: explicit CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {} void AddReadErrCallback(std::function f) { m_err_callbacks.emplace_back(std::move(f)); } bool GetCoin(const COutPoint &outpoint, Coin &coin) const override; private: /** A list of callbacks to execute upon leveldb read error. */ std::vector> m_err_callbacks; }; #endif // BITCOIN_COINS_H