123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- // Copyright (c) 2009-2010 Satoshi Nakamoto
- // Copyright (c) 2009-2016 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 "primitives/transaction.h"
- #include "compressor.h"
- #include "core_memusage.h"
- #include "hash.h"
- #include "memusage.h"
- #include "serialize.h"
- #include "uint256.h"
-
- #include <assert.h>
- #include <stdint.h>
-
- #include <unordered_map>
-
- /**
- * 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<typename Stream>
- void Serialize(Stream &s) const {
- assert(!IsSpent());
- uint32_t code = nHeight * 2 + fCoinBase;
- ::Serialize(s, VARINT(code));
- ::Serialize(s, CTxOutCompressor(REF(out)));
- }
-
- template<typename Stream>
- void Unserialize(Stream &s) {
- uint32_t code = 0;
- ::Unserialize(s, VARINT(code));
- nHeight = code >> 1;
- fCoinBase = code & 1;
- ::Unserialize(s, REF(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).
- */
- size_t operator()(const COutPoint& id) const {
- 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<COutPoint, CCoinsCacheEntry, SaltedOutpointHasher> 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<uint256> 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<uint256> 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);
-
- // 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:
- CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const;
-
- /**
- * By making the copy constructor private, we prevent accidentally using it when one intends to create a cache on top of a base cache.
- */
- CCoinsViewCache(const CCoinsViewCache &);
- };
-
- //! 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);
-
- #endif // BITCOIN_COINS_H
|