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