Bitcoin ABC 0.32.4
P2P Digital Currency
coins.h
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2016 The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#ifndef BITCOIN_COINS_H
7#define BITCOIN_COINS_H
8
9#include <compressor.h>
10#include <memusage.h>
12#include <serialize.h>
14#include <util/check.h>
15#include <util/hasher.h>
16
17#include <cassert>
18#include <cstdint>
19#include <functional>
20#include <unordered_map>
21
29class Coin {
32
36
37public:
40
42 Coin(CTxOut outIn, uint32_t nHeightIn, bool IsCoinbase)
43 : out(std::move(outIn)),
44 nHeightAndIsCoinBase((nHeightIn << 1) | IsCoinbase) {}
45
46 uint32_t GetHeight() const { return nHeightAndIsCoinBase >> 1; }
47 bool IsCoinBase() const { return nHeightAndIsCoinBase & 0x01; }
48 bool IsSpent() const { return out.IsNull(); }
49
50 CTxOut &GetTxOut() { return out; }
51 const CTxOut &GetTxOut() const { return out; }
52
53 void Clear() {
54 out.SetNull();
56 }
57
58 template <typename Stream> void Serialize(Stream &s) const {
59 assert(!IsSpent());
61 ::Serialize(s, Using<TxOutCompression>(out));
62 }
63
64 template <typename Stream> void Unserialize(Stream &s) {
66 ::Unserialize(s, Using<TxOutCompression>(out));
67 }
68
69 size_t DynamicMemoryUsage() const {
71 }
72};
73
74struct CCoinsCacheEntry;
75using CoinsCachePair = std::pair<const COutPoint, CCoinsCacheEntry>;
76
96private:
115 uint8_t m_flags{0};
116
119 static void AddFlags(uint8_t flags, CoinsCachePair &pair,
120 CoinsCachePair &sentinel) noexcept {
121 Assume(flags & (DIRTY | FRESH));
122 if (!pair.second.m_flags) {
123 Assume(!pair.second.m_prev && !pair.second.m_next);
124 pair.second.m_prev = sentinel.second.m_prev;
125 pair.second.m_next = &sentinel;
126 sentinel.second.m_prev = &pair;
127 pair.second.m_prev->second.m_next = &pair;
128 }
129 Assume(pair.second.m_prev && pair.second.m_next);
130 pair.second.m_flags |= flags;
131 }
132
133public:
134 // The actual cached data.
136
137 enum Flags {
145 DIRTY = (1 << 0),
155 FRESH = (1 << 1),
156 };
157
158 CCoinsCacheEntry() noexcept = default;
159 explicit CCoinsCacheEntry(Coin &&coin_) : coin(std::move(coin_)) {}
161
162 static void SetDirty(CoinsCachePair &pair,
163 CoinsCachePair &sentinel) noexcept {
164 AddFlags(DIRTY, pair, sentinel);
165 }
166 static void SetFresh(CoinsCachePair &pair,
167 CoinsCachePair &sentinel) noexcept {
168 AddFlags(FRESH, pair, sentinel);
169 }
170
171 void SetClean() noexcept {
172 if (!m_flags) {
173 return;
174 }
175 m_next->second.m_prev = m_prev;
176 m_prev->second.m_next = m_next;
177 m_flags = 0;
178 m_prev = m_next = nullptr;
179 }
180 bool IsDirty() const noexcept { return m_flags & DIRTY; }
181 bool IsFresh() const noexcept { return m_flags & FRESH; }
182
184 CoinsCachePair *Next() const noexcept {
186 return m_next;
187 }
188
190 CoinsCachePair *Prev() const noexcept {
192 return m_prev;
193 }
194
196 void SelfRef(CoinsCachePair &pair) noexcept {
197 Assume(&pair.second == this);
198 m_prev = &pair;
199 m_next = &pair;
200 // Set sentinel to DIRTY so we can call Next on it
201 m_flags = DIRTY;
202 }
203};
204
215using CCoinsMap = std::unordered_map<
216 COutPoint, CCoinsCacheEntry, SaltedOutpointHasher, std::equal_to<COutPoint>,
217 PoolAllocator<CoinsCachePair, sizeof(CoinsCachePair) + sizeof(void *) * 4>>;
218
219using CCoinsMapMemoryResource = CCoinsMap::allocator_type::ResourceType;
220
223public:
224 CCoinsViewCursor(const BlockHash &hashBlockIn) : hashBlock(hashBlockIn) {}
225 virtual ~CCoinsViewCursor() {}
226
227 virtual bool GetKey(COutPoint &key) const = 0;
228 virtual bool GetValue(Coin &coin) const = 0;
229 virtual unsigned int GetValueSize() const = 0;
230
231 virtual bool Valid() const = 0;
232 virtual void Next() = 0;
233
235 const BlockHash &GetBestBlock() const { return hashBlock; }
236
237private:
239};
240
268 CCoinsMap &map LIFETIMEBOUND, bool will_erase) noexcept
269 : m_usage(usage), m_sentinel(sentinel), m_map(map),
270 m_will_erase(will_erase) {}
271
272 inline CoinsCachePair *Begin() const noexcept {
273 return m_sentinel.second.Next();
274 }
275 inline CoinsCachePair *End() const noexcept { return &m_sentinel; }
276
279 const auto next_entry{current.second.Next()};
280 // If we are not going to erase the cache, we must still erase spent
281 // entries. Otherwise, clear the state of the entry.
282 if (!m_will_erase) {
283 if (current.second.coin.IsSpent()) {
284 m_usage -= current.second.coin.DynamicMemoryUsage();
285 m_map.erase(current.first);
286 } else {
287 current.second.SetClean();
288 }
289 }
290 return next_entry;
291 }
292
293 inline bool WillErase(CoinsCachePair &current) const noexcept {
294 return m_will_erase || current.second.coin.IsSpent();
295 }
296
297private:
298 size_t &m_usage;
302};
303
306public:
312 virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const;
313
315 virtual bool HaveCoin(const COutPoint &outpoint) const;
316
318 virtual BlockHash GetBestBlock() const;
319
325 virtual std::vector<BlockHash> GetHeadBlocks() const;
326
329 virtual bool BatchWrite(CoinsViewCacheCursor &cursor,
330 const BlockHash &hashBlock);
331
333 virtual CCoinsViewCursor *Cursor() const;
334
336 virtual ~CCoinsView() {}
337
339 virtual size_t EstimateSize() const { return 0; }
340};
341
344protected:
346
347public:
349 bool GetCoin(const COutPoint &outpoint, Coin &coin) const override;
350 bool HaveCoin(const COutPoint &outpoint) const override;
351 BlockHash GetBestBlock() const override;
352 std::vector<BlockHash> GetHeadBlocks() const override;
353 void SetBackend(CCoinsView &viewIn);
354 bool BatchWrite(CoinsViewCacheCursor &cursor,
355 const BlockHash &hashBlock) override;
356 CCoinsViewCursor *Cursor() const override;
357 size_t EstimateSize() const override;
358};
359
364private:
365 const bool m_deterministic;
366
367protected:
379
380 /* Cached dynamic memory usage for the inner Coin objects. */
381 mutable size_t cachedCoinsUsage;
382
383public:
384 CCoinsViewCache(CCoinsView *baseIn, bool deterministic = false);
385
391
392 // Standard CCoinsView methods
393 bool GetCoin(const COutPoint &outpoint, Coin &coin) const override;
394 bool HaveCoin(const COutPoint &outpoint) const override;
395 BlockHash GetBestBlock() const override;
396 void SetBestBlock(const BlockHash &hashBlock);
397 bool BatchWrite(CoinsViewCacheCursor &cursor,
398 const BlockHash &hashBlock) override;
399 CCoinsViewCursor *Cursor() const override {
400 throw std::logic_error(
401 "CCoinsViewCache cursor iteration not supported.");
402 }
403
409 bool HaveCoinInCache(const COutPoint &outpoint) const;
410
421 const Coin &AccessCoin(const COutPoint &output) const;
422
427 void AddCoin(const COutPoint &outpoint, Coin coin, bool possible_overwrite);
428
436 void EmplaceCoinInternalDANGER(COutPoint &&outpoint, Coin &&coin);
437
443 bool SpendCoin(const COutPoint &outpoint, Coin *moveto = nullptr);
444
451 bool Flush();
452
460 bool Sync();
461
466 void Uncache(const COutPoint &outpoint);
467
469 unsigned int GetCacheSize() const;
470
472 size_t DynamicMemoryUsage() const;
473
476 bool HaveInputs(const CTransaction &tx) const;
477
484 void ReallocateCache();
485
487 void SanityCheck() const;
488
489private:
494 CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const;
495};
496
501// TODO: pass in a boolean to limit these possible overwrites to known
502// (pre-BIP34) cases.
503void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight,
504 bool check = false);
505
510const Coin &AccessByTxid(const CCoinsViewCache &cache, const TxId &txid);
511
521public:
523 : CCoinsViewBacked(view) {}
524
525 void AddReadErrCallback(std::function<void()> f) {
526 m_err_callbacks.emplace_back(std::move(f));
527 }
528
529 bool GetCoin(const COutPoint &outpoint, Coin &coin) const override;
530
531private:
535 std::vector<std::function<void()>> m_err_callbacks;
536};
537
538#endif // BITCOIN_COINS_H
#define LIFETIMEBOUND
Definition: attributes.h:16
int flags
Definition: bitcoin-tx.cpp:542
#define Assume(val)
Assume is the identity function.
Definition: check.h:97
CCoinsView backed by another CCoinsView.
Definition: coins.h:343
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
Definition: coins.cpp:38
BlockHash GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:41
CCoinsViewCursor * Cursor() const override
Get a cursor to iterate over the whole state.
Definition: coins.cpp:54
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:35
size_t EstimateSize() const override
Estimate database size (0 if not implemented)
Definition: coins.cpp:57
void SetBackend(CCoinsView &viewIn)
Definition: coins.cpp:47
CCoinsView * base
Definition: coins.h:345
std::vector< BlockHash > GetHeadBlocks() const override
Retrieve the range of blocks that may have been only partially written.
Definition: coins.cpp:44
bool BatchWrite(CoinsViewCacheCursor &cursor, const BlockHash &hashBlock) override
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:50
CCoinsViewBacked(CCoinsView *viewIn)
Definition: coins.cpp:34
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:363
CCoinsViewCache(CCoinsView *baseIn, bool deterministic=false)
Definition: coins.cpp:61
void AddCoin(const COutPoint &outpoint, Coin coin, bool possible_overwrite)
Add a coin.
Definition: coins.cpp:100
const bool m_deterministic
Definition: coins.h:365
BlockHash GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:214
CCoinsMapMemoryResource m_cache_coins_memory_resource
Definition: coins.h:373
bool SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr)
Spend a coin.
Definition: coins.cpp:172
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
Definition: coins.cpp:324
CCoinsViewCursor * Cursor() const override
Get a cursor to iterate over the whole state.
Definition: coins.h:399
CCoinsViewCache(const CCoinsViewCache &)=delete
By deleting the copy constructor, we prevent accidentally using it when one intends to create a cache...
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:341
bool BatchWrite(CoinsViewCacheCursor &cursor, const BlockHash &hashBlock) override
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:225
void SetBestBlock(const BlockHash &hashBlock)
Definition: coins.cpp:221
BlockHash hashBlock
Make mutable so that we can "fill the cache" even from Get-methods declared as "const".
Definition: coins.h:372
unsigned int GetCacheSize() const
Calculate the size of the cache (in number of transaction outputs)
Definition: coins.cpp:337
size_t cachedCoinsUsage
Definition: coins.h:381
CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const
Definition: coins.cpp:74
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:91
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
Definition: coins.cpp:209
bool Flush()
Push the modifications applied to this cache to its base and wipe local state.
Definition: coins.cpp:298
CoinsCachePair m_sentinel
The starting sentinel of the flagged entry circular doubly linked list.
Definition: coins.h:377
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes)
Definition: coins.cpp:69
bool Sync()
Push the modifications applied to this cache to its base while retaining the contents of this cache (...
Definition: coins.cpp:310
void EmplaceCoinInternalDANGER(COutPoint &&outpoint, Coin &&coin)
Emplace a coin into cacheCoins without performing any checks, marking the emplaced coin as dirty.
Definition: coins.cpp:146
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
Definition: coins.cpp:204
void SanityCheck() const
Run an internal sanity check on the cache data structure.
Definition: coins.cpp:366
CCoinsMap cacheCoins
Definition: coins.h:378
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
Definition: coins.cpp:196
void ReallocateCache()
Force a reallocation of the cache map.
Definition: coins.cpp:355
Cursor for iterating over CoinsView state.
Definition: coins.h:222
virtual void Next()=0
virtual bool Valid() const =0
CCoinsViewCursor(const BlockHash &hashBlockIn)
Definition: coins.h:224
virtual unsigned int GetValueSize() const =0
BlockHash hashBlock
Definition: coins.h:238
virtual ~CCoinsViewCursor()
Definition: coins.h:225
virtual bool GetKey(COutPoint &key) const =0
const BlockHash & GetBestBlock() const
Get best block at the time this cursor was created.
Definition: coins.h:235
virtual bool GetValue(Coin &coin) const =0
This is a minimally invasive approach to shutdown on LevelDB read errors from the chainstate,...
Definition: coins.h:520
void AddReadErrCallback(std::function< void()> f)
Definition: coins.h:525
std::vector< std::function< void()> > m_err_callbacks
A list of callbacks to execute upon leveldb read error.
Definition: coins.h:535
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:422
CCoinsViewErrorCatcher(CCoinsView *view)
Definition: coins.h:522
Abstract view on the open txout dataset.
Definition: coins.h:305
virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:13
virtual CCoinsViewCursor * Cursor() const
Get a cursor to iterate over the whole state.
Definition: coins.cpp:26
virtual std::vector< BlockHash > GetHeadBlocks() const
Retrieve the range of blocks that may have been only partially written.
Definition: coins.cpp:19
virtual ~CCoinsView()
As we use CCoinsViews polymorphically, have a virtual destructor.
Definition: coins.h:336
virtual BlockHash GetBestBlock() const
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:16
virtual bool HaveCoin(const COutPoint &outpoint) const
Just check whether a given outpoint is unspent.
Definition: coins.cpp:29
virtual size_t EstimateSize() const
Estimate database size (0 if not implemented)
Definition: coins.h:339
virtual bool BatchWrite(CoinsViewCacheCursor &cursor, const BlockHash &hashBlock)
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:22
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:20
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:192
An output of a transaction.
Definition: transaction.h:128
CScript scriptPubKey
Definition: transaction.h:131
void SetNull()
Definition: transaction.h:140
bool IsNull() const
Definition: transaction.h:145
A UTXO entry.
Definition: coins.h:29
uint32_t GetHeight() const
Definition: coins.h:46
bool IsCoinBase() const
Definition: coins.h:47
void Clear()
Definition: coins.h:53
Coin(CTxOut outIn, uint32_t nHeightIn, bool IsCoinbase)
Constructor from a CTxOut and height/coinbase information.
Definition: coins.h:42
void Serialize(Stream &s) const
Definition: coins.h:58
CTxOut & GetTxOut()
Definition: coins.h:50
uint32_t nHeightAndIsCoinBase
Whether containing transaction was a coinbase and height at which the transaction was included into a...
Definition: coins.h:35
Coin()
Empty constructor.
Definition: coins.h:39
CTxOut out
Unspent transaction output.
Definition: coins.h:31
const CTxOut & GetTxOut() const
Definition: coins.h:51
bool IsSpent() const
Definition: coins.h:48
void Unserialize(Stream &s)
Definition: coins.h:64
size_t DynamicMemoryUsage() const
Definition: coins.h:69
Forwards all allocations/deallocations to the PoolResource.
Definition: pool.h:299
const Coin & AccessByTxid(const CCoinsViewCache &cache, const TxId &txid)
Utility function to find any unspent output with a given txid.
Definition: coins.cpp:411
void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight, bool check=false)
Utility function to add all of a transaction's outputs to a cache.
Definition: coins.cpp:156
std::pair< const COutPoint, CCoinsCacheEntry > CoinsCachePair
Definition: coins.h:75
std::unordered_map< COutPoint, CCoinsCacheEntry, SaltedOutpointHasher, std::equal_to< COutPoint >, PoolAllocator< CoinsCachePair, sizeof(CoinsCachePair)+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:217
CCoinsMap::allocator_type::ResourceType CCoinsMapMemoryResource
Definition: coins.h:219
unsigned int nHeight
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
Definition: memusage.h:28
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:259
#define VARINT(obj)
Definition: serialize.h:569
A BlockHash is a unqiue identifier for a block.
Definition: blockhash.h:13
A Coin in one level of the coins database caching hierarchy.
Definition: coins.h:95
Coin coin
Definition: coins.h:135
CCoinsCacheEntry() noexcept=default
Flags
Definition: coins.h:137
@ 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:155
@ DIRTY
DIRTY means the CCoinsCacheEntry is potentially different from the version in the parent cache.
Definition: coins.h:145
void SetClean() noexcept
Definition: coins.h:171
static void SetFresh(CoinsCachePair &pair, CoinsCachePair &sentinel) noexcept
Definition: coins.h:166
uint8_t m_flags
Definition: coins.h:115
static void AddFlags(uint8_t flags, CoinsCachePair &pair, CoinsCachePair &sentinel) noexcept
Adding a flag requires a reference to the sentinel of the flagged pair linked list.
Definition: coins.h:119
CoinsCachePair * m_next
Definition: coins.h:114
bool IsFresh() const noexcept
Definition: coins.h:181
~CCoinsCacheEntry()
Definition: coins.h:160
static void SetDirty(CoinsCachePair &pair, CoinsCachePair &sentinel) noexcept
Definition: coins.h:162
void SelfRef(CoinsCachePair &pair) noexcept
Only use this for initializing the linked list sentinel.
Definition: coins.h:196
bool IsDirty() const noexcept
Definition: coins.h:180
CoinsCachePair * m_prev
These are used to create a doubly linked list of flagged entries.
Definition: coins.h:113
CoinsCachePair * Next() const noexcept
Only call Next when this entry is DIRTY, FRESH, or both.
Definition: coins.h:184
CoinsCachePair * Prev() const noexcept
Only call Prev when this entry is DIRTY, FRESH, or both.
Definition: coins.h:190
Cursor for iterating over the linked list of flagged entries in CCoinsViewCache.
Definition: coins.h:255
CoinsCachePair & m_sentinel
Definition: coins.h:299
CoinsCachePair * NextAndMaybeErase(CoinsCachePair &current) noexcept
Return the next entry after current, possibly erasing current.
Definition: coins.h:278
CoinsViewCacheCursor(size_t &usage LIFETIMEBOUND, CoinsCachePair &sentinel LIFETIMEBOUND, CCoinsMap &map LIFETIMEBOUND, bool will_erase) noexcept
If will_erase is not set, iterating through the cursor will erase spent coins from the map,...
Definition: coins.h:266
bool WillErase(CoinsCachePair &current) const noexcept
Definition: coins.h:293
CCoinsMap & m_map
Definition: coins.h:300
CoinsCachePair * Begin() const noexcept
Definition: coins.h:272
size_t & m_usage
Definition: coins.h:298
CoinsCachePair * End() const noexcept
Definition: coins.h:275
A TxId is the identifier of a transaction.
Definition: txid.h:14
assert(!tx.IsCoinBase())