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