Bitcoin Core  26.99.0
P2P Digital Currency
coins.cpp
Go to the documentation of this file.
1 // Copyright (c) 2012-2022 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 <logging.h>
9 #include <random.h>
10 #include <util/trace.h>
11 
12 bool CCoinsView::GetCoin(const COutPoint &outpoint, Coin &coin) const { return false; }
14 std::vector<uint256> CCoinsView::GetHeadBlocks() const { return std::vector<uint256>(); }
15 bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, bool erase) { return false; }
16 std::unique_ptr<CCoinsViewCursor> CCoinsView::Cursor() const { return nullptr; }
17 
18 bool CCoinsView::HaveCoin(const COutPoint &outpoint) const
19 {
20  Coin coin;
21  return GetCoin(outpoint, coin);
22 }
23 
25 bool CCoinsViewBacked::GetCoin(const COutPoint &outpoint, Coin &coin) const { return base->GetCoin(outpoint, coin); }
26 bool CCoinsViewBacked::HaveCoin(const COutPoint &outpoint) const { return base->HaveCoin(outpoint); }
28 std::vector<uint256> CCoinsViewBacked::GetHeadBlocks() const { return base->GetHeadBlocks(); }
29 void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
30 bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, bool erase) { return base->BatchWrite(mapCoins, hashBlock, erase); }
31 std::unique_ptr<CCoinsViewCursor> CCoinsViewBacked::Cursor() const { return base->Cursor(); }
32 size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); }
33 
34 CCoinsViewCache::CCoinsViewCache(CCoinsView* baseIn, bool deterministic) :
35  CCoinsViewBacked(baseIn), m_deterministic(deterministic),
36  cacheCoins(0, SaltedOutpointHasher(/*deterministic=*/deterministic), CCoinsMap::key_equal{}, &m_cache_coins_memory_resource)
37 {}
38 
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("Attempted to overwrite an unspent coin (when possible_overwrite is false)");
82  }
83  // If the coin exists in this cache as a spent coin and is DIRTY, then
84  // its spentness hasn't been flushed to the parent cache. We're
85  // re-adding the coin to this cache now but we can't mark it as FRESH.
86  // If we mark it FRESH and then spend it before the cache is flushed
87  // we would remove it from this cache and would never flush spentness
88  // to the parent cache.
89  //
90  // Re-adding a spent coin can happen in the case of a re-org (the coin
91  // is 'spent' when the block adding it is disconnected and then
92  // re-added when it is also added in a newly connected block).
93  //
94  // If the coin doesn't exist in the current cache, or is spent but not
95  // DIRTY, then it can be marked FRESH.
96  fresh = !(it->second.flags & CCoinsCacheEntry::DIRTY);
97  }
98  it->second.coin = std::move(coin);
99  it->second.flags |= CCoinsCacheEntry::DIRTY | (fresh ? CCoinsCacheEntry::FRESH : 0);
100  cachedCoinsUsage += it->second.coin.DynamicMemoryUsage();
101  TRACE5(utxocache, add,
102  outpoint.hash.data(),
103  (uint32_t)outpoint.n,
104  (uint32_t)it->second.coin.nHeight,
105  (int64_t)it->second.coin.out.nValue,
106  (bool)it->second.coin.IsCoinBase());
107 }
108 
110  cachedCoinsUsage += coin.DynamicMemoryUsage();
111  cacheCoins.emplace(
112  std::piecewise_construct,
113  std::forward_as_tuple(std::move(outpoint)),
114  std::forward_as_tuple(std::move(coin), CCoinsCacheEntry::DIRTY));
115 }
116 
117 void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight, bool check_for_overwrite) {
118  bool fCoinbase = tx.IsCoinBase();
119  const Txid& txid = tx.GetHash();
120  for (size_t i = 0; i < tx.vout.size(); ++i) {
121  bool overwrite = check_for_overwrite ? cache.HaveCoin(COutPoint(txid, i)) : fCoinbase;
122  // Coinbase transactions can always be overwritten, in order to correctly
123  // deal with the pre-BIP30 occurrences of duplicate coinbase transactions.
124  cache.AddCoin(COutPoint(txid, i), Coin(tx.vout[i], nHeight, fCoinbase), overwrite);
125  }
126 }
127 
128 bool CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
129  CCoinsMap::iterator it = FetchCoin(outpoint);
130  if (it == cacheCoins.end()) return false;
131  cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
132  TRACE5(utxocache, spent,
133  outpoint.hash.data(),
134  (uint32_t)outpoint.n,
135  (uint32_t)it->second.coin.nHeight,
136  (int64_t)it->second.coin.out.nValue,
137  (bool)it->second.coin.IsCoinBase());
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  return true;
148 }
149 
150 static const Coin coinEmpty;
151 
152 const Coin& CCoinsViewCache::AccessCoin(const COutPoint &outpoint) const {
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  CCoinsMap::const_iterator it = FetchCoin(outpoint);
163  return (it != cacheCoins.end() && !it->second.coin.IsSpent());
164 }
165 
166 bool CCoinsViewCache::HaveCoinInCache(const COutPoint &outpoint) const {
167  CCoinsMap::const_iterator it = cacheCoins.find(outpoint);
168  return (it != cacheCoins.end() && !it->second.coin.IsSpent());
169 }
170 
172  if (hashBlock.IsNull())
174  return hashBlock;
175 }
176 
177 void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
178  hashBlock = hashBlockIn;
179 }
180 
181 bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn, bool erase) {
182  for (CCoinsMap::iterator it = mapCoins.begin();
183  it != mapCoins.end();
184  it = erase ? mapCoins.erase(it) : std::next(it)) {
185  // Ignore non-dirty entries (optimization).
186  if (!(it->second.flags & CCoinsCacheEntry::DIRTY)) {
187  continue;
188  }
189  CCoinsMap::iterator itUs = cacheCoins.find(it->first);
190  if (itUs == cacheCoins.end()) {
191  // The parent cache does not have an entry, while the child cache does.
192  // We can ignore it if it's both spent and FRESH in the child
193  if (!(it->second.flags & CCoinsCacheEntry::FRESH && it->second.coin.IsSpent())) {
194  // Create the coin in the parent cache, move the data up
195  // and mark it as dirty.
196  CCoinsCacheEntry& entry = cacheCoins[it->first];
197  if (erase) {
198  // The `move` call here is purely an optimization; we rely on the
199  // `mapCoins.erase` call in the `for` expression to actually remove
200  // the entry from the child map.
201  entry.coin = std::move(it->second.coin);
202  } else {
203  entry.coin = it->second.coin;
204  }
207  // We can mark it FRESH in the parent if it was FRESH in the child
208  // Otherwise it might have just been flushed from the parent's cache
209  // and already exist in the grandparent
210  if (it->second.flags & CCoinsCacheEntry::FRESH) {
212  }
213  }
214  } else {
215  // Found the entry in the parent cache
216  if ((it->second.flags & CCoinsCacheEntry::FRESH) && !itUs->second.coin.IsSpent()) {
217  // The coin was marked FRESH in the child cache, but the coin
218  // exists in the parent cache. If this ever happens, it means
219  // the FRESH flag was misapplied and there is a logic error in
220  // the calling code.
221  throw std::logic_error("FRESH flag misapplied to coin that exists in parent cache");
222  }
223 
224  if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coin.IsSpent()) {
225  // The grandparent cache does not have an entry, and the coin
226  // has been spent. We can just delete it from the parent cache.
227  cachedCoinsUsage -= itUs->second.coin.DynamicMemoryUsage();
228  cacheCoins.erase(itUs);
229  } else {
230  // A normal modification.
231  cachedCoinsUsage -= itUs->second.coin.DynamicMemoryUsage();
232  if (erase) {
233  // The `move` call here is purely an optimization; we rely on the
234  // `mapCoins.erase` call in the `for` expression to actually remove
235  // the entry from the child map.
236  itUs->second.coin = std::move(it->second.coin);
237  } else {
238  itUs->second.coin = it->second.coin;
239  }
240  cachedCoinsUsage += itUs->second.coin.DynamicMemoryUsage();
241  itUs->second.flags |= CCoinsCacheEntry::DIRTY;
242  // NOTE: It isn't safe to mark the coin as FRESH in the parent
243  // cache. If it already existed and was spent in the parent
244  // cache then marking it FRESH would prevent that spentness
245  // from being flushed to the grandparent.
246  }
247  }
248  }
249  hashBlock = hashBlockIn;
250  return true;
251 }
252 
254  bool fOk = base->BatchWrite(cacheCoins, hashBlock, /*erase=*/true);
255  if (fOk) {
256  if (!cacheCoins.empty()) {
257  /* BatchWrite must erase all cacheCoins elements when erase=true. */
258  throw std::logic_error("Not all cached coins were erased");
259  }
260  ReallocateCache();
261  }
262  cachedCoinsUsage = 0;
263  return fOk;
264 }
265 
267 {
268  bool fOk = base->BatchWrite(cacheCoins, hashBlock, /*erase=*/false);
269  // Instead of clearing `cacheCoins` as we would in Flush(), just clear the
270  // FRESH/DIRTY flags of any coin that isn't spent.
271  for (auto it = cacheCoins.begin(); it != cacheCoins.end(); ) {
272  if (it->second.coin.IsSpent()) {
273  cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
274  it = cacheCoins.erase(it);
275  } else {
276  it->second.flags = 0;
277  ++it;
278  }
279  }
280  return fOk;
281 }
282 
284 {
285  CCoinsMap::iterator it = cacheCoins.find(hash);
286  if (it != cacheCoins.end() && it->second.flags == 0) {
287  cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
288  TRACE5(utxocache, uncache,
289  hash.hash.data(),
290  (uint32_t)hash.n,
291  (uint32_t)it->second.coin.nHeight,
292  (int64_t)it->second.coin.out.nValue,
293  (bool)it->second.coin.IsCoinBase());
294  cacheCoins.erase(it);
295  }
296 }
297 
298 unsigned int CCoinsViewCache::GetCacheSize() const {
299  return cacheCoins.size();
300 }
301 
303 {
304  if (!tx.IsCoinBase()) {
305  for (unsigned int i = 0; i < tx.vin.size(); i++) {
306  if (!HaveCoin(tx.vin[i].prevout)) {
307  return false;
308  }
309  }
310  }
311  return true;
312 }
313 
315 {
316  // Cache should be empty when we're calling this.
317  assert(cacheCoins.size() == 0);
318  cacheCoins.~CCoinsMap();
319  m_cache_coins_memory_resource.~CCoinsMapMemoryResource();
321  ::new (&cacheCoins) CCoinsMap{0, SaltedOutpointHasher{/*deterministic=*/m_deterministic}, CCoinsMap::key_equal{}, &m_cache_coins_memory_resource};
322 }
323 
325 {
326  size_t recomputed_usage = 0;
327  for (const auto& [_, entry] : cacheCoins) {
328  unsigned attr = 0;
329  if (entry.flags & CCoinsCacheEntry::DIRTY) attr |= 1;
330  if (entry.flags & CCoinsCacheEntry::FRESH) attr |= 2;
331  if (entry.coin.IsSpent()) attr |= 4;
332  // Only 5 combinations are possible.
333  assert(attr != 2 && attr != 4 && attr != 7);
334 
335  // Recompute cachedCoinsUsage.
336  recomputed_usage += entry.coin.DynamicMemoryUsage();
337  }
338  assert(recomputed_usage == cachedCoinsUsage);
339 }
340 
343 
344 const Coin& AccessByTxid(const CCoinsViewCache& view, const Txid& txid)
345 {
346  COutPoint iter(txid, 0);
347  while (iter.n < MAX_OUTPUTS_PER_BLOCK) {
348  const Coin& alternate = view.AccessCoin(iter);
349  if (!alternate.IsSpent()) return alternate;
350  ++iter.n;
351  }
352  return coinEmpty;
353 }
354 
355 template <typename Func>
356 static bool ExecuteBackedWrapper(Func func, const std::vector<std::function<void()>>& err_callbacks)
357 {
358  try {
359  return func();
360  } catch(const std::runtime_error& e) {
361  for (const auto& f : err_callbacks) {
362  f();
363  }
364  LogPrintf("Error reading from database: %s\n", e.what());
365  // Starting the shutdown sequence and returning false to the caller would be
366  // interpreted as 'entry not found' (as opposed to unable to read data), and
367  // could lead to invalid interpretation. Just exit immediately, as we can't
368  // continue anyway, and all writes should be atomic.
369  std::abort();
370  }
371 }
372 
373 bool CCoinsViewErrorCatcher::GetCoin(const COutPoint &outpoint, Coin &coin) const {
374  return ExecuteBackedWrapper([&]() { return CCoinsViewBacked::GetCoin(outpoint, coin); }, m_err_callbacks);
375 }
376 
377 bool CCoinsViewErrorCatcher::HaveCoin(const COutPoint &outpoint) const {
378  return ExecuteBackedWrapper([&]() { return CCoinsViewBacked::HaveCoin(outpoint); }, m_err_callbacks);
379 }
int ret
CCoinsView backed by another CCoinsView.
Definition: coins.h:210
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
Definition: coins.cpp:26
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:25
size_t EstimateSize() const override
Estimate database size (0 if not implemented)
Definition: coins.cpp:32
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:27
void SetBackend(CCoinsView &viewIn)
Definition: coins.cpp:29
std::unique_ptr< CCoinsViewCursor > Cursor() const override
Get a cursor to iterate over the whole state.
Definition: coins.cpp:31
CCoinsView * base
Definition: coins.h:212
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, bool erase=true) override
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:30
std::vector< uint256 > GetHeadBlocks() const override
Retrieve the range of blocks that may have been only partially written.
Definition: coins.cpp:28
CCoinsViewBacked(CCoinsView *viewIn)
Definition: coins.cpp:24
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:229
CCoinsViewCache(CCoinsView *baseIn, bool deterministic=false)
Definition: coins.cpp:34
const bool m_deterministic
Definition: coins.h:231
uint256 hashBlock
Make mutable so that we can "fill the cache" even from Get-methods declared as "const".
Definition: coins.h:238
CCoinsMapMemoryResource m_cache_coins_memory_resource
Definition: coins.h:239
bool SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr)
Spend a coin.
Definition: coins.cpp:128
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
Definition: coins.cpp:283
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:302
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool possible_overwrite)
Add a coin.
Definition: coins.cpp:69
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, bool erase=true) override
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:181
unsigned int GetCacheSize() const
Calculate the size of the cache (in number of transaction outputs)
Definition: coins.cpp:298
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:171
size_t cachedCoinsUsage
Definition: coins.h:243
void SetBestBlock(const uint256 &hashBlock)
Definition: coins.cpp:177
CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const
Definition: coins.cpp:43
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:60
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
Definition: coins.cpp:166
bool Flush()
Push the modifications applied to this cache to its base and wipe local state.
Definition: coins.cpp:253
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes)
Definition: coins.cpp:39
bool Sync()
Push the modifications applied to this cache to its base while retaining the contents of this cache (...
Definition: coins.cpp:266
void EmplaceCoinInternalDANGER(COutPoint &&outpoint, Coin &&coin)
Emplace a coin into cacheCoins without performing any checks, marking the emplaced coin as dirty.
Definition: coins.cpp:109
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
Definition: coins.cpp:161
void SanityCheck() const
Run an internal sanity check on the cache data structure. *‍/.
Definition: coins.cpp:324
CCoinsMap cacheCoins
Definition: coins.h:240
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
Definition: coins.cpp:152
void ReallocateCache()
Force a reallocation of the cache map.
Definition: coins.cpp:314
std::vector< std::function< void()> > m_err_callbacks
A list of callbacks to execute upon leveldb read error.
Definition: coins.h:389
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:373
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
Definition: coins.cpp:377
Abstract view on the open txout dataset.
Definition: coins.h:173
virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:12
virtual std::vector< uint256 > GetHeadBlocks() const
Retrieve the range of blocks that may have been only partially written.
Definition: coins.cpp:14
virtual bool HaveCoin(const COutPoint &outpoint) const
Just check whether a given outpoint is unspent.
Definition: coins.cpp:18
virtual size_t EstimateSize() const
Estimate database size (0 if not implemented)
Definition: coins.h:204
virtual std::unique_ptr< CCoinsViewCursor > Cursor() const
Get a cursor to iterate over the whole state.
Definition: coins.cpp:16
virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, bool erase=true)
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:15
virtual uint256 GetBestBlock() const
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:13
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:29
uint32_t n
Definition: transaction.h:32
Txid hash
Definition: transaction.h:31
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:296
const Txid & GetHash() const LIFETIMEBOUND
Definition: transaction.h:343
const std::vector< CTxOut > vout
Definition: transaction.h:307
bool IsCoinBase() const
Definition: transaction.h:356
const std::vector< CTxIn > vin
Definition: transaction.h:306
An output of a transaction.
Definition: transaction.h:150
A UTXO entry.
Definition: coins.h:32
bool IsSpent() const
Either this coin never existed (see e.g.
Definition: coins.h:80
size_t DynamicMemoryUsage() const
Definition: coins.h:84
constexpr bool IsNull() const
Definition: uint256.h:42
constexpr const std::byte * data() const
256-bit opaque blob.
Definition: uint256.h:106
static const size_t MIN_TRANSACTION_OUTPUT_WEIGHT
Definition: coins.cpp:341
static const Coin coinEmpty
Definition: coins.cpp:150
static bool ExecuteBackedWrapper(Func func, const std::vector< std::function< void()>> &err_callbacks)
Definition: coins.cpp:356
const Coin & AccessByTxid(const CCoinsViewCache &view, const Txid &txid)
Utility function to find any unspent output with a given txid.
Definition: coins.cpp:344
static const size_t MAX_OUTPUTS_PER_BLOCK
Definition: coins.cpp:342
void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight, bool check_for_overwrite)
Utility function to add all of a transaction's outputs to a cache.
Definition: coins.cpp:117
std::unordered_map< COutPoint, CCoinsCacheEntry, SaltedOutpointHasher, std::equal_to< COutPoint >, PoolAllocator< std::pair< const COutPoint, CCoinsCacheEntry >, sizeof(std::pair< const COutPoint, CCoinsCacheEntry >)+sizeof(void *) *4 > > CCoinsMap
PoolAllocator's MAX_BLOCK_SIZE_BYTES parameter here uses sizeof the data, and adds the size of 4 poin...
Definition: coins.h:148
CCoinsMap::allocator_type::ResourceType CCoinsMapMemoryResource
Definition: coins.h:150
static const unsigned int MAX_BLOCK_WEIGHT
The maximum allowed weight for a block, see BIP 141 (network rule)
Definition: consensus.h:15
static const int WITNESS_SCALE_FACTOR
Definition: consensus.h:21
#define LogPrintf(...)
Definition: logging.h:245
unsigned int nHeight
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
Definition: memusage.h:30
bool Func(const std::string &str, Span< const char > &sp)
Parse a function call.
Definition: spanparsing.cpp:24
size_t GetSerializeSize(const T &t)
Definition: serialize.h:1116
A Coin in one level of the coins database caching hierarchy.
Definition: coins.h:105
unsigned char flags
Definition: coins.h:107
Coin coin
Definition: coins.h:106
@ FRESH
FRESH means the parent cache does not have this coin or that it is a spent coin in the parent cache.
Definition: coins.h:127
@ DIRTY
DIRTY means the CCoinsCacheEntry is potentially different from the version in the parent cache.
Definition: coins.h:117
#define TRACE5(context, event, a, b, c, d, e)
Definition: trace.h:37
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:74
assert(!tx.IsCoinBase())