Dogecoin Core  1.14.2
P2P Digital Currency
coins.cpp
Go to the documentation of this file.
1 // Copyright (c) 2012-2016 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 "memusage.h"
8 #include "random.h"
9 
10 #include <assert.h>
11 
17 void CCoins::CalcMaskSize(unsigned int &nBytes, unsigned int &nNonzeroBytes) const {
18  unsigned int nLastUsedByte = 0;
19  for (unsigned int b = 0; 2+b*8 < vout.size(); b++) {
20  bool fZero = true;
21  for (unsigned int i = 0; i < 8 && 2+b*8+i < vout.size(); i++) {
22  if (!vout[2+b*8+i].IsNull()) {
23  fZero = false;
24  continue;
25  }
26  }
27  if (!fZero) {
28  nLastUsedByte = b + 1;
29  nNonzeroBytes++;
30  }
31  }
32  nBytes += nLastUsedByte;
33 }
34 
35 bool CCoins::Spend(uint32_t nPos)
36 {
37  if (nPos >= vout.size() || vout[nPos].IsNull())
38  return false;
39  vout[nPos].SetNull();
40  Cleanup();
41  return true;
42 }
43 
44 bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; }
45 bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; }
47 bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
48 CCoinsViewCursor *CCoinsView::Cursor() const { return 0; }
49 
50 
52 bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); }
53 bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); }
55 void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
56 bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
58 
59 SaltedTxidHasher::SaltedTxidHasher() : k0(GetRand(std::numeric_limits<uint64_t>::max())), k1(GetRand(std::numeric_limits<uint64_t>::max())) {}
60 
61 CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false), cachedCoinsUsage(0) { }
62 
64 {
65  assert(!hasModifier);
66 }
67 
69  return memusage::DynamicUsage(cacheCoins) + cachedCoinsUsage;
70 }
71 
72 CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const {
73  CCoinsMap::iterator it = cacheCoins.find(txid);
74  if (it != cacheCoins.end())
75  return it;
76  CCoins tmp;
77  if (!base->GetCoins(txid, tmp))
78  return cacheCoins.end();
79  CCoinsMap::iterator ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry())).first;
80  tmp.swap(ret->second.coins);
81  if (ret->second.coins.IsPruned()) {
82  // The parent only has an empty entry for this txid; we can consider our
83  // version as fresh.
84  ret->second.flags = CCoinsCacheEntry::FRESH;
85  }
86  cachedCoinsUsage += ret->second.coins.DynamicMemoryUsage();
87  return ret;
88 }
89 
90 bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
91  CCoinsMap::const_iterator it = FetchCoins(txid);
92  if (it != cacheCoins.end()) {
93  coins = it->second.coins;
94  return true;
95  }
96  return false;
97 }
98 
100  assert(!hasModifier);
101  std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry()));
102  size_t cachedCoinUsage = 0;
103  if (ret.second) {
104  if (!base->GetCoins(txid, ret.first->second.coins)) {
105  // The parent view does not have this entry; mark it as fresh.
106  ret.first->second.coins.Clear();
107  ret.first->second.flags = CCoinsCacheEntry::FRESH;
108  } else if (ret.first->second.coins.IsPruned()) {
109  // The parent view only has a pruned entry for this; mark it as fresh.
110  ret.first->second.flags = CCoinsCacheEntry::FRESH;
111  }
112  } else {
113  cachedCoinUsage = ret.first->second.coins.DynamicMemoryUsage();
114  }
115  // Assume that whenever ModifyCoins is called, the entry will be modified.
116  ret.first->second.flags |= CCoinsCacheEntry::DIRTY;
117  return CCoinsModifier(*this, ret.first, cachedCoinUsage);
118 }
119 
120 /* ModifyNewCoins allows for faster coin modification when creating the new
121  * outputs from a transaction. It assumes that BIP 30 (no duplicate txids)
122  * applies and has already been tested for (or the test is not required due to
123  * BIP 34, height in coinbase). If we can assume BIP 30 then we know that any
124  * non-coinbase transaction we are adding to the UTXO must not already exist in
125  * the utxo unless it is fully spent. Thus we can check only if it exists DIRTY
126  * at the current level of the cache, in which case it is not safe to mark it
127  * FRESH (b/c then its spentness still needs to flushed). If it's not dirty and
128  * doesn't exist or is pruned in the current cache, we know it either doesn't
129  * exist or is pruned in parent caches, which is the definition of FRESH. The
130  * exception to this is the two historical violations of BIP 30 in the chain,
131  * both of which were coinbases. We do not mark these fresh so we we can ensure
132  * that they will still be properly overwritten when spent.
133  */
135  assert(!hasModifier);
136  std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry()));
137  if (!coinbase) {
138  // New coins must not already exist.
139  if (!ret.first->second.coins.IsPruned())
140  throw std::logic_error("ModifyNewCoins should not find pre-existing coins on a non-coinbase unless they are pruned!");
141 
142  if (!(ret.first->second.flags & CCoinsCacheEntry::DIRTY)) {
143  // If the coin is known to be pruned (have no unspent outputs) in
144  // the current view and the cache entry is not dirty, we know the
145  // coin also must be pruned in the parent view as well, so it is safe
146  // to mark this fresh.
147  ret.first->second.flags |= CCoinsCacheEntry::FRESH;
148  }
149  }
150  ret.first->second.coins.Clear();
151  ret.first->second.flags |= CCoinsCacheEntry::DIRTY;
152  return CCoinsModifier(*this, ret.first, 0);
153 }
154 
155 const CCoins* CCoinsViewCache::AccessCoins(const uint256 &txid) const {
156  CCoinsMap::const_iterator it = FetchCoins(txid);
157  if (it == cacheCoins.end()) {
158  return NULL;
159  } else {
160  return &it->second.coins;
161  }
162 }
163 
164 bool CCoinsViewCache::HaveCoins(const uint256 &txid) const {
165  CCoinsMap::const_iterator it = FetchCoins(txid);
166  // We're using vtx.empty() instead of IsPruned here for performance reasons,
167  // as we only care about the case where a transaction was replaced entirely
168  // in a reorganization (which wipes vout entirely, as opposed to spending
169  // which just cleans individual outputs).
170  return (it != cacheCoins.end() && !it->second.coins.vout.empty());
171 }
172 
174  CCoinsMap::const_iterator it = cacheCoins.find(txid);
175  return it != cacheCoins.end();
176 }
177 
179  if (hashBlock.IsNull())
181  return hashBlock;
182 }
183 
184 void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
185  hashBlock = hashBlockIn;
186 }
187 
188 bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
189  assert(!hasModifier);
190  for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
191  if (it->second.flags & CCoinsCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization).
192  CCoinsMap::iterator itUs = cacheCoins.find(it->first);
193  if (itUs == cacheCoins.end()) {
194  // The parent cache does not have an entry, while the child does
195  // We can ignore it if it's both FRESH and pruned in the child
196  if (!(it->second.flags & CCoinsCacheEntry::FRESH && it->second.coins.IsPruned())) {
197  // Otherwise we will need to create it in the parent
198  // and move the data up and mark it as dirty
199  CCoinsCacheEntry& entry = cacheCoins[it->first];
200  entry.coins.swap(it->second.coins);
203  // We can mark it FRESH in the parent if it was FRESH in the child
204  // Otherwise it might have just been flushed from the parent's cache
205  // and already exist in the grandparent
206  if (it->second.flags & CCoinsCacheEntry::FRESH)
208  }
209  } else {
210  // Assert that the child cache entry was not marked FRESH if the
211  // parent cache entry has unspent outputs. If this ever happens,
212  // it means the FRESH flag was misapplied and there is a logic
213  // error in the calling code.
214  if ((it->second.flags & CCoinsCacheEntry::FRESH) && !itUs->second.coins.IsPruned())
215  throw std::logic_error("FRESH flag misapplied to cache entry for base transaction with spendable outputs");
216 
217  // Found the entry in the parent cache
218  if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coins.IsPruned()) {
219  // The grandparent does not have an entry, and the child is
220  // modified and being pruned. This means we can just delete
221  // it from the parent.
222  cachedCoinsUsage -= itUs->second.coins.DynamicMemoryUsage();
223  cacheCoins.erase(itUs);
224  } else {
225  // A normal modification.
226  cachedCoinsUsage -= itUs->second.coins.DynamicMemoryUsage();
227  itUs->second.coins.swap(it->second.coins);
228  cachedCoinsUsage += itUs->second.coins.DynamicMemoryUsage();
229  itUs->second.flags |= CCoinsCacheEntry::DIRTY;
230  // NOTE: It is possible the child has a FRESH flag here in
231  // the event the entry we found in the parent is pruned. But
232  // we must not copy that FRESH flag to the parent as that
233  // pruned state likely still needs to be communicated to the
234  // grandparent.
235  }
236  }
237  }
238  CCoinsMap::iterator itOld = it++;
239  mapCoins.erase(itOld);
240  }
241  hashBlock = hashBlockIn;
242  return true;
243 }
244 
246  bool fOk = base->BatchWrite(cacheCoins, hashBlock);
247  cacheCoins.clear();
248  cachedCoinsUsage = 0;
249  return fOk;
250 }
251 
253 {
254  CCoinsMap::iterator it = cacheCoins.find(hash);
255  if (it != cacheCoins.end() && it->second.flags == 0) {
256  cachedCoinsUsage -= it->second.coins.DynamicMemoryUsage();
257  cacheCoins.erase(it);
258  }
259 }
260 
261 unsigned int CCoinsViewCache::GetCacheSize() const {
262  return cacheCoins.size();
263 }
264 
265 const CTxOut &CCoinsViewCache::GetOutputFor(const CTxIn& input) const
266 {
267  const CCoins* coins = AccessCoins(input.prevout.hash);
268  assert(coins && coins->IsAvailable(input.prevout.n));
269  return coins->vout[input.prevout.n];
270 }
271 
273 {
274  if (tx.IsCoinBase())
275  return 0;
276 
277  CAmount nResult = 0;
278  for (unsigned int i = 0; i < tx.vin.size(); i++)
279  nResult += GetOutputFor(tx.vin[i]).nValue;
280 
281  return nResult;
282 }
283 
285 {
286  if (!tx.IsCoinBase()) {
287  for (unsigned int i = 0; i < tx.vin.size(); i++) {
288  const COutPoint &prevout = tx.vin[i].prevout;
289  const CCoins* coins = AccessCoins(prevout.hash);
290  if (!coins || !coins->IsAvailable(prevout.n)) {
291  return false;
292  }
293  }
294  }
295  return true;
296 }
297 
298 double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight, CAmount &inChainInputValue) const
299 {
300  inChainInputValue = 0;
301  if (tx.IsCoinBase())
302  return 0.0;
303  double dResult = 0.0;
304  BOOST_FOREACH(const CTxIn& txin, tx.vin)
305  {
306  const CCoins* coins = AccessCoins(txin.prevout.hash);
307  assert(coins);
308  if (!coins->IsAvailable(txin.prevout.n)) continue;
309  if (coins->nHeight <= nHeight) {
310  dResult += (double)(coins->vout[txin.prevout.n].nValue) * (nHeight-coins->nHeight);
311  inChainInputValue += coins->vout[txin.prevout.n].nValue;
312  }
313  }
314  return tx.ComputePriority(dResult);
315 }
316 
317 CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_, size_t usage) : cache(cache_), it(it_), cachedCoinUsage(usage) {
318  assert(!cache.hasModifier);
319  cache.hasModifier = true;
320 }
321 
323 {
324  assert(cache.hasModifier);
325  cache.hasModifier = false;
326  it->second.coins.Cleanup();
327  cache.cachedCoinsUsage -= cachedCoinUsage; // Subtract the old usage
328  if ((it->second.flags & CCoinsCacheEntry::FRESH) && it->second.coins.IsPruned()) {
329  cache.cacheCoins.erase(it);
330  } else {
331  // If the coin still exists after the modification, add the new usage
332  cache.cachedCoinsUsage += it->second.coins.DynamicMemoryUsage();
333  }
334 }
335 
337 {
338 }
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:15
Pruned version of CTransaction: only retains metadata and unspent transaction outputs.
Definition: coins.h:75
bool Spend(uint32_t nPos)
mark a vout spent
Definition: coins.cpp:35
std::vector< CTxOut > vout
unspent transaction outputs; spent outputs are .IsNull(); spent outputs at the end of the array are d...
Definition: coins.h:81
void Cleanup()
remove spent outputs at the end of vout
Definition: coins.h:114
void CalcMaskSize(unsigned int &nBytes, unsigned int &nNonzeroBytes) const
calculate number of bytes for the bitmask, and its number of non-zero bytes each bit in the bitmask r...
Definition: coins.cpp:17
size_t DynamicMemoryUsage() const
Definition: coins.h:236
void swap(CCoins &to)
Definition: coins.h:129
bool IsAvailable(unsigned int nPos) const
check whether a particular output is still available
Definition: coins.h:223
int nHeight
at which height this transaction was included in the active block chain
Definition: coins.h:84
A reference to a mutable cache entry.
Definition: coins.h:356
CCoinsMap::iterator it
Definition: coins.h:359
CCoinsViewCache & cache
Definition: coins.h:358
size_t cachedCoinUsage
Definition: coins.h:360
CCoinsModifier(CCoinsViewCache &cache_, CCoinsMap::iterator it_, size_t usage)
Definition: coins.cpp:317
CCoinsView backed by another CCoinsView.
Definition: coins.h:333
CCoinsViewCursor * Cursor() const
Get a cursor to iterate over the whole state.
Definition: coins.cpp:57
uint256 GetBestBlock() const
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:54
bool GetCoins(const uint256 &txid, CCoins &coins) const
Retrieve the CCoins (unspent transaction outputs) for a given txid.
Definition: coins.cpp:52
void SetBackend(CCoinsView &viewIn)
Definition: coins.cpp:55
CCoinsView * base
Definition: coins.h:335
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock)
Do a bulk modification (multiple CCoins changes + BestBlock change).
Definition: coins.cpp:56
bool HaveCoins(const uint256 &txid) const
Just check whether we have data for a given txid.
Definition: coins.cpp:53
CCoinsViewBacked(CCoinsView *viewIn)
Definition: coins.cpp:51
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:372
uint256 GetBestBlock() const
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:178
CAmount GetValueIn(const CTransaction &tx) const
Amount of bitcoins coming in to a transaction Note that lightweight clients may not know anything bes...
Definition: coins.cpp:272
bool GetCoins(const uint256 &txid, CCoins &coins) const
Retrieve the CCoins (unspent transaction outputs) for a given txid.
Definition: coins.cpp:90
uint256 hashBlock
Make mutable so that we can "fill the cache" even from Get-methods declared as "const".
Definition: coins.h:382
bool hasModifier
Definition: coins.h:375
CCoinsViewCache(CCoinsView *baseIn)
Definition: coins.cpp:61
const CTxOut & GetOutputFor(const CTxIn &input) const
Definition: coins.cpp:265
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock)
Do a bulk modification (multiple CCoins changes + BestBlock change).
Definition: coins.cpp:188
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:284
bool HaveCoinsInCache(const uint256 &txid) const
Check if we have the given tx already loaded in this cache.
Definition: coins.cpp:173
~CCoinsViewCache()
Definition: coins.cpp:63
const CCoins * AccessCoins(const uint256 &txid) const
Return a pointer to CCoins in the cache, or NULL if not found.
Definition: coins.cpp:155
unsigned int GetCacheSize() const
Calculate the size of the cache (in number of transactions)
Definition: coins.cpp:261
CCoinsMap::const_iterator FetchCoins(const uint256 &txid) const
Definition: coins.cpp:72
size_t cachedCoinsUsage
Definition: coins.h:386
double GetPriority(const CTransaction &tx, int nHeight, CAmount &inChainInputValue) const
Return priority of tx at height nHeight.
Definition: coins.cpp:298
void SetBestBlock(const uint256 &hashBlock)
Definition: coins.cpp:184
bool HaveCoins(const uint256 &txid) const
Just check whether we have data for a given txid.
Definition: coins.cpp:164
void Uncache(const uint256 &txid)
Removes the transaction with the given hash from the cache, if it is not modified.
Definition: coins.cpp:252
CCoinsModifier ModifyCoins(const uint256 &txid)
Return a modifiable reference to a CCoins.
Definition: coins.cpp:99
bool Flush()
Push the modifications applied to this cache to its base.
Definition: coins.cpp:245
CCoinsModifier ModifyNewCoins(const uint256 &txid, bool coinbase)
Return a modifiable reference to a CCoins.
Definition: coins.cpp:134
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes)
Definition: coins.cpp:68
friend class CCoinsModifier
Definition: coins.h:472
CCoinsMap cacheCoins
Definition: coins.h:383
Cursor for iterating over CoinsView state.
Definition: coins.h:286
virtual ~CCoinsViewCursor()
Definition: coins.cpp:336
Abstract view on the open txout dataset.
Definition: coins.h:307
virtual CCoinsViewCursor * Cursor() const
Get a cursor to iterate over the whole state.
Definition: coins.cpp:48
virtual bool GetCoins(const uint256 &txid, CCoins &coins) const
Retrieve the CCoins (unspent transaction outputs) for a given txid.
Definition: coins.cpp:44
virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock)
Do a bulk modification (multiple CCoins changes + BestBlock change).
Definition: coins.cpp:47
virtual bool HaveCoins(const uint256 &txid) const
Just check whether we have data for a given txid.
Definition: coins.cpp:45
virtual uint256 GetBestBlock() const
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:46
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:20
uint32_t n
Definition: transaction.h:23
uint256 hash
Definition: transaction.h:22
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:308
bool IsCoinBase() const
Definition: transaction.h:383
const std::vector< CTxIn > vin
Definition: transaction.h:326
double ComputePriority(double dPriorityInputs, unsigned int nTxSize=0) const
Definition: transaction.cpp:95
An input of a transaction.
Definition: transaction.h:63
COutPoint prevout
Definition: transaction.h:65
An output of a transaction.
Definition: transaction.h:133
CAmount nValue
Definition: transaction.h:135
bool IsNull() const
Definition: uint256.h:32
256-bit opaque blob.
Definition: uint256.h:123
boost::unordered_map< uint256, CCoinsCacheEntry, SaltedTxidHasher > CCoinsMap
Definition: coins.h:282
uint64_t GetRand(uint64_t nMax)
Definition: random.cpp:153
Definition: coins.h:265
unsigned char flags
Definition: coins.h:267
@ FRESH
Definition: coins.h:271
@ DIRTY
Definition: coins.h:270
CCoins coins
Definition: coins.h:266
struct event_base * base
Definition: torcontrol.cpp:679