Fabcoin Core  0.16.2
P2P Digital Currency
coins.cpp
Go to the documentation of this file.
1 // Copyright (c) 2012-2017 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 <memusage.h>
9 #include <random.h>
10 
11 #include <assert.h>
12 
13 bool CCoinsView::GetCoin(const COutPoint &outpoint, Coin &coin) const { return false; }
15 std::vector<uint256> CCoinsView::GetHeadBlocks() const { return std::vector<uint256>(); }
16 bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
17 CCoinsViewCursor *CCoinsView::Cursor() const { return 0; }
18 
19 bool CCoinsView::HaveCoin(const COutPoint &outpoint) const
20 {
21  Coin coin;
22  return GetCoin(outpoint, coin);
23 }
24 
26 bool CCoinsViewBacked::GetCoin(const COutPoint &outpoint, Coin &coin) const { return base->GetCoin(outpoint, coin); }
27 bool CCoinsViewBacked::HaveCoin(const COutPoint &outpoint) const { return base->HaveCoin(outpoint); }
29 std::vector<uint256> CCoinsViewBacked::GetHeadBlocks() const { return base->GetHeadBlocks(); }
30 void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
31 bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
33 size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); }
34 
35 SaltedOutpointHasher::SaltedOutpointHasher() : k0(GetRand(std::numeric_limits<uint64_t>::max())), k1(GetRand(std::numeric_limits<uint64_t>::max())) {}
36 
37 CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), cachedCoinsUsage(0) {}
38 
40  return memusage::DynamicUsage(cacheCoins) + cachedCoinsUsage;
41 }
42 
43 CCoinsMap::iterator CCoinsViewCache::FetchCoin(const COutPoint &outpoint) const {
44  CCoinsMap::iterator it = cacheCoins.find(outpoint);
45  if (it != cacheCoins.end())
46  return it;
47  Coin tmp;
48  if (!base->GetCoin(outpoint, tmp))
49  return cacheCoins.end();
50  CCoinsMap::iterator ret = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::forward_as_tuple(std::move(tmp))).first;
51  if (ret->second.coin.IsSpent()) {
52  // The parent only has an empty entry for this outpoint; we can consider our
53  // version as fresh.
54  ret->second.flags = CCoinsCacheEntry::FRESH;
55  }
56  cachedCoinsUsage += ret->second.coin.DynamicMemoryUsage();
57  return ret;
58 }
59 
60 bool CCoinsViewCache::GetCoin(const COutPoint &outpoint, Coin &coin) const {
61  CCoinsMap::const_iterator it = FetchCoin(outpoint);
62  if (it != cacheCoins.end()) {
63  coin = it->second.coin;
64  return !coin.IsSpent();
65  }
66  return false;
67 }
68 
69 void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possible_overwrite) {
70  assert(!coin.IsSpent());
71  if (coin.out.scriptPubKey.IsUnspendable()) return;
72  CCoinsMap::iterator it;
73  bool inserted;
74  std::tie(it, inserted) = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::tuple<>());
75  bool fresh = false;
76  if (!inserted) {
77  cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
78  }
79  if (!possible_overwrite) {
80  if (!it->second.coin.IsSpent()) {
81  throw std::logic_error("Adding new coin that replaces non-pruned entry");
82  }
83  fresh = !(it->second.flags & CCoinsCacheEntry::DIRTY);
84  }
85  it->second.coin = std::move(coin);
86  it->second.flags |= CCoinsCacheEntry::DIRTY | (fresh ? CCoinsCacheEntry::FRESH : 0);
87  cachedCoinsUsage += it->second.coin.DynamicMemoryUsage();
88 }
89 
90 void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight, bool check) {
91  bool fCoinbase = tx.IsCoinBase();
92  const uint256& txid = tx.GetHash();
93  for (size_t i = 0; i < tx.vout.size(); ++i) {
94  bool overwrite = check ? cache.HaveCoin(COutPoint(txid, i)) : fCoinbase;
95  // Always set the possible_overwrite flag to AddCoin for coinbase txn, in order to correctly
96  // deal with the pre-BIP30 occurrences of duplicate coinbase transactions.
97  cache.AddCoin(COutPoint(txid, i), Coin(tx.vout[i], nHeight, fCoinbase), overwrite);
98  }
99 }
100 
101 bool CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
102  CCoinsMap::iterator it = FetchCoin(outpoint);
103  if (it == cacheCoins.end()) return false;
104  cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
105  if (moveout) {
106  *moveout = std::move(it->second.coin);
107  }
108  if (it->second.flags & CCoinsCacheEntry::FRESH) {
109  cacheCoins.erase(it);
110  } else {
111  it->second.flags |= CCoinsCacheEntry::DIRTY;
112  it->second.coin.Clear();
113  }
114  return true;
115 }
116 
117 static const Coin coinEmpty;
118 
119 const Coin& CCoinsViewCache::AccessCoin(const COutPoint &outpoint) const {
120  CCoinsMap::const_iterator it = FetchCoin(outpoint);
121  if (it == cacheCoins.end()) {
122  return coinEmpty;
123  } else {
124  return it->second.coin;
125  }
126 }
127 
128 bool CCoinsViewCache::HaveCoin(const COutPoint &outpoint) const {
129  CCoinsMap::const_iterator it = FetchCoin(outpoint);
130  return (it != cacheCoins.end() && !it->second.coin.IsSpent());
131 }
132 
133 bool CCoinsViewCache::HaveCoinInCache(const COutPoint &outpoint) const {
134  CCoinsMap::const_iterator it = cacheCoins.find(outpoint);
135  return (it != cacheCoins.end() && !it->second.coin.IsSpent());
136 }
137 
139  if (hashBlock.IsNull())
141  return hashBlock;
142 }
143 
144 void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
145  hashBlock = hashBlockIn;
146 }
147 
148 bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
149  for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
150  if (it->second.flags & CCoinsCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization).
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  } else {
169  // Assert that the child cache entry was not marked FRESH if the
170  // parent cache entry has unspent outputs. If this ever happens,
171  // it means the FRESH flag was misapplied and there is a logic
172  // error in the calling code.
173  if ((it->second.flags & CCoinsCacheEntry::FRESH) && !itUs->second.coin.IsSpent())
174  throw std::logic_error("FRESH flag misapplied to cache entry for base transaction with spendable outputs");
175 
176  // Found the entry in the parent cache
177  if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coin.IsSpent()) {
178  // The grandparent does not have an entry, and the child is
179  // modified and being pruned. This means we can just delete
180  // it from the parent.
181  cachedCoinsUsage -= itUs->second.coin.DynamicMemoryUsage();
182  cacheCoins.erase(itUs);
183  } else {
184  // A normal modification.
185  cachedCoinsUsage -= itUs->second.coin.DynamicMemoryUsage();
186  itUs->second.coin = std::move(it->second.coin);
187  cachedCoinsUsage += itUs->second.coin.DynamicMemoryUsage();
188  itUs->second.flags |= CCoinsCacheEntry::DIRTY;
189  // NOTE: It is possible the child has a FRESH flag here in
190  // the event the entry we found in the parent is pruned. But
191  // we must not copy that FRESH flag to the parent as that
192  // pruned state likely still needs to be communicated to the
193  // grandparent.
194  }
195  }
196  }
197  CCoinsMap::iterator itOld = it++;
198  mapCoins.erase(itOld);
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(), SER_NETWORK, PROTOCOL_VERSION);
249 static const size_t MAX_OUTPUTS_PER_BLOCK = dgpMaxBlockWeight / MIN_TRANSACTION_OUTPUT_WEIGHT;
250 //??? static const size_t MAX_OUTPUTS_PER_BLOCK = MAX_BLOCK_WEIGHT / MIN_TRANSACTION_OUTPUT_WEIGHT;
251 
252 const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid)
253 {
254  COutPoint iter(txid, 0);
255  while (iter.n < MAX_OUTPUTS_PER_BLOCK) {
256  const Coin& alternate = view.AccessCoin(iter);
257  if (!alternate.IsSpent()) return alternate;
258  ++iter.n;
259  }
260  return coinEmpty;
261 }
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:28
CAmount nValue
Definition: transaction.h:134
const Coin & AccessByTxid(const CCoinsViewCache &view, const uint256 &txid)
Utility function to find any unspent output with a given txid.
Definition: coins.cpp:252
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool potential_overwrite)
Add a coin.
Definition: coins.cpp:69
CCoinsViewCache(CCoinsView *baseIn)
Definition: coins.cpp:37
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
Definition: coins.cpp:133
Definition: coins.h:103
bool Flush()
Push the modifications applied to this cache to its base.
Definition: coins.cpp:204
void SetBackend(CCoinsView &viewIn)
Definition: coins.cpp:30
A UTXO entry.
Definition: coins.h:29
size_t GetSerializeSize(const T &t, int nType, int nVersion=0)
Definition: serialize.h:989
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
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:29
virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock)
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:16
unsigned int GetCacheSize() const
Calculate the size of the cache (in number of transaction outputs)
Definition: coins.cpp:220
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:90
bool IsSpent() const
Definition: coins.h:75
std::hash for asio::adress
Definition: Common.h:323
assert(len-trim+(2 *lenIndices)<=WIDTH)
CCoinsViewCursor * Cursor() const override
Get a cursor to iterate over the whole state.
Definition: coins.cpp:32
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:148
virtual CCoinsViewCursor * Cursor() const
Get a cursor to iterate over the whole state.
Definition: coins.cpp:17
bool SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr)
Spend a coin.
Definition: coins.cpp:101
const std::vector< CTxIn > vin
Definition: transaction.h:292
Definition: coins.h:109
virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:13
int64_t CAmount
Amount in lius (Can be negative)
Definition: amount.h:15
void SetBestBlock(const uint256 &hashBlock)
Definition: coins.cpp:144
virtual std::vector< uint256 > GetHeadBlocks() const
Retrieve the range of blocks that may have been only partially written.
Definition: coins.cpp:15
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:31
virtual uint256 GetBestBlock() const
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:14
Abstract view on the open txout dataset.
Definition: coins.h:145
bool IsNull() const
Definition: uint256.h:38
CCoinsView * base
Definition: coins.h:185
ExecStats::duration max
Definition: ExecStats.cpp:36
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:293
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:119
#define k0
Definition: ripemd.cpp:18
An output of a transaction.
Definition: transaction.h:131
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:25
CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const
Definition: coins.cpp:43
size_t DynamicMemoryUsage() const
Definition: coins.h:79
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:138
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
Definition: coins.cpp:27
256-bit opaque blob.
Definition: uint256.h:132
uint256 hashBlock
Make mutable so that we can "fill the cache" even from Get-methods declared as "const".
Definition: coins.h:208
virtual bool HaveCoin(const COutPoint &outpoint) const
Just check whether a given outpoint is unspent.
Definition: coins.cpp:19
virtual size_t EstimateSize() const
Estimate database size (0 if not implemented)
Definition: coins.h:177
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:60
Definition: coins.h:110
CAmount GetValueIn(const CTransaction &tx) const
Amount of fabcoins coming in to a transaction Note that lightweight clients may not know anything bes...
Definition: coins.cpp:224
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
Definition: coins.cpp:211
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:26
#define k1
Definition: ripemd.cpp:19
size_t cachedCoinsUsage
Definition: coins.h:212
bool IsCoinBase() const
Definition: transaction.h:349
const uint256 & GetHash() const
Definition: transaction.h:325
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:275
CCoinsView backed by another CCoinsView.
Definition: coins.h:182
size_t EstimateSize() const override
Estimate database size (0 if not implemented)
Definition: coins.cpp:33
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:352
unsigned int dgpMaxBlockWeight
The maximum allowed weight for a block, see BIP 141 (network rule)
Definition: consensus.cpp:8
Coin coin
Definition: coins.h:105
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes)
Definition: coins.cpp:39
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
Definition: coins.cpp:128
Cursor for iterating over CoinsView state.
Definition: coins.h:125