Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

coins.cpp
Go to the documentation of this file.
1 // Copyright (c) 2012-2015 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <coins.h>
6 
7 #include <consensus/consensus.h>
8 #include <random.h>
9 
10 bool CCoinsView::GetCoin(const COutPoint &outpoint, Coin &coin) const { return false; }
12 std::vector<uint256> CCoinsView::GetHeadBlocks() const { return std::vector<uint256>(); }
13 bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
14 CCoinsViewCursor *CCoinsView::Cursor() const { return nullptr; }
15 
16 bool CCoinsView::HaveCoin(const COutPoint &outpoint) const
17 {
18  Coin coin;
19  return GetCoin(outpoint, coin);
20 }
21 
23 bool CCoinsViewBacked::GetCoin(const COutPoint &outpoint, Coin &coin) const { return base->GetCoin(outpoint, coin); }
24 bool CCoinsViewBacked::HaveCoin(const COutPoint &outpoint) const { return base->HaveCoin(outpoint); }
26 std::vector<uint256> CCoinsViewBacked::GetHeadBlocks() const { return base->GetHeadBlocks(); }
27 void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
28 bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
30 size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); }
31 
32 SaltedOutpointHasher::SaltedOutpointHasher() : k0(GetRand(std::numeric_limits<uint64_t>::max())), k1(GetRand(std::numeric_limits<uint64_t>::max())) {}
33 
34 CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), cachedCoinsUsage(0) {}
35 
38 }
39 
40 CCoinsMap::iterator CCoinsViewCache::FetchCoin(const COutPoint &outpoint) const {
41  CCoinsMap::iterator it = cacheCoins.find(outpoint);
42  if (it != cacheCoins.end())
43  return it;
44  Coin tmp;
45  if (!base->GetCoin(outpoint, tmp))
46  return cacheCoins.end();
47  CCoinsMap::iterator ret = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::forward_as_tuple(std::move(tmp))).first;
48  if (ret->second.coin.IsSpent()) {
49  // The parent only has an empty entry for this outpoint; we can consider our
50  // version as fresh.
51  ret->second.flags = CCoinsCacheEntry::FRESH;
52  }
53  cachedCoinsUsage += ret->second.coin.DynamicMemoryUsage();
54  return ret;
55 }
56 
57 bool CCoinsViewCache::GetCoin(const COutPoint &outpoint, Coin &coin) const {
58  CCoinsMap::const_iterator it = FetchCoin(outpoint);
59  if (it != cacheCoins.end()) {
60  coin = it->second.coin;
61  return !coin.IsSpent();
62  }
63  return false;
64 }
65 
66 void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possible_overwrite) {
67  assert(!coin.IsSpent());
68  if (coin.out.scriptPubKey.IsUnspendable()) return;
69  CCoinsMap::iterator it;
70  bool inserted;
71  std::tie(it, inserted) = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::tuple<>());
72  bool fresh = false;
73  if (!inserted) {
74  cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
75  }
76  if (!possible_overwrite) {
77  if (!it->second.coin.IsSpent()) {
78  throw std::logic_error("Adding new coin that replaces non-pruned entry");
79  }
80  fresh = !(it->second.flags & CCoinsCacheEntry::DIRTY);
81  }
82  it->second.coin = std::move(coin);
83  it->second.flags |= CCoinsCacheEntry::DIRTY | (fresh ? CCoinsCacheEntry::FRESH : 0);
84  cachedCoinsUsage += it->second.coin.DynamicMemoryUsage();
85 }
86 
87 void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight, bool check) {
88  bool fCoinbase = tx.IsCoinBase();
89  const uint256& txid = tx.GetHash();
90  for (size_t i = 0; i < tx.vout.size(); ++i) {
91  bool overwrite = check ? cache.HaveCoin(COutPoint(txid, i)) : fCoinbase;
92  // Always set the possible_overwrite flag to AddCoin for coinbase txn, in order to correctly
93  // deal with the pre-BIP30 occurrences of duplicate coinbase transactions.
94  cache.AddCoin(COutPoint(txid, i), Coin(tx.vout[i], nHeight, fCoinbase), overwrite);
95  }
96 }
97 
98 bool CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
99  CCoinsMap::iterator it = FetchCoin(outpoint);
100  if (it == cacheCoins.end()) return false;
101  cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
102  if (moveout) {
103  *moveout = std::move(it->second.coin);
104  }
105  if (it->second.flags & CCoinsCacheEntry::FRESH) {
106  cacheCoins.erase(it);
107  } else {
108  it->second.flags |= CCoinsCacheEntry::DIRTY;
109  it->second.coin.Clear();
110  }
111  return true;
112 }
113 
114 static const Coin coinEmpty;
115 
116 const Coin& CCoinsViewCache::AccessCoin(const COutPoint &outpoint) const {
117  CCoinsMap::const_iterator it = FetchCoin(outpoint);
118  if (it == cacheCoins.end()) {
119  return coinEmpty;
120  } else {
121  return it->second.coin;
122  }
123 }
124 
125 bool CCoinsViewCache::HaveCoin(const COutPoint &outpoint) const {
126  CCoinsMap::const_iterator it = FetchCoin(outpoint);
127  return (it != cacheCoins.end() && !it->second.coin.IsSpent());
128 }
129 
130 bool CCoinsViewCache::HaveCoinInCache(const COutPoint &outpoint) const {
131  CCoinsMap::const_iterator it = cacheCoins.find(outpoint);
132  return (it != cacheCoins.end() && !it->second.coin.IsSpent());
133 }
134 
136  if (hashBlock.IsNull())
138  return hashBlock;
139 }
140 
141 void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
142  hashBlock = hashBlockIn;
143 }
144 
145 bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
146  for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end(); it = mapCoins.erase(it)) {
147  // Ignore non-dirty entries (optimization).
148  if (!(it->second.flags & CCoinsCacheEntry::DIRTY)) {
149  continue;
150  }
151  CCoinsMap::iterator itUs = cacheCoins.find(it->first);
152  if (itUs == cacheCoins.end()) {
153  // The parent cache does not have an entry, while the child does
154  // We can ignore it if it's both FRESH and pruned in the child
155  if (!(it->second.flags & CCoinsCacheEntry::FRESH && it->second.coin.IsSpent())) {
156  // Otherwise we will need to create it in the parent
157  // and move the data up and mark it as dirty
158  CCoinsCacheEntry& entry = cacheCoins[it->first];
159  entry.coin = std::move(it->second.coin);
162  // We can mark it FRESH in the parent if it was FRESH in the child
163  // Otherwise it might have just been flushed from the parent's cache
164  // and already exist in the grandparent
165  if (it->second.flags & CCoinsCacheEntry::FRESH) {
167  }
168  }
169  } else {
170  // Assert that the child cache entry was not marked FRESH if the
171  // parent cache entry has unspent outputs. If this ever happens,
172  // it means the FRESH flag was misapplied and there is a logic
173  // error in the calling code.
174  if ((it->second.flags & CCoinsCacheEntry::FRESH) && !itUs->second.coin.IsSpent()) {
175  throw std::logic_error("FRESH flag misapplied to cache entry for base transaction with spendable outputs");
176  }
177 
178  // Found the entry in the parent cache
179  if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coin.IsSpent()) {
180  // The grandparent does not have an entry, and the child is
181  // modified and being pruned. This means we can just delete
182  // it from the parent.
183  cachedCoinsUsage -= itUs->second.coin.DynamicMemoryUsage();
184  cacheCoins.erase(itUs);
185  } else {
186  // A normal modification.
187  cachedCoinsUsage -= itUs->second.coin.DynamicMemoryUsage();
188  itUs->second.coin = std::move(it->second.coin);
189  cachedCoinsUsage += itUs->second.coin.DynamicMemoryUsage();
190  itUs->second.flags |= CCoinsCacheEntry::DIRTY;
191  // NOTE: It is possible the child has a FRESH flag here in
192  // the event the entry we found in the parent is pruned. But
193  // we must not copy that FRESH flag to the parent as that
194  // pruned state likely still needs to be communicated to the
195  // grandparent.
196  }
197  }
198  }
199  hashBlock = hashBlockIn;
200  return true;
201 }
202 
204  bool fOk = base->BatchWrite(cacheCoins, hashBlock);
205  cacheCoins.clear();
206  cachedCoinsUsage = 0;
207  return fOk;
208 }
209 
211 {
212  CCoinsMap::iterator it = cacheCoins.find(hash);
213  if (it != cacheCoins.end() && it->second.flags == 0) {
214  cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
215  cacheCoins.erase(it);
216  }
217 }
218 
219 unsigned int CCoinsViewCache::GetCacheSize() const {
220  return cacheCoins.size();
221 }
222 
224 {
225  if (tx.IsCoinBase())
226  return 0;
227 
228  CAmount nResult = 0;
229  for (unsigned int i = 0; i < tx.vin.size(); i++)
230  nResult += AccessCoin(tx.vin[i].prevout).out.nValue;
231 
232  return nResult;
233 }
234 
236 {
237  if (!tx.IsCoinBase()) {
238  for (unsigned int i = 0; i < tx.vin.size(); i++) {
239  if (!HaveCoin(tx.vin[i].prevout)) {
240  return false;
241  }
242  }
243  }
244  return true;
245 }
246 
247 static const size_t MAX_OUTPUTS_PER_BLOCK = MaxBlockSize(true) / ::GetSerializeSize(CTxOut(), SER_NETWORK, PROTOCOL_VERSION); // TODO: merge with similar definition in undo.h.
248 
249 const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid)
250 {
251  COutPoint iter(txid, 0);
252  while (iter.n < MAX_OUTPUTS_PER_BLOCK) {
253  const Coin& alternate = view.AccessCoin(iter);
254  if (!alternate.IsSpent()) return alternate;
255  ++iter.n;
256  }
257  return coinEmpty;
258 }
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:25
CAmount nValue
Definition: transaction.h:147
const Coin & AccessByTxid(const CCoinsViewCache &view, const uint256 &txid)
Utility function to find any unspent output with a given txid.
Definition: coins.cpp:249
bool IsSpent() const
Definition: coins.h:75
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool potential_overwrite)
Add a coin.
Definition: coins.cpp:66
CCoinsViewCache(CCoinsView *baseIn)
Definition: coins.cpp:34
Definition: coins.h:103
virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:10
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or a pruned one if not found.
Definition: coins.cpp:116
bool Flush()
Push the modifications applied to this cache to its base.
Definition: coins.cpp:203
void SetBackend(CCoinsView &viewIn)
Definition: coins.cpp:27
A UTXO entry.
Definition: coins.h:29
unsigned int MaxBlockSize(bool fDIP0001Active)
Definition: consensus.h:12
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
Definition: memusage.h:27
size_t GetSerializeSize(const T &t, int nType, int nVersion=0)
Definition: serialize.h:1295
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes)
Definition: coins.cpp:36
CTxOut out
unspent transaction output
Definition: coins.h:33
std::vector< uint256 > GetHeadBlocks() const override
Retrieve the range of blocks that may have been only partially written.
Definition: coins.cpp:26
virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock)
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:13
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
Definition: coins.cpp:130
void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight, bool check)
Utility function to add all of a transaction&#39;s outputs to a cache.
Definition: coins.cpp:87
virtual CCoinsViewCursor * Cursor() const
Get a cursor to iterate over the whole state.
Definition: coins.cpp:14
Definition: box.hpp:161
virtual bool HaveCoin(const COutPoint &outpoint) const
Just check whether a given outpoint is unspent.
Definition: coins.cpp:16
CCoinsViewCursor * Cursor() const override
Get a cursor to iterate over the whole state.
Definition: coins.cpp:29
static const Coin coinEmpty
Definition: coins.cpp:114
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:235
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:145
bool IsNull() const
Definition: uint256.h:33
bool IsCoinBase() const
Definition: transaction.h:272
bool SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr)
Spend a coin.
Definition: coins.cpp:98
const std::vector< CTxIn > vin
Definition: transaction.h:215
Definition: coins.h:109
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
void SetBestBlock(const uint256 &hashBlock)
Definition: coins.cpp:141
unsigned int GetCacheSize() const
Calculate the size of the cache (in number of transaction outputs)
Definition: coins.cpp:219
CCoinsMap cacheCoins
Definition: coins.h:209
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:28
Abstract view on the open txout dataset.
Definition: coins.h:145
CCoinsView * base
Definition: coins.h:185
const uint256 & GetHash() const
Definition: transaction.h:256
uint32_t n
Definition: transaction.h:30
std::unordered_map< COutPoint, CCoinsCacheEntry, SaltedOutpointHasher > CCoinsMap
Definition: coins.h:122
const std::vector< CTxOut > vout
Definition: transaction.h:216
static const unsigned char k1[32]
virtual std::vector< uint256 > GetHeadBlocks() const
Retrieve the range of blocks that may have been only partially written.
Definition: coins.cpp:12
An output of a transaction.
Definition: transaction.h:144
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:26
CCoinsViewBacked(CCoinsView *viewIn)
Definition: coins.cpp:22
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:135
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
Definition: coins.cpp:24
256-bit opaque blob.
Definition: uint256.h:123
uint256 hashBlock
Make mutable so that we can "fill the cache" even from Get-methods declared as "const".
Definition: coins.h:208
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:57
Definition: coins.h:110
virtual size_t EstimateSize() const
Estimate database size (0 if not implemented)
Definition: coins.h:177
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:14
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
Definition: coins.cpp:210
virtual uint256 GetBestBlock() const
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:11
size_t DynamicMemoryUsage() const
Definition: coins.h:79
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:23
CAmount GetValueIn(const CTransaction &tx) const
Amount of dash coming in to a transaction Note that lightweight clients may not know anything besides...
Definition: coins.cpp:223
static const size_t MAX_OUTPUTS_PER_BLOCK
Definition: coins.cpp:247
size_t cachedCoinsUsage
Definition: coins.h:212
CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const
Definition: coins.cpp:40
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:198
CCoinsView backed by another CCoinsView.
Definition: coins.h:182
size_t EstimateSize() const override
Estimate database size (0 if not implemented)
Definition: coins.cpp:30
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:201
unsigned char flags
Definition: coins.h:106
uint64_t GetRand(uint64_t nMax)
Definition: random.cpp:354
Coin coin
Definition: coins.h:105
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
Definition: coins.cpp:125
Cursor for iterating over CoinsView state.
Definition: coins.h:125
Released under the MIT license