PIVX Core  5.6.99
P2P Digital Currency
coins.cpp
Go to the documentation of this file.
1 // Copyright (c) 2012-2014 The Bitcoin developers
2 // Copyright (c) 2015-2021 The PIVX 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 #include "coins.h"
7 
8 #include "consensus/consensus.h"
9 #include "invalid.h"
10 #include "logging.h"
11 #include "random.h"
12 #include "version.h"
13 
14 #include <assert.h>
15 
16 bool CCoinsView::GetCoin(const COutPoint& outpoint, Coin& coin) const { return false; }
17 bool CCoinsView::HaveCoin(const COutPoint& outpoint) const { return false; }
19 std::vector<uint256> CCoinsView::GetHeadBlocks() const { return std::vector<uint256>(); }
20 CCoinsViewCursor *CCoinsView::Cursor() const { return 0; }
21 
23  const uint256& hashBlock,
24  const uint256& hashSaplingAnchor,
25  CAnchorsSaplingMap& mapSaplingAnchors,
26  CNullifiersMap& mapSaplingNullifiers) { return false; }
27 
28 // Sapling
29 bool CCoinsView::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { return false; }
30 bool CCoinsView::GetNullifier(const uint256 &nullifier) const { return false; }
32 
34 bool CCoinsViewBacked::GetCoin(const COutPoint& outpoint, Coin& coin) const { return base->GetCoin(outpoint, coin); }
35 bool CCoinsViewBacked::HaveCoin(const COutPoint& outpoint) const { return base->HaveCoin(outpoint); }
37 std::vector<uint256> CCoinsViewBacked::GetHeadBlocks() const { return base->GetHeadBlocks(); }
38 void CCoinsViewBacked::SetBackend(CCoinsView& viewIn) { base = &viewIn; }
40 size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); }
41 
43  const uint256& hashBlock,
44  const uint256& hashSaplingAnchor,
45  CAnchorsSaplingMap& mapSaplingAnchors,
46  CNullifiersMap& mapSaplingNullifiers)
47 { return base->BatchWrite(mapCoins, hashBlock, hashSaplingAnchor, mapSaplingAnchors, mapSaplingNullifiers); }
48 
49 // Sapling
50 bool CCoinsViewBacked::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { return base->GetSaplingAnchorAt(rt, tree); }
51 bool CCoinsViewBacked::GetNullifier(const uint256 &nullifier) const { return base->GetNullifier(nullifier); }
53 
54 SaltedOutpointHasher::SaltedOutpointHasher() : k0(GetRand(std::numeric_limits<uint64_t>::max())), k1(GetRand(std::numeric_limits<uint64_t>::max())) {}
55 SaltedIdHasher::SaltedIdHasher() : k0(GetRand(std::numeric_limits<uint64_t>::max())), k1(GetRand(std::numeric_limits<uint64_t>::max())) {}
56 
57 CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), cachedCoinsUsage(0) {}
58 
60  return memusage::DynamicUsage(cacheCoins) +
61  memusage::DynamicUsage(cacheSaplingAnchors) +
62  memusage::DynamicUsage(cacheSaplingNullifiers) +
64 }
65 
66 CCoinsMap::iterator CCoinsViewCache::FetchCoin(const COutPoint& outpoint) const
67 {
68  CCoinsMap::iterator it = cacheCoins.find(outpoint);
69  if (it != cacheCoins.end())
70  return it;
71  Coin tmp;
72  if (!base->GetCoin(outpoint, tmp))
73  return cacheCoins.end();
74  CCoinsMap::iterator ret = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::forward_as_tuple(std::move(tmp))).first;
75  if (ret->second.coin.IsSpent()) {
76  // The parent only has an empty entry for this outpoint; we can consider our
77  // version as fresh.
78  ret->second.flags = CCoinsCacheEntry::FRESH;
79  }
80  cachedCoinsUsage += memusage::DynamicUsage(ret->second.coin);
81  return ret;
82 }
83 
84 bool CCoinsViewCache::GetCoin(const COutPoint& outpoint, Coin& coin) const
85 {
86  CCoinsMap::const_iterator it = FetchCoin(outpoint);
87  if (it != cacheCoins.end()) {
88  coin = it->second.coin;
89  return true;
90  }
91  return false;
92 }
93 
94 void CCoinsViewCache::AddCoin(const COutPoint& outpoint, Coin&& coin, bool possible_overwrite) {
95  assert(!coin.IsSpent());
96  if (coin.out.scriptPubKey.IsUnspendable()) return;
97  if (coin.out.IsZerocoinMint()) return;
98  CCoinsMap::iterator it;
99  bool inserted;
100  std::tie(it, inserted) = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::tuple<>());
101  bool fresh = false;
102  if (!inserted) {
103  cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
104  }
105  if (!possible_overwrite) {
106  if (!it->second.coin.IsSpent()) {
107  throw std::logic_error("Adding new coin that replaces non-pruned entry");
108  }
109  fresh = !(it->second.flags & CCoinsCacheEntry::DIRTY);
110  }
111  it->second.coin = std::move(coin);
112  it->second.flags |= CCoinsCacheEntry::DIRTY | (fresh ? CCoinsCacheEntry::FRESH : 0);
113  cachedCoinsUsage += it->second.coin.DynamicMemoryUsage();
114 }
115 
116 void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight, bool check, bool fSkipInvalid)
117 {
118  bool fCoinbase = tx.IsCoinBase();
119  bool fCoinstake = tx.IsCoinStake();
120  const uint256& txid = tx.GetHash();
121  for (size_t i = 0; i < tx.vout.size(); ++i) {
122  const COutPoint out(txid, i);
123  // Don't add fraudulent/banned outputs
124  if (fSkipInvalid && invalid_out::ContainsOutPoint(out)) {
125  cache.SpendCoin(out); // no-op if the coin is not in the cache
126  continue;
127  }
128  bool overwrite = check && cache.HaveCoin(out);
129  cache.AddCoin(out, Coin(tx.vout[i], nHeight, fCoinbase, fCoinstake), overwrite);
130  }
131 }
132 
133 void CCoinsViewCache::SpendCoin(const COutPoint& outpoint, Coin* moveout)
134 {
135  CCoinsMap::iterator it = FetchCoin(outpoint);
136  if (it == cacheCoins.end()) return;
137  cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
138  if (moveout) {
139  *moveout = std::move(it->second.coin);
140  }
141  if (it->second.flags & CCoinsCacheEntry::FRESH) {
142  cacheCoins.erase(it);
143  } else {
144  it->second.flags |= CCoinsCacheEntry::DIRTY;
145  it->second.coin.Clear();
146  }
147 }
148 
149 static const Coin coinEmpty;
150 
151 const Coin& CCoinsViewCache::AccessCoin(const COutPoint& outpoint) const
152 {
153  CCoinsMap::const_iterator it = FetchCoin(outpoint);
154  if (it == cacheCoins.end()) {
155  return coinEmpty;
156  } else {
157  return it->second.coin;
158  }
159 }
160 
161 bool CCoinsViewCache::HaveCoin(const COutPoint& outpoint) const
162 {
163  CCoinsMap::const_iterator it = FetchCoin(outpoint);
164  return (it != cacheCoins.end() && !it->second.coin.IsSpent());
165 }
166 
167 bool CCoinsViewCache::HaveCoinInCache(const COutPoint& outpoint) const
168 {
169  CCoinsMap::const_iterator it = cacheCoins.find(outpoint);
170  return it != cacheCoins.end();
171 }
172 
174 {
175  if (hashBlock.IsNull())
177  return hashBlock;
178 }
179 
180 void CCoinsViewCache::SetBestBlock(const uint256& hashBlockIn)
181 {
182  hashBlock = hashBlockIn;
183 }
184 
185 template<typename Map, typename MapIterator, typename MapEntry>
187  Map &mapAnchors,
188  Map &cacheAnchors,
189  size_t &cachedCoinsUsage
190 )
191 {
192  for (MapIterator child_it = mapAnchors.begin(); child_it != mapAnchors.end();)
193  {
194  if (child_it->second.flags & MapEntry::DIRTY) {
195  MapIterator parent_it = cacheAnchors.find(child_it->first);
196 
197  if (parent_it == cacheAnchors.end()) {
198  MapEntry& entry = cacheAnchors[child_it->first];
199  entry.entered = child_it->second.entered;
200  entry.tree = child_it->second.tree;
201  entry.flags = MapEntry::DIRTY;
202 
203  cachedCoinsUsage += entry.tree.DynamicMemoryUsage();
204  } else {
205  if (parent_it->second.entered != child_it->second.entered) {
206  // The parent may have removed the entry.
207  parent_it->second.entered = child_it->second.entered;
208  parent_it->second.flags |= MapEntry::DIRTY;
209  }
210  }
211  }
212 
213  MapIterator itOld = child_it++;
214  mapAnchors.erase(itOld);
215  }
216 }
217 
218 void BatchWriteNullifiers(CNullifiersMap &mapNullifiers, CNullifiersMap &cacheNullifiers)
219 {
220  for (CNullifiersMap::iterator child_it = mapNullifiers.begin(); child_it != mapNullifiers.end();) {
221  if (child_it->second.flags & CNullifiersCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization).
222  CNullifiersMap::iterator parent_it = cacheNullifiers.find(child_it->first);
223 
224  if (parent_it == cacheNullifiers.end()) {
225  CNullifiersCacheEntry& entry = cacheNullifiers[child_it->first];
226  entry.entered = child_it->second.entered;
228  } else {
229  if (parent_it->second.entered != child_it->second.entered) {
230  parent_it->second.entered = child_it->second.entered;
231  parent_it->second.flags |= CNullifiersCacheEntry::DIRTY;
232  }
233  }
234  }
235  CNullifiersMap::iterator itOld = child_it++;
236  mapNullifiers.erase(itOld);
237  }
238 }
239 
241  const uint256& hashBlockIn,
242  const uint256 &hashSaplingAnchorIn,
243  CAnchorsSaplingMap& mapSaplingAnchors,
244  CNullifiersMap& mapSaplingNullifiers)
245 {
246  for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end(); it = mapCoins.erase(it)) {
247  // Ignore non-dirty entries (optimization).
248  if (!(it->second.flags & CCoinsCacheEntry::DIRTY)) {
249  continue;
250  }
251  CCoinsMap::iterator itUs = cacheCoins.find(it->first);
252  if (itUs == cacheCoins.end()) {
253  // The parent cache does not have an entry, while the child does
254  // We can ignore it if it's both FRESH and pruned in the child
255  if (!(it->second.flags & CCoinsCacheEntry::FRESH && it->second.coin.IsSpent())) {
256  // Otherwise we will need to create it in the parent
257  // and move the data up and mark it as dirty
258  CCoinsCacheEntry& entry = cacheCoins[it->first];
259  entry.coin = std::move(it->second.coin);
260  cachedCoinsUsage += memusage::DynamicUsage(entry.coin);
262  // We can mark it FRESH in the parent if it was FRESH in the child
263  // Otherwise it might have just been flushed from the parent's cache
264  // and already exist in the grandparent
265  if (it->second.flags & CCoinsCacheEntry::FRESH) {
267  }
268  }
269  } else {
270  // Assert that the child cache entry was not marked FRESH if the
271  // parent cache entry has unspent outputs. If this ever happens,
272  // it means the FRESH flag was misapplied and there is a logic
273  // error in the calling code.
274  if ((it->second.flags & CCoinsCacheEntry::FRESH) && !itUs->second.coin.IsSpent()) {
275  throw std::logic_error("FRESH flag misapplied to cache entry for base transaction with spendable outputs");
276  }
277 
278  // Found the entry in the parent cache
279  if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coin.IsSpent()) {
280  // The grandparent does not have an entry, and the child is
281  // modified and being pruned. This means we can just delete
282  // it from the parent.
283  cachedCoinsUsage -= memusage::DynamicUsage(itUs->second.coin);
284  cacheCoins.erase(itUs);
285  } else {
286  // A normal modification.
287  cachedCoinsUsage -= memusage::DynamicUsage(itUs->second.coin);
288  itUs->second.coin = std::move(it->second.coin);
289  cachedCoinsUsage += memusage::DynamicUsage(itUs->second.coin);
290  itUs->second.flags |= CCoinsCacheEntry::DIRTY;
291  // NOTE: It is possible the child has a FRESH flag here in
292  // the event the entry we found in the parent is pruned. But
293  // we must not copy that FRESH flag to the parent as that
294  // pruned state likely still needs to be communicated to the
295  // grandparent.
296  }
297  }
298  }
299 
300  // Sapling
301  ::BatchWriteAnchors<CAnchorsSaplingMap, CAnchorsSaplingMap::iterator, CAnchorsSaplingCacheEntry>(mapSaplingAnchors, cacheSaplingAnchors, cachedCoinsUsage);
302  ::BatchWriteNullifiers(mapSaplingNullifiers, cacheSaplingNullifiers);
303  hashSaplingAnchor = hashSaplingAnchorIn;
304 
305  hashBlock = hashBlockIn;
306  return true;
307 }
308 
310 {
311  bool fOk = base->BatchWrite(cacheCoins,
312  hashBlock,
316  cacheCoins.clear();
317  cacheSaplingAnchors.clear();
318  cacheSaplingNullifiers.clear();
319  cachedCoinsUsage = 0;
320  return fOk;
321 }
322 
323 void CCoinsViewCache::Uncache(const COutPoint& outpoint)
324 {
325  CCoinsMap::iterator it = cacheCoins.find(outpoint);
326  if (it != cacheCoins.end() && it->second.flags == 0) {
327  cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
328  cacheCoins.erase(it);
329  }
330 }
331 
332 unsigned int CCoinsViewCache::GetCacheSize() const
333 {
334  return cacheCoins.size();
335 }
336 
338 {
339  if (tx.IsCoinBase())
340  return 0;
341 
342  CAmount nResult = 0;
343  for (const CTxIn& in : tx.vin) {
344  if (in.IsZerocoinSpend() || in.IsZerocoinPublicSpend()) {
345  nResult += in.nSequence * COIN;
346  } else {
347  nResult += AccessCoin(in.prevout).out.nValue;
348  }
349  }
350 
351  // Sapling
352  nResult += tx.GetShieldedValueIn();
353 
354  return nResult;
355 }
356 
358 {
359  if (!tx.IsCoinBase() && !tx.HasZerocoinSpendInputs()) {
360  for (unsigned int i = 0; i < tx.vin.size(); i++) {
361  if (!HaveCoin(tx.vin[i].prevout)) {
362  return false;
363  }
364  }
365  }
366  return true;
367 }
368 
369 int CCoinsViewCache::GetCoinDepthAtHeight(const COutPoint& output, int nHeight) const
370 {
371  const Coin& coin = AccessCoin(output);
372  if (!coin.IsSpent())
373  return nHeight - coin.nHeight + 1;
374  return -1;
375 }
376 
378 {
379  CAmount nTotal = 0;
380 
381  std::unique_ptr<CCoinsViewCursor> pcursor(Cursor());
382  while (pcursor->Valid()) {
383  Coin coin;
384  if (pcursor->GetValue(coin) && !coin.IsSpent()) {
385  nTotal += coin.out.nValue;
386  }
387  pcursor->Next();
388  }
389 
390  return nTotal;
391 }
392 
394 {
395  // Prune zerocoin Mints and fraudulent/frozen outputs
396  bool loaded = invalid_out::LoadOutpoints();
397  assert(loaded);
398  for (const COutPoint& out: invalid_out::setInvalidOutPoints) {
399  if (HaveCoin(out)) {
400  LogPrintf("Pruning invalid output %s\n", out.ToString());
401  SpendCoin(out);
402  }
403  }
404  return Flush();
405 }
406 
407 static const size_t MAX_OUTPUTS_PER_BLOCK = MAX_BLOCK_SIZE_CURRENT / ::GetSerializeSize(CTxOut(), PROTOCOL_VERSION); // TODO: merge with similar definition in undo.h.
408 
409 const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid)
410 {
411  COutPoint iter(txid, 0);
412  while (iter.n < MAX_OUTPUTS_PER_BLOCK) {
413  const Coin& alternate = view.AccessCoin(iter);
414  if (!alternate.IsSpent()) return alternate;
415  ++iter.n;
416  }
417  return coinEmpty;
418 }
419 
420 // Sapling
421 
423 
424  CAnchorsSaplingMap::const_iterator it = cacheSaplingAnchors.find(rt);
425  if (it != cacheSaplingAnchors.end()) {
426  if (it->second.entered) {
427  tree = it->second.tree;
428  return true;
429  } else {
430  return false;
431  }
432  }
433 
434  if (!base->GetSaplingAnchorAt(rt, tree)) {
435  return false;
436  }
437 
438  CAnchorsSaplingMap::iterator ret = cacheSaplingAnchors.insert(std::make_pair(rt, CAnchorsSaplingCacheEntry())).first;
439  ret->second.entered = true;
440  ret->second.tree = tree;
441  cachedCoinsUsage += ret->second.tree.DynamicMemoryUsage();
442 
443  return true;
444 }
445 
446 bool CCoinsViewCache::GetNullifier(const uint256 &nullifier) const {
447  CNullifiersMap* cacheToUse = &cacheSaplingNullifiers;
448  CNullifiersMap::iterator it = cacheToUse->find(nullifier);
449  if (it != cacheToUse->end())
450  return it->second.entered;
451 
452  CNullifiersCacheEntry entry;
453  bool tmp = base->GetNullifier(nullifier);
454  entry.entered = tmp;
455 
456  cacheToUse->insert(std::make_pair(nullifier, entry));
457  return tmp;
458 }
459 
460 template<typename Tree, typename Cache, typename CacheIterator, typename CacheEntry>
462  const Tree &tree,
463  Cache &cacheAnchors,
464  uint256 &hash
465 )
466 {
467  uint256 newrt = tree.root();
468 
469  auto currentRoot = GetBestAnchor();
470 
471  // We don't want to overwrite an anchor we already have.
472  // This occurs when a block doesn't modify mapAnchors at all,
473  // because there are no joinsplits. We could get around this a
474  // different way (make all blocks modify mapAnchors somehow)
475  // but this is simpler to reason about.
476  if (currentRoot != newrt) {
477  auto insertRet = cacheAnchors.insert(std::make_pair(newrt, CacheEntry()));
478  CacheIterator ret = insertRet.first;
479 
480  ret->second.entered = true;
481  ret->second.tree = tree;
482  ret->second.flags = CacheEntry::DIRTY;
483 
484  if (insertRet.second) {
485  // An insert took place
486  cachedCoinsUsage += ret->second.tree.DynamicMemoryUsage();
487  }
488 
489  hash = newrt;
490  }
491 }
492 
493 template<> void CCoinsViewCache::PushAnchor(const SaplingMerkleTree &tree)
494 {
495  AbstractPushAnchor<SaplingMerkleTree, CAnchorsSaplingMap, CAnchorsSaplingMap::iterator, CAnchorsSaplingCacheEntry>(
496  tree,
499  );
500 }
501 
502 template<>
504  const uint256 &currentRoot,
505  SaplingMerkleTree &tree
506 )
507 {
508  assert(GetSaplingAnchorAt(currentRoot, tree));
509 }
510 
511 template<typename Tree, typename Cache, typename CacheEntry>
513  const uint256 &newrt,
514  Cache &cacheAnchors,
515  uint256 &hash
516 )
517 {
518  auto currentRoot = GetBestAnchor();
519 
520  // Blocks might not change the commitment tree, in which
521  // case restoring the "old" anchor during a reorg must
522  // have no effect.
523  if (currentRoot != newrt) {
524  // Bring the current best anchor into our local cache
525  // so that its tree exists in memory.
526  {
527  Tree tree;
528  BringBestAnchorIntoCache(currentRoot, tree);
529  }
530 
531  // Mark the anchor as unentered, removing it from view
532  cacheAnchors[currentRoot].entered = false;
533 
534  // Mark the cache entry as dirty so it's propagated
535  cacheAnchors[currentRoot].flags = CacheEntry::DIRTY;
536 
537  // Mark the new root as the best anchor
538  hash = newrt;
539  }
540 }
541 
543  AbstractPopAnchor<SaplingMerkleTree, CAnchorsSaplingMap, CAnchorsSaplingCacheEntry>(
544  newrt,
547  );
548 }
549 
550 void CCoinsViewCache::SetNullifiers(const CTransaction& tx, bool spent) {
551  if (tx.sapData) {
552  for (const SpendDescription& spendDescription : tx.sapData->vShieldedSpend) {
553  std::pair<CNullifiersMap::iterator, bool> ret = cacheSaplingNullifiers.insert(
554  std::make_pair(spendDescription.nullifier, CNullifiersCacheEntry()));
555  ret.first->second.entered = spent;
556  ret.first->second.flags |= CNullifiersCacheEntry::DIRTY;
557  }
558  }
559 }
560 
564  return hashSaplingAnchor;
565 }
566 
568 {
569  if (tx.IsShieldedTx()) {
570  for (const SpendDescription &spendDescription : tx.sapData->vShieldedSpend) {
571  if (GetNullifier(spendDescription.nullifier)) // Prevent double spends
572  return false;
573 
574  SaplingMerkleTree tree;
575  if (!GetSaplingAnchorAt(spendDescription.anchor, tree)) {
576  return false;
577  }
578  }
579  }
580 
581  return true;
582 }
583 
584 bool CCoinsViewCache::GetUTXOCoin(const COutPoint& outpoint, Coin& coin) const
585 {
586  return GetCoin(outpoint, coin) && !coin.IsSpent();
587 }
int64_t CAmount
Amount in PIV (Can be negative)
Definition: amount.h:13
uint32_t n
Definition: transaction.h:36
CCoinsView backed by another CCoinsView.
Definition: coins.h:250
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashSaplingAnchor, CAnchorsSaplingMap &mapSaplingAnchors, CNullifiersMap &mapSaplingNullifiers) override
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:42
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether we have data for a given outpoint.
Definition: coins.cpp:35
bool GetNullifier(const uint256 &nullifier) const override
Determine whether a nullifier is spent or not.
Definition: coins.cpp:51
CCoinsViewCursor * Cursor() const override
Get a cursor to iterate over the whole state.
Definition: coins.cpp:39
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:34
size_t EstimateSize() const override
Estimate database size (0 if not implemented)
Definition: coins.cpp:40
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:36
uint256 GetBestAnchor() const override
Get the current "tip" or the latest anchored tree root in the chain.
Definition: coins.cpp:52
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const override
Retrieve the tree (Sapling) at a particular anchored root in the chain.
Definition: coins.cpp:50
void SetBackend(CCoinsView &viewIn)
Definition: coins.cpp:38
CCoinsView * base
Definition: coins.h:252
std::vector< uint256 > GetHeadBlocks() const override
Retrieve the range of blocks that may have been only partially written.
Definition: coins.cpp:37
CCoinsViewBacked(CCoinsView *viewIn)
Definition: coins.cpp:33
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:283
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashSaplingAnchor, CAnchorsSaplingMap &mapSaplingAnchors, CNullifiersMap &mapSaplingNullifiers) override
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:240
void SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr)
Spend a coin.
Definition: coins.cpp:133
uint256 hashSaplingAnchor
Definition: coins.h:293
CAmount GetValueIn(const CTransaction &tx) const
Amount of pivx coming in to a transaction Note that lightweight clients may not know anything besides...
Definition: coins.cpp:337
uint256 hashBlock
Make mutable so that we can "fill the cache" even from Get-methods declared as "const".
Definition: coins.h:289
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
Definition: coins.cpp:323
CCoinsViewCache(CCoinsView *baseIn)
Definition: coins.cpp:57
bool HaveInputs(const CTransaction &tx) const
Check whether all prevouts of the transaction are present in the UTXO set represented by this view.
Definition: coins.cpp:357
void BringBestAnchorIntoCache(const uint256 &currentRoot, Tree &tree)
Interface for bringing an anchor into the cache.
CAnchorsSaplingMap cacheSaplingAnchors
Definition: coins.h:294
void SetNullifiers(const CTransaction &tx, bool spent)
Definition: coins.cpp:550
void PushAnchor(const Tree &tree)
bool PruneInvalidEntries()
Definition: coins.cpp:393
CNullifiersMap cacheSaplingNullifiers
Definition: coins.h:295
void PopAnchor(const uint256 &rt)
Definition: coins.cpp:542
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool potential_overwrite)
Add a coin.
Definition: coins.cpp:94
void AbstractPopAnchor(const uint256 &newrt, Cache &cacheAnchors, uint256 &hash)
Generalized interface for popping anchors.
Definition: coins.cpp:512
unsigned int GetCacheSize() const
Calculate the size of the cache (in number of transaction outputs)
Definition: coins.cpp:332
bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const override
Retrieve the tree (Sapling) at a particular anchored root in the chain.
Definition: coins.cpp:422
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:173
size_t cachedCoinsUsage
Definition: coins.h:298
uint256 GetBestAnchor() const override
Get the current "tip" or the latest anchored tree root in the chain.
Definition: coins.cpp:561
void SetBestBlock(const uint256 &hashBlock)
Definition: coins.cpp:180
CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const
Definition: coins.cpp:66
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:84
bool GetUTXOCoin(const COutPoint &outpoint, Coin &coin) const
Get the coin and check if it's spent.
Definition: coins.cpp:584
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
Definition: coins.cpp:167
bool GetNullifier(const uint256 &nullifier) const override
Determine whether a nullifier is spent or not.
Definition: coins.cpp:446
int GetCoinDepthAtHeight(const COutPoint &output, int nHeight) const
Definition: coins.cpp:369
bool Flush()
Push the modifications applied to this cache to its base.
Definition: coins.cpp:309
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes)
Definition: coins.cpp:59
bool HaveShieldedRequirements(const CTransaction &tx) const
Check whether all sapling spend requirements (anchors/nullifiers) are satisfied.
Definition: coins.cpp:567
CAmount GetTotalAmount() const
Definition: coins.cpp:377
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether we have data for a given outpoint.
Definition: coins.cpp:161
CCoinsMap cacheCoins
Definition: coins.h:290
void AbstractPushAnchor(const Tree &tree, Cache &cacheAnchors, uint256 &hash)
Generalized interface for pushing anchors.
Definition: coins.cpp:461
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to a Coin in the cache, or a pruned one if not found.
Definition: coins.cpp:151
Cursor for iterating over CoinsView state.
Definition: coins.h:181
Abstract view on the open txout dataset.
Definition: coins.h:201
virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashSaplingAnchor, CAnchorsSaplingMap &mapSaplingAnchors, CNullifiersMap &mapSaplingNullifiers)
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:22
virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:16
virtual bool GetNullifier(const uint256 &nullifier) const
Determine whether a nullifier is spent or not.
Definition: coins.cpp:30
virtual uint256 GetBestAnchor() const
Get the current "tip" or the latest anchored tree root in the chain.
Definition: coins.cpp:31
virtual CCoinsViewCursor * Cursor() const
Get a cursor to iterate over the whole state.
Definition: coins.cpp:20
virtual std::vector< uint256 > GetHeadBlocks() const
Retrieve the range of blocks that may have been only partially written.
Definition: coins.cpp:19
virtual bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const
Retrieve the tree (Sapling) at a particular anchored root in the chain.
Definition: coins.cpp:29
virtual bool HaveCoin(const COutPoint &outpoint) const
Just check whether we have data for a given outpoint.
Definition: coins.cpp:17
virtual size_t EstimateSize() const
Estimate database size (0 if not implemented)
Definition: coins.h:234
virtual uint256 GetBestBlock() const
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:18
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:72
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:244
bool HasZerocoinSpendInputs() const
std::vector< CTxIn > vin
Definition: transaction.h:270
bool IsShieldedTx() const
Definition: transaction.h:319
const uint256 & GetHash() const
Definition: transaction.h:301
CAmount GetShieldedValueIn() const
bool IsCoinBase() const
Definition: transaction.h:376
Optional< SaplingTxData > sapData
Definition: transaction.h:275
bool IsCoinStake() const
std::vector< CTxOut > vout
Definition: transaction.h:271
An input of a transaction.
Definition: transaction.h:94
bool IsZerocoinSpend() const
Definition: transaction.cpp:43
uint32_t nSequence
Definition: transaction.h:98
bool IsZerocoinPublicSpend() const
Definition: transaction.cpp:48
COutPoint prevout
Definition: transaction.h:96
An output of a transaction.
Definition: transaction.h:137
CAmount nValue
Definition: transaction.h:139
A UTXO entry.
Definition: coins.h:32
CTxOut out
unspent transaction output
Definition: coins.h:41
bool IsSpent() const
Definition: coins.h:86
uint32_t nHeight
at which height the containing transaction was included in the active block chain
Definition: coins.h:44
SaltedIdHasher()
Definition: coins.cpp:55
A shielded input to a transaction.
uint256 anchor
A Merkle root of the Sapling note commitment tree at some block height in the past.
uint256 nullifier
The nullifier of the input note.
bool IsNull() const
Definition: uint256.h:36
256-bit opaque blob.
Definition: uint256.h:138
void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight, bool check, bool fSkipInvalid)
Utility function to add all of a transaction's outputs to a cache.
Definition: coins.cpp:116
void BatchWriteAnchors(Map &mapAnchors, Map &cacheAnchors, size_t &cachedCoinsUsage)
Definition: coins.cpp:186
const Coin & AccessByTxid(const CCoinsViewCache &view, const uint256 &txid)
Utility function to find any unspent output with a given txid.
Definition: coins.cpp:409
void BatchWriteNullifiers(CNullifiersMap &mapNullifiers, CNullifiersMap &cacheNullifiers)
Definition: coins.cpp:218
std::unordered_map< uint256, CAnchorsSaplingCacheEntry, SaltedIdHasher > CAnchorsSaplingMap
Definition: coins.h:174
std::unordered_map< COutPoint, CCoinsCacheEntry, SaltedOutpointHasher > CCoinsMap
Definition: coins.h:177
std::unordered_map< uint256, CNullifiersCacheEntry, SaltedIdHasher > CNullifiersMap
Definition: coins.h:175
bool LoadOutpoints()
Definition: invalid.cpp:27
std::set< COutPoint > setInvalidOutPoints
Definition: invalid.cpp:14
bool ContainsOutPoint(const COutPoint &out)
Definition: invalid.cpp:57
Definition: uint256.h:212
uint64_t GetRand(uint64_t nMax) noexcept
Definition: random.cpp:586
unsigned int GetSerializeSize(const std::array< T, N > &item)
array
Definition: serialize.h:847
Definition: coins.h:150
Definition: coins.h:134
unsigned char flags
Definition: coins.h:136
Coin coin
Definition: coins.h:135
@ FRESH
Definition: coins.h:140
@ DIRTY
Definition: coins.h:139
Definition: coins.h:163
unsigned char flags
Definition: coins.h:165
bool entered
Definition: coins.h:164
@ DIRTY
Definition: coins.h:168
const uint256 UINT256_ZERO
constant uint256 instances
Definition: uint256.h:175