Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2014 The Bitcoin developers
3 : // Copyright (c) 2016-2021 The PIVX Core developers
4 : // Distributed under the MIT software license, see the accompanying
5 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 :
7 : #ifndef PIVX_COINS_H
8 : #define PIVX_COINS_H
9 :
10 : #include "compressor.h"
11 : #include "consensus/consensus.h" // can be removed once policy/ established
12 : #include "crypto/siphash.h"
13 : #include "memusage.h"
14 : #include "sapling/incrementalmerkletree.h"
15 : #include "script/standard.h"
16 : #include "serialize.h"
17 : #include "uint256.h"
18 :
19 : #include <assert.h>
20 : #include <stdint.h>
21 :
22 : #include <unordered_map>
23 :
24 : /**
25 : * A UTXO entry.
26 : *
27 : * Serialized format:
28 : * - VARINT((coinbase ? 2 : 0) | (coinstake ? 1 : 0) | (height << 2))
29 : * - the non-spent CTxOut (via CTxOutCompressor)
30 : */
31 74729637 : class Coin
32 : {
33 : public:
34 : //! whether the containing transaction was a coinbase
35 : bool fCoinBase;
36 :
37 : //! whether the containing transaction was a coinstake
38 : bool fCoinStake;
39 :
40 : //! unspent transaction output
41 : CTxOut out;
42 :
43 : //! at which height the containing transaction was included in the active block chain
44 : uint32_t nHeight;
45 :
46 : //! construct a Coin from a CTxOut and height/coinbase properties.
47 27 : Coin(CTxOut&& outIn, int nHeightIn, bool fCoinBaseIn, bool fCoinStakeIn) : fCoinBase(fCoinBaseIn), fCoinStake(fCoinStakeIn), out(std::move(outIn)), nHeight(nHeightIn) {}
48 7146884 : Coin(const CTxOut& outIn, int nHeightIn, bool fCoinBaseIn, bool fCoinStakeIn) : fCoinBase(fCoinBaseIn), fCoinStake(fCoinStakeIn), out(outIn), nHeight(nHeightIn) {}
49 :
50 5330123 : void Clear() {
51 5330123 : out.SetNull();
52 5330123 : fCoinBase = false;
53 5330123 : fCoinStake = false;
54 5330123 : nHeight = 0;
55 5279879 : }
56 :
57 : //! empty constructor
58 46698310 : Coin() : fCoinBase(false), fCoinStake(false), nHeight(0) { }
59 :
60 6045025 : bool IsCoinBase() const {
61 6045025 : return fCoinBase;
62 : }
63 :
64 6021514 : bool IsCoinStake() const {
65 6021514 : return fCoinStake;
66 : }
67 :
68 : template<typename Stream>
69 695135 : void Serialize(Stream &s) const {
70 695135 : assert(!IsSpent());
71 2038173 : uint32_t code = nHeight * 4 + (fCoinBase ? 2 : 0) + (fCoinStake ? 1 : 0);
72 695135 : ::Serialize(s, VARINT(code));
73 695135 : ::Serialize(s, Using<TxOutCompression>(out));
74 695135 : }
75 :
76 : template<typename Stream>
77 6893133 : void Unserialize(Stream &s) {
78 6893133 : uint32_t code = 0;
79 6893133 : ::Unserialize(s, VARINT(code));
80 6893133 : nHeight = code >> 2;
81 6893133 : fCoinBase = code & 2;
82 6893133 : fCoinStake = code & 1;
83 6893133 : ::Unserialize(s, Using<TxOutCompression>(out));
84 6893131 : }
85 :
86 58466135 : bool IsSpent() const {
87 57772388 : return out.IsNull();
88 : }
89 :
90 1035872 : size_t DynamicMemoryUsage() const {
91 21732663 : return memusage::DynamicUsage(out.scriptPubKey);
92 : }
93 : };
94 :
95 : class SaltedOutpointHasher
96 : {
97 : private:
98 : /** Salt */
99 : const uint64_t k0, k1;
100 :
101 : public:
102 : SaltedOutpointHasher();
103 :
104 : /**
105 : * This *must* return size_t. With Boost 1.46 on 32-bit systems the
106 : * unordered_map will behave unpredictably if the custom hasher returns a
107 : * uint64_t, resulting in failures when syncing the chain (#4634).
108 : */
109 76617192 : size_t operator()(const COutPoint& id) const {
110 76617192 : return SipHashUint256Extra(k0, k1, id.hash, id.n);
111 : }
112 : };
113 :
114 : // Used on Sapling nullifiers, anchor maps and txmempool::mapTx: sorted by txid
115 : class SaltedIdHasher
116 : {
117 : private:
118 : /** Salt */
119 : const uint64_t k0, k1;
120 :
121 : public:
122 : SaltedIdHasher();
123 :
124 : /**
125 : * This *must* return size_t. With Boost 1.46 on 32-bit systems the
126 : * unordered_map will behave unpredictably if the custom hasher returns a
127 : * uint64_t, resulting in failures when syncing the chain (#4634).
128 : */
129 20721656 : size_t operator()(const uint256& txid) const {
130 20721656 : return SipHashUint256(k0, k1, txid);
131 : }
132 : };
133 :
134 15062562 : struct CCoinsCacheEntry {
135 : Coin coin; // The actual cached data.
136 : unsigned char flags;
137 :
138 : enum Flags {
139 : DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view.
140 : FRESH = (1 << 1), // The parent view does not have this entry (or it is pruned).
141 : };
142 :
143 8115984 : CCoinsCacheEntry() : flags(0) {}
144 6825780 : explicit CCoinsCacheEntry(Coin&& coin_) : coin(std::move(coin_)), flags(0) {}
145 : };
146 :
147 : // Sapling
148 :
149 287347 : struct CAnchorsSaplingCacheEntry
150 : {
151 : bool entered; // This will be false if the anchor is removed from the cache
152 : SaplingMerkleTree tree; // The tree itself
153 : unsigned char flags;
154 :
155 : enum Flags {
156 : DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view.
157 : };
158 :
159 57383 : CAnchorsSaplingCacheEntry() : entered(false), flags(0) {}
160 : };
161 :
162 : struct CNullifiersCacheEntry
163 : {
164 : bool entered; // If the nullifier is spent or not
165 : unsigned char flags;
166 :
167 : enum Flags {
168 : DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view.
169 : };
170 :
171 939 : CNullifiersCacheEntry() : entered(false), flags(0) {}
172 : };
173 :
174 : typedef std::unordered_map<uint256, CAnchorsSaplingCacheEntry, SaltedIdHasher> CAnchorsSaplingMap;
175 : typedef std::unordered_map<uint256, CNullifiersCacheEntry, SaltedIdHasher> CNullifiersMap;
176 :
177 : typedef std::unordered_map<COutPoint, CCoinsCacheEntry, SaltedOutpointHasher> CCoinsMap;
178 :
179 : /** Cursor for iterating over CoinsView state */
180 : class CCoinsViewCursor
181 : {
182 : public:
183 518 : CCoinsViewCursor(const uint256 &hashBlockIn): hashBlock(hashBlockIn) {}
184 518 : virtual ~CCoinsViewCursor() {}
185 :
186 : virtual bool GetKey(COutPoint& key) const = 0;
187 : virtual bool GetValue(Coin& coin) const = 0;
188 : virtual unsigned int GetValueSize() const = 0;
189 :
190 : virtual bool Valid() const = 0;
191 : virtual void Next() = 0;
192 :
193 : //! Get best block at the time this cursor was created
194 49 : const uint256 &GetBestBlock() const { return hashBlock; }
195 : private:
196 : uint256 hashBlock;
197 : };
198 :
199 : /** Abstract view on the open txout dataset. */
200 669772 : class CCoinsView
201 : {
202 : public:
203 : //! Retrieve the Coin (unspent transaction output) for a given outpoint.
204 : virtual bool GetCoin(const COutPoint& outpoint, Coin& coin) const;
205 :
206 : //! Just check whether we have data for a given outpoint.
207 : //! This may (but cannot always) return true for spent outputs.
208 : virtual bool HaveCoin(const COutPoint& outpoint) const;
209 :
210 : //! Retrieve the block hash whose state this CCoinsView currently represents
211 : virtual uint256 GetBestBlock() const;
212 :
213 : //! Retrieve the range of blocks that may have been only partially written.
214 : //! If the database is in a consistent state, the result is the empty vector.
215 : //! Otherwise, a two-element vector is returned consisting of the new and
216 : //! the old block hash, in that order.
217 : virtual std::vector<uint256> GetHeadBlocks() const;
218 :
219 : //! Do a bulk modification (multiple Coin changes + BestBlock change).
220 : //! The passed mapCoins can be modified.
221 : virtual bool BatchWrite(CCoinsMap& mapCoins,
222 : const uint256& hashBlock,
223 : const uint256& hashSaplingAnchor,
224 : CAnchorsSaplingMap& mapSaplingAnchors,
225 : CNullifiersMap& mapSaplingNullifiers);
226 :
227 : //! Get a cursor to iterate over the whole state
228 : virtual CCoinsViewCursor* Cursor() const;
229 :
230 : //! As we use CCoinsViews polymorphically, have a virtual destructor
231 281001 : virtual ~CCoinsView() {}
232 :
233 : //! Estimate database size (0 if not implemented)
234 0 : virtual size_t EstimateSize() const { return 0; }
235 :
236 : // Sapling
237 : //! Retrieve the tree (Sapling) at a particular anchored root in the chain
238 : virtual bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const;
239 :
240 : //! Determine whether a nullifier is spent or not
241 : virtual bool GetNullifier(const uint256 &nullifier) const;
242 :
243 : //! Get the current "tip" or the latest anchored tree root in the chain
244 : virtual uint256 GetBestAnchor() const;
245 : };
246 :
247 :
248 : /** CCoinsView backed by another CCoinsView */
249 280826 : class CCoinsViewBacked : public CCoinsView
250 : {
251 : protected:
252 : CCoinsView* base;
253 :
254 : public:
255 : CCoinsViewBacked(CCoinsView* viewIn);
256 : bool GetCoin(const COutPoint& outpoint, Coin& coin) const override;
257 : bool HaveCoin(const COutPoint& outpoint) const override;
258 : uint256 GetBestBlock() const override;
259 : std::vector<uint256> GetHeadBlocks() const override;
260 : void SetBackend(CCoinsView& viewIn);
261 : CCoinsViewCursor* Cursor() const override;
262 : size_t EstimateSize() const override;
263 :
264 : bool BatchWrite(CCoinsMap& mapCoins,
265 : const uint256& hashBlock,
266 : const uint256& hashSaplingAnchor,
267 : CAnchorsSaplingMap& mapSaplingAnchors,
268 : CNullifiersMap& mapSaplingNullifiers) override;
269 :
270 : // Sapling
271 : bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const override;
272 : bool GetNullifier(const uint256 &nullifier) const override;
273 : uint256 GetBestAnchor() const override;
274 : };
275 :
276 :
277 : /** Used as the flags parameter to sequence and nLocktime checks in non-consensus code. */
278 : static const unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS = LOCKTIME_VERIFY_SEQUENCE |
279 : LOCKTIME_MEDIAN_TIME_PAST;
280 :
281 : /** CCoinsView that adds a memory cache for transactions to another CCoinsView */
282 : class CCoinsViewCache : public CCoinsViewBacked
283 : {
284 : protected:
285 : /**
286 : * Make mutable so that we can "fill the cache" even from Get-methods
287 : * declared as "const".
288 : */
289 : mutable uint256 hashBlock;
290 : mutable CCoinsMap cacheCoins;
291 :
292 : // Sapling
293 : mutable uint256 hashSaplingAnchor;
294 : mutable CAnchorsSaplingMap cacheSaplingAnchors;
295 : mutable CNullifiersMap cacheSaplingNullifiers;
296 :
297 : /* Cached dynamic memory usage for the inner Coin objects. */
298 : mutable size_t cachedCoinsUsage;
299 :
300 : public:
301 : CCoinsViewCache(CCoinsView *baseIn);
302 :
303 : /**
304 : * By deleting the copy constructor, we prevent accidentally using it when one intends to create a cache on top of a base cache.
305 : */
306 : CCoinsViewCache(const CCoinsViewCache &) = delete;
307 :
308 : // Sapling methods
309 : bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const override;
310 : bool GetNullifier(const uint256 &nullifier) const override;
311 : uint256 GetBestAnchor() const override;
312 :
313 : // Adds the tree to mapSaplingAnchors
314 : // and sets the current commitment root to this root.
315 : template<typename Tree> void PushAnchor(const Tree &tree);
316 :
317 : // Removes the current commitment root from mapAnchors and sets
318 : // the new current root.
319 : void PopAnchor(const uint256 &rt);
320 :
321 : // Marks nullifiers for a given transaction as spent or not.
322 : void SetNullifiers(const CTransaction& tx, bool spent);
323 :
324 : //! Check whether all sapling spend requirements (anchors/nullifiers) are satisfied
325 : bool HaveShieldedRequirements(const CTransaction& tx) const;
326 :
327 : // Standard CCoinsView methods
328 : bool GetCoin(const COutPoint& outpoint, Coin& coin) const override;
329 : bool HaveCoin(const COutPoint& outpoint) const override;
330 : uint256 GetBestBlock() const override;
331 : void SetBestBlock(const uint256& hashBlock);
332 :
333 : //! Get the coin and check if it's spent
334 : bool GetUTXOCoin(const COutPoint& outpoint, Coin& coin) const;
335 :
336 : bool BatchWrite(CCoinsMap& mapCoins,
337 : const uint256& hashBlock,
338 : const uint256& hashSaplingAnchor,
339 : CAnchorsSaplingMap& mapSaplingAnchors,
340 : CNullifiersMap& mapSaplingNullifiers) override;
341 :
342 : /**
343 : * Check if we have the given utxo already loaded in this cache.
344 : * The semantics are the same as HaveCoin(), but no calls to
345 : * the backing CCoinsView are made.
346 : */
347 : bool HaveCoinInCache(const COutPoint& outpoint) const;
348 :
349 : /**
350 : * Return a reference to a Coin in the cache, or a pruned one if not found. This is
351 : * more efficient than GetCoin. Modifications to other cache entries are
352 : * allowed while accessing the returned pointer.
353 : */
354 : const Coin& AccessCoin(const COutPoint& output) const;
355 :
356 : /**
357 : * Add a coin. Set potential_overwrite to true if a non-pruned version may
358 : * already exist.
359 : */
360 : void AddCoin(const COutPoint& outpoint, Coin&& coin, bool potential_overwrite);
361 :
362 : /**
363 : * Spend a coin. Pass moveto in order to get the deleted data.
364 : * If no unspent output exists for the passed outpoint, this call
365 : * has no effect.
366 : */
367 : void SpendCoin(const COutPoint &outpoint, Coin* moveto = nullptr);
368 :
369 : /**
370 : * Push the modifications applied to this cache to its base.
371 : * Failure to call this method before destruction will cause the changes to be forgotten.
372 : * If false is returned, the state of this cache (and its backing view) will be undefined.
373 : */
374 : bool Flush();
375 :
376 : /**
377 : * Removes the UTXO with the given outpoint from the cache, if it is not modified.
378 : */
379 : void Uncache(const COutPoint &outpoint);
380 :
381 : //! Calculate the size of the cache (in number of transaction outputs)
382 : unsigned int GetCacheSize() const;
383 :
384 : //! Calculate the size of the cache (in bytes)
385 : size_t DynamicMemoryUsage() const;
386 :
387 : /**
388 : * Amount of pivx coming in to a transaction
389 : * Note that lightweight clients may not know anything besides the hash of previous transactions,
390 : * so may not be able to calculate this.
391 : *
392 : * @param[in] tx transaction for which we are checking input total
393 : * @return Sum of value of all inputs (scriptSigs)
394 : */
395 : CAmount GetValueIn(const CTransaction& tx) const;
396 :
397 : //! Check whether all prevouts of the transaction are present in the UTXO set represented by this view
398 : bool HaveInputs(const CTransaction& tx) const;
399 :
400 : /*
401 : * Return the depth of a coin at height nHeight, or -1 if not found
402 : */
403 : int GetCoinDepthAtHeight(const COutPoint& output, int nHeight) const;
404 :
405 : /*
406 : * Return the sum of the value of all transaction outputs
407 : */
408 : CAmount GetTotalAmount() const;
409 :
410 : /*
411 : * Prune zerocoin mints and frozen outputs - do it once, after initialization
412 : */
413 : bool PruneInvalidEntries();
414 :
415 :
416 : private:
417 : CCoinsMap::iterator FetchCoin(const COutPoint& outpoint) const;
418 :
419 : //! Generalized interface for popping anchors
420 : template<typename Tree, typename Cache, typename CacheEntry>
421 : void AbstractPopAnchor(
422 : const uint256 &newrt,
423 : Cache &cacheAnchors,
424 : uint256 &hash
425 : );
426 :
427 : //! Generalized interface for pushing anchors
428 : template<typename Tree, typename Cache, typename CacheIterator, typename CacheEntry>
429 : void AbstractPushAnchor(
430 : const Tree &tree,
431 : Cache &cacheAnchors,
432 : uint256 &hash
433 : );
434 :
435 : //! Interface for bringing an anchor into the cache.
436 : template<typename Tree>
437 : void BringBestAnchorIntoCache(
438 : const uint256 ¤tRoot,
439 : Tree &tree
440 : );
441 : };
442 :
443 : //! Utility function to add all of a transaction's outputs to a cache.
444 : // PIVX: When check is false, this assumes that overwrites are never possible due to BIP34 always in effect
445 : // When check is true, the underlying view may be queried to determine whether an addition is
446 : // an overwrite.
447 : // When fSkipInvalid is true, the invalid_out list is checked before adding the coin.
448 : void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight, bool check = false, bool fSkipInvalid = false);
449 :
450 : //! Utility function to find any unspent output with a given txid.
451 : const Coin& AccessByTxid(const CCoinsViewCache& cache, const uint256& txid);
452 :
453 : #endif // PIVX_COINS_H
|