You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

coins.h 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. // Copyright (c) 2009-2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2016 The Starwels developers
  3. // Distributed under the MIT software license, see the accompanying
  4. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5. #ifndef STARWELS_COINS_H
  6. #define STARWELS_COINS_H
  7. #include "primitives/transaction.h"
  8. #include "compressor.h"
  9. #include "core_memusage.h"
  10. #include "hash.h"
  11. #include "memusage.h"
  12. #include "serialize.h"
  13. #include "uint256.h"
  14. #include <assert.h>
  15. #include <stdint.h>
  16. #include <unordered_map>
  17. /**
  18. * A UTXO entry.
  19. *
  20. * Serialized format:
  21. * - VARINT((coinbase ? 1 : 0) | (height << 1))
  22. * - the non-spent CTxOut (via CTxOutCompressor)
  23. */
  24. class Coin
  25. {
  26. public:
  27. //! unspent transaction output
  28. CTxOut out;
  29. //! whether containing transaction was a coinbase
  30. unsigned int fCoinBase : 1;
  31. //! at which height this containing transaction was included in the active block chain
  32. uint32_t nHeight : 31;
  33. //! construct a Coin from a CTxOut and height/coinbase information.
  34. Coin(CTxOut&& outIn, int nHeightIn, bool fCoinBaseIn) : out(std::move(outIn)), fCoinBase(fCoinBaseIn), nHeight(nHeightIn) {}
  35. Coin(const CTxOut& outIn, int nHeightIn, bool fCoinBaseIn) : out(outIn), fCoinBase(fCoinBaseIn),nHeight(nHeightIn) {}
  36. void Clear() {
  37. out.SetNull();
  38. fCoinBase = false;
  39. nHeight = 0;
  40. }
  41. //! empty constructor
  42. Coin() : fCoinBase(false), nHeight(0) { }
  43. bool IsCoinBase() const {
  44. return fCoinBase;
  45. }
  46. template<typename Stream>
  47. void Serialize(Stream &s) const {
  48. assert(!IsSpent());
  49. uint32_t code = nHeight * 2 + fCoinBase;
  50. ::Serialize(s, VARINT(code));
  51. ::Serialize(s, CTxOutCompressor(REF(out)));
  52. }
  53. template<typename Stream>
  54. void Unserialize(Stream &s) {
  55. uint32_t code = 0;
  56. ::Unserialize(s, VARINT(code));
  57. nHeight = code >> 1;
  58. fCoinBase = code & 1;
  59. ::Unserialize(s, REF(CTxOutCompressor(out)));
  60. }
  61. bool IsSpent() const {
  62. return out.IsNull();
  63. }
  64. size_t DynamicMemoryUsage() const {
  65. return memusage::DynamicUsage(out.scriptPubKey);
  66. }
  67. };
  68. class SaltedOutpointHasher
  69. {
  70. private:
  71. /** Salt */
  72. const uint64_t k0, k1;
  73. public:
  74. SaltedOutpointHasher();
  75. /**
  76. * This *must* return size_t. With Boost 1.46 on 32-bit systems the
  77. * unordered_map will behave unpredictably if the custom hasher returns a
  78. * uint64_t, resulting in failures when syncing the chain (#4634).
  79. */
  80. size_t operator()(const COutPoint& id) const {
  81. return SipHashUint256Extra(k0, k1, id.hash, id.n);
  82. }
  83. };
  84. struct CCoinsCacheEntry
  85. {
  86. Coin coin; // The actual cached data.
  87. unsigned char flags;
  88. enum Flags {
  89. DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view.
  90. FRESH = (1 << 1), // The parent view does not have this entry (or it is pruned).
  91. /* Note that FRESH is a performance optimization with which we can
  92. * erase coins that are fully spent if we know we do not need to
  93. * flush the changes to the parent cache. It is always safe to
  94. * not mark FRESH if that condition is not guaranteed.
  95. */
  96. };
  97. CCoinsCacheEntry() : flags(0) {}
  98. explicit CCoinsCacheEntry(Coin&& coin_) : coin(std::move(coin_)), flags(0) {}
  99. };
  100. typedef std::unordered_map<COutPoint, CCoinsCacheEntry, SaltedOutpointHasher> CCoinsMap;
  101. /** Cursor for iterating over CoinsView state */
  102. class CCoinsViewCursor
  103. {
  104. public:
  105. CCoinsViewCursor(const uint256 &hashBlockIn): hashBlock(hashBlockIn) {}
  106. virtual ~CCoinsViewCursor() {}
  107. virtual bool GetKey(COutPoint &key) const = 0;
  108. virtual bool GetValue(Coin &coin) const = 0;
  109. virtual unsigned int GetValueSize() const = 0;
  110. virtual bool Valid() const = 0;
  111. virtual void Next() = 0;
  112. //! Get best block at the time this cursor was created
  113. const uint256 &GetBestBlock() const { return hashBlock; }
  114. private:
  115. uint256 hashBlock;
  116. };
  117. /** Abstract view on the open txout dataset. */
  118. class CCoinsView
  119. {
  120. public:
  121. /** Retrieve the Coin (unspent transaction output) for a given outpoint.
  122. * Returns true only when an unspent coin was found, which is returned in coin.
  123. * When false is returned, coin's value is unspecified.
  124. */
  125. virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const;
  126. //! Just check whether a given outpoint is unspent.
  127. virtual bool HaveCoin(const COutPoint &outpoint) const;
  128. //! Retrieve the block hash whose state this CCoinsView currently represents
  129. virtual uint256 GetBestBlock() const;
  130. //! Retrieve the range of blocks that may have been only partially written.
  131. //! If the database is in a consistent state, the result is the empty vector.
  132. //! Otherwise, a two-element vector is returned consisting of the new and
  133. //! the old block hash, in that order.
  134. virtual std::vector<uint256> GetHeadBlocks() const;
  135. //! Do a bulk modification (multiple Coin changes + BestBlock change).
  136. //! The passed mapCoins can be modified.
  137. virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
  138. //! Get a cursor to iterate over the whole state
  139. virtual CCoinsViewCursor *Cursor() const;
  140. //! As we use CCoinsViews polymorphically, have a virtual destructor
  141. virtual ~CCoinsView() {}
  142. //! Estimate database size (0 if not implemented)
  143. virtual size_t EstimateSize() const { return 0; }
  144. };
  145. /** CCoinsView backed by another CCoinsView */
  146. class CCoinsViewBacked : public CCoinsView
  147. {
  148. protected:
  149. CCoinsView *base;
  150. public:
  151. CCoinsViewBacked(CCoinsView *viewIn);
  152. bool GetCoin(const COutPoint &outpoint, Coin &coin) const override;
  153. bool HaveCoin(const COutPoint &outpoint) const override;
  154. uint256 GetBestBlock() const override;
  155. std::vector<uint256> GetHeadBlocks() const override;
  156. void SetBackend(CCoinsView &viewIn);
  157. bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override;
  158. CCoinsViewCursor *Cursor() const override;
  159. size_t EstimateSize() const override;
  160. };
  161. /** CCoinsView that adds a memory cache for transactions to another CCoinsView */
  162. class CCoinsViewCache : public CCoinsViewBacked
  163. {
  164. protected:
  165. /**
  166. * Make mutable so that we can "fill the cache" even from Get-methods
  167. * declared as "const".
  168. */
  169. mutable uint256 hashBlock;
  170. mutable CCoinsMap cacheCoins;
  171. /* Cached dynamic memory usage for the inner Coin objects. */
  172. mutable size_t cachedCoinsUsage;
  173. public:
  174. CCoinsViewCache(CCoinsView *baseIn);
  175. // Standard CCoinsView methods
  176. bool GetCoin(const COutPoint &outpoint, Coin &coin) const override;
  177. bool HaveCoin(const COutPoint &outpoint) const override;
  178. uint256 GetBestBlock() const override;
  179. void SetBestBlock(const uint256 &hashBlock);
  180. bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override;
  181. CCoinsViewCursor* Cursor() const override {
  182. throw std::logic_error("CCoinsViewCache cursor iteration not supported.");
  183. }
  184. /**
  185. * Check if we have the given utxo already loaded in this cache.
  186. * The semantics are the same as HaveCoin(), but no calls to
  187. * the backing CCoinsView are made.
  188. */
  189. bool HaveCoinInCache(const COutPoint &outpoint) const;
  190. /**
  191. * Return a reference to Coin in the cache, or a pruned one if not found. This is
  192. * more efficient than GetCoin.
  193. *
  194. * Generally, do not hold the reference returned for more than a short scope.
  195. * While the current implementation allows for modifications to the contents
  196. * of the cache while holding the reference, this behavior should not be relied
  197. * on! To be safe, best to not hold the returned reference through any other
  198. * calls to this cache.
  199. */
  200. const Coin& AccessCoin(const COutPoint &output) const;
  201. /**
  202. * Add a coin. Set potential_overwrite to true if a non-pruned version may
  203. * already exist.
  204. */
  205. void AddCoin(const COutPoint& outpoint, Coin&& coin, bool potential_overwrite);
  206. /**
  207. * Spend a coin. Pass moveto in order to get the deleted data.
  208. * If no unspent output exists for the passed outpoint, this call
  209. * has no effect.
  210. */
  211. bool SpendCoin(const COutPoint &outpoint, Coin* moveto = nullptr);
  212. /**
  213. * Push the modifications applied to this cache to its base.
  214. * Failure to call this method before destruction will cause the changes to be forgotten.
  215. * If false is returned, the state of this cache (and its backing view) will be undefined.
  216. */
  217. bool Flush();
  218. /**
  219. * Removes the UTXO with the given outpoint from the cache, if it is
  220. * not modified.
  221. */
  222. void Uncache(const COutPoint &outpoint);
  223. //! Calculate the size of the cache (in number of transaction outputs)
  224. unsigned int GetCacheSize() const;
  225. //! Calculate the size of the cache (in bytes)
  226. size_t DynamicMemoryUsage() const;
  227. /**
  228. * Amount of starwelss coming in to a transaction
  229. * Note that lightweight clients may not know anything besides the hash of previous transactions,
  230. * so may not be able to calculate this.
  231. *
  232. * @param[in] tx transaction for which we are checking input total
  233. * @return Sum of value of all inputs (scriptSigs)
  234. */
  235. CAmount GetValueIn(const CTransaction& tx) const;
  236. //! Check whether all prevouts of the transaction are present in the UTXO set represented by this view
  237. bool HaveInputs(const CTransaction& tx) const;
  238. private:
  239. CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const;
  240. /**
  241. * By making the copy constructor private, we prevent accidentally using it when one intends to create a cache on top of a base cache.
  242. */
  243. CCoinsViewCache(const CCoinsViewCache &);
  244. };
  245. //! Utility function to add all of a transaction's outputs to a cache.
  246. // When check is false, this assumes that overwrites are only possible for coinbase transactions.
  247. // When check is true, the underlying view may be queried to determine whether an addition is
  248. // an overwrite.
  249. // TODO: pass in a boolean to limit these possible overwrites to known
  250. // (pre-BIP34) cases.
  251. void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight, bool check = false);
  252. //! Utility function to find any unspent output with a given txid.
  253. // This function can be quite expensive because in the event of a transaction
  254. // which is not found in the cache, it can cause up to MAX_OUTPUTS_PER_BLOCK
  255. // lookups to database, so it should be used with care.
  256. const Coin& AccessByTxid(const CCoinsViewCache& cache, const uint256& txid);
  257. #endif // STARWELS_COINS_H