Bitcoin ABC 0.33.6
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 <attributes.h>
10#include <compressor.h>
11#include <memusage.h>
13#include <serialize.h>
15#include <util/check.h>
16#include <util/hasher.h>
17#include <util/overflow.h>
18
19#include <cassert>
20#include <cstdint>
21#include <functional>
22#include <unordered_map>
23
31class Coin {
34
38
39public:
42
44 Coin(CTxOut outIn, uint32_t nHeightIn, bool IsCoinbase)
45 : out(std::move(outIn)),
46 nHeightAndIsCoinBase((nHeightIn << 1) | IsCoinbase) {}
47
48 uint32_t GetHeight() const { return nHeightAndIsCoinBase >> 1; }
49 bool IsCoinBase() const { return nHeightAndIsCoinBase & 0x01; }
50 bool IsSpent() const { return out.IsNull(); }
51
52 CTxOut &GetTxOut() { return out; }
53 const CTxOut &GetTxOut() const { return out; }
54
55 void Clear() {
56 out.SetNull();
58 }
59
60 template <typename Stream> void Serialize(Stream &s) const {
61 assert(!IsSpent());
63 ::Serialize(s, Using<TxOutCompression>(out));
64 }
65
66 template <typename Stream> void Unserialize(Stream &s) {
68 ::Unserialize(s, Using<TxOutCompression>(out));
69 }
70
71 size_t DynamicMemoryUsage() const {
73 }
74};
75
76struct CCoinsCacheEntry;
77using CoinsCachePair = std::pair<const COutPoint, CCoinsCacheEntry>;
78
97private:
110 uint8_t m_flags{0};
111
114 static void AddFlags(uint8_t flags, CoinsCachePair &pair,
115 CoinsCachePair &sentinel) noexcept {
116 Assume(flags & (DIRTY | FRESH));
117 if (!pair.second.m_flags) {
118 Assume(!pair.second.m_prev && !pair.second.m_next);
119 pair.second.m_prev = sentinel.second.m_prev;
120 pair.second.m_next = &sentinel;
121 sentinel.second.m_prev = &pair;
122 pair.second.m_prev->second.m_next = &pair;
123 }
124 Assume(pair.second.m_prev && pair.second.m_next);
125 pair.second.m_flags |= flags;
126 }
127
128public:
129 // The actual cached data.
131
132 enum Flags {
140 DIRTY = (1 << 0),
150 FRESH = (1 << 1),
151 };
152
153 CCoinsCacheEntry() noexcept = default;
154 explicit CCoinsCacheEntry(Coin &&coin_) : coin(std::move(coin_)) {}
156
157 static void SetDirty(CoinsCachePair &pair,
158 CoinsCachePair &sentinel) noexcept {
159 AddFlags(DIRTY, pair, sentinel);
160 }
161 static void SetFresh(CoinsCachePair &pair,
162 CoinsCachePair &sentinel) noexcept {
163 AddFlags(FRESH, pair, sentinel);
164 }
165
166 void SetClean() noexcept {
167 if (!m_flags) {
168 return;
169 }
170 m_next->second.m_prev = m_prev;
171 m_prev->second.m_next = m_next;
172 m_flags = 0;
173 m_prev = m_next = nullptr;
174 }
175 bool IsDirty() const noexcept { return m_flags & DIRTY; }
176 bool IsFresh() const noexcept { return m_flags & FRESH; }
177
179 CoinsCachePair *Next() const noexcept {
181 return m_next;
182 }
183
185 CoinsCachePair *Prev() const noexcept {
187 return m_prev;
188 }
189
191 void SelfRef(CoinsCachePair &pair) noexcept {
192 Assume(&pair.second == this);
193 m_prev = &pair;
194 m_next = &pair;
195 // Set sentinel to DIRTY so we can call Next on it
196 m_flags = DIRTY;
197 }
198};
199
210using CCoinsMap = std::unordered_map<
211 COutPoint, CCoinsCacheEntry, SaltedOutpointHasher, std::equal_to<COutPoint>,
212 PoolAllocator<CoinsCachePair, sizeof(CoinsCachePair) + sizeof(void *) * 4>>;
213
214using CCoinsMapMemoryResource = CCoinsMap::allocator_type::ResourceType;
215
218public:
219 CCoinsViewCursor(const BlockHash &hashBlockIn) : hashBlock(hashBlockIn) {}
220 virtual ~CCoinsViewCursor() {}
221
222 virtual bool GetKey(COutPoint &key) const = 0;
223 virtual bool GetValue(Coin &coin) const = 0;
224 virtual unsigned int GetValueSize() const = 0;
225
226 virtual bool Valid() const = 0;
227 virtual void Next() = 0;
228
230 const BlockHash &GetBestBlock() const { return hashBlock; }
231
232private:
234};
235
263 CCoinsMap &map LIFETIMEBOUND, bool will_erase) noexcept
264 : m_dirty_count(dirty_count), m_sentinel(sentinel), m_map(map),
265 m_will_erase(will_erase) {}
266
267 inline CoinsCachePair *Begin() const noexcept {
268 return m_sentinel.second.Next();
269 }
270 inline CoinsCachePair *End() const noexcept { return &m_sentinel; }
271
274 const auto next_entry{current.second.Next()};
275 Assume(TrySub(m_dirty_count, current.second.IsDirty()));
276 // If we are not going to erase the cache, we must still erase spent
277 // entries. Otherwise, clear the state of the entry.
278 if (!m_will_erase) {
279 if (current.second.coin.IsSpent()) {
280 // scriptPubKey was already cleared in SpendCoin
281 assert(current.second.coin.DynamicMemoryUsage() == 0);
282 m_map.erase(current.first);
283 } else {
284 current.second.SetClean();
285 }
286 }
287 return next_entry;
288 }
289
290 inline bool WillErase(CoinsCachePair &current) const noexcept {
291 return m_will_erase || current.second.coin.IsSpent();
292 }
293 size_t GetDirtyCount() const noexcept { return m_dirty_count; }
294 size_t GetTotalCount() const noexcept { return m_map.size(); }
295
296private:
301};
302
305public:
307 virtual std::optional<Coin> GetCoin(const COutPoint &outpoint) const;
308
310 virtual bool HaveCoin(const COutPoint &outpoint) const;
311
313 virtual BlockHash GetBestBlock() const;
314
320 virtual std::vector<BlockHash> GetHeadBlocks() const;
321
324 virtual void BatchWrite(CoinsViewCacheCursor &cursor,
325 const BlockHash &hashBlock);
326
328 virtual CCoinsViewCursor *Cursor() const;
329
331 virtual ~CCoinsView() {}
332
334 virtual size_t EstimateSize() const { return 0; }
335};
336
339protected:
341
342public:
344 std::optional<Coin> GetCoin(const COutPoint &outpoint) const override;
345 bool HaveCoin(const COutPoint &outpoint) const override;
346 BlockHash GetBestBlock() const override;
347 std::vector<BlockHash> GetHeadBlocks() const override;
348 void SetBackend(CCoinsView &viewIn);
349 void BatchWrite(CoinsViewCacheCursor &cursor,
350 const BlockHash &hashBlock) override;
351 CCoinsViewCursor *Cursor() const override;
352 size_t EstimateSize() const override;
353};
354
359private:
360 const bool m_deterministic;
361
362protected:
374
375 /* Cached dynamic memory usage for the inner Coin objects. */
376 mutable size_t cachedCoinsUsage;
377 /* Running count of dirty Coin cache entries. */
378 mutable size_t m_dirty_count{0};
379
385 void Reset() noexcept;
386
387public:
388 CCoinsViewCache(CCoinsView *baseIn, bool deterministic = false);
389
395
396 // Standard CCoinsView methods
397 std::optional<Coin> GetCoin(const COutPoint &outpoint) const override;
398 bool HaveCoin(const COutPoint &outpoint) const override;
399 BlockHash GetBestBlock() const override;
400 void SetBestBlock(const BlockHash &hashBlock);
401 void BatchWrite(CoinsViewCacheCursor &cursor,
402 const BlockHash &hashBlock) override;
403 CCoinsViewCursor *Cursor() const override {
404 throw std::logic_error(
405 "CCoinsViewCache cursor iteration not supported.");
406 }
407
413 bool HaveCoinInCache(const COutPoint &outpoint) const;
414
425 const Coin &AccessCoin(const COutPoint &output) const;
426
431 void AddCoin(const COutPoint &outpoint, Coin coin, bool possible_overwrite);
432
440 void EmplaceCoinInternalDANGER(COutPoint &&outpoint, Coin &&coin);
441
447 bool SpendCoin(const COutPoint &outpoint, Coin *moveto = nullptr);
448
458 void Flush(bool reallocate_cache = true);
459
466 void Sync();
467
472 void Uncache(const COutPoint &outpoint);
473
475 unsigned int GetCacheSize() const;
476
478 size_t GetDirtyCount() const noexcept { return m_dirty_count; }
479
481 size_t DynamicMemoryUsage() const;
482
485 bool HaveInputs(const CTransaction &tx) const;
486
493 void ReallocateCache();
494
496 void SanityCheck() const;
497
499 private:
502 explicit ResetGuard(CCoinsViewCache &cache LIFETIMEBOUND) noexcept
503 : m_cache{cache} {}
504
505 public:
506 ResetGuard(const ResetGuard &) = delete;
507 ResetGuard &operator=(const ResetGuard &) = delete;
508 ResetGuard(ResetGuard &&) = delete;
510
512 };
513
516 [[nodiscard]] ResetGuard CreateResetGuard() noexcept {
517 return ResetGuard{*this};
518 }
519
520private:
525 CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const;
526};
527
532// TODO: pass in a boolean to limit these possible overwrites to known
533// (pre-BIP34) cases.
534void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight,
535 bool check = false);
536
541const Coin &AccessByTxid(const CCoinsViewCache &cache, const TxId &txid);
542
552public:
554 : CCoinsViewBacked(view) {}
555
556 void AddReadErrCallback(std::function<void()> f) {
557 m_err_callbacks.emplace_back(std::move(f));
558 }
559
560 std::optional<Coin> GetCoin(const COutPoint &outpoint) const override;
561 bool HaveCoin(const COutPoint &outpoint) const override;
562
563private:
567 std::vector<std::function<void()>> m_err_callbacks;
568};
569
570#endif // BITCOIN_COINS_H
#define LIFETIMEBOUND
Definition: attributes.h:16
int flags
Definition: bitcoin-tx.cpp:546
#define Assume(val)
Assume is the identity function.
Definition: check.h:97
CCoinsView backed by another CCoinsView.
Definition: coins.h:338
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
Definition: coins.cpp:39
BlockHash GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:42
CCoinsViewCursor * Cursor() const override
Get a cursor to iterate over the whole state.
Definition: coins.cpp:55
size_t EstimateSize() const override
Estimate database size (0 if not implemented)
Definition: coins.cpp:58
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:36
void SetBackend(CCoinsView &viewIn)
Definition: coins.cpp:48
CCoinsView * base
Definition: coins.h:340
std::vector< BlockHash > GetHeadBlocks() const override
Retrieve the range of blocks that may have been only partially written.
Definition: coins.cpp:45
void BatchWrite(CoinsViewCacheCursor &cursor, const BlockHash &hashBlock) override
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:51
CCoinsViewBacked(CCoinsView *viewIn)
Definition: coins.cpp:35
CCoinsViewCache & m_cache
Definition: coins.h:501
ResetGuard(const ResetGuard &)=delete
ResetGuard & operator=(ResetGuard &&)=delete
ResetGuard(ResetGuard &&)=delete
ResetGuard & operator=(const ResetGuard &)=delete
ResetGuard(CCoinsViewCache &cache LIFETIMEBOUND) noexcept
Definition: coins.h:502
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:358
void Sync()
Push the modifications applied to this cache to its base while retaining the contents of this cache (...
Definition: coins.cpp:320
void AddCoin(const COutPoint &outpoint, Coin coin, bool possible_overwrite)
Add a coin.
Definition: coins.cpp:98
const bool m_deterministic
Definition: coins.h:360
BlockHash GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: coins.cpp:218
size_t GetDirtyCount() const noexcept
Number of dirty cache entries (transaction outputs)
Definition: coins.h:478
CCoinsMapMemoryResource m_cache_coins_memory_resource
Definition: coins.h:368
bool SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr)
Spend a coin.
Definition: coins.cpp:174
ResetGuard CreateResetGuard() noexcept
Create a scoped guard that will call Reset() on this cache when it goes out of scope.
Definition: coins.h:516
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
Definition: coins.cpp:338
void BatchWrite(CoinsViewCacheCursor &cursor, const BlockHash &hashBlock) override
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:229
CCoinsViewCursor * Cursor() const override
Get a cursor to iterate over the whole state.
Definition: coins.h:403
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:354
void SetBestBlock(const BlockHash &hashBlock)
Definition: coins.cpp:225
BlockHash hashBlock
Make mutable so that we can "fill the cache" even from Get-methods declared as "const".
Definition: coins.h:367
size_t m_dirty_count
Definition: coins.h:378
void Flush(bool reallocate_cache=true)
Push the modifications applied to this cache to its base and wipe local state.
Definition: coins.cpp:308
void Reset() noexcept
Discard all modifications made to this cache without flushing to the base view.
Definition: coins.cpp:331
unsigned int GetCacheSize() const
Size of the cache (in number of transaction outputs)
Definition: coins.cpp:350
size_t cachedCoinsUsage
Definition: coins.h:376
CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const
Definition: coins.cpp:75
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
Definition: coins.cpp:213
CoinsCachePair m_sentinel
The starting sentinel of the flagged entry circular doubly linked list.
Definition: coins.h:372
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes)
Definition: coins.cpp:70
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:208
void SanityCheck() const
Run an internal sanity check on the cache data structure.
Definition: coins.cpp:379
CCoinsMap cacheCoins
Definition: coins.h:373
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:90
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
Definition: coins.cpp:200
void ReallocateCache()
Force a reallocation of the cache map.
Definition: coins.cpp:368
Cursor for iterating over CoinsView state.
Definition: coins.h:217
virtual void Next()=0
virtual bool Valid() const =0
CCoinsViewCursor(const BlockHash &hashBlockIn)
Definition: coins.h:219
virtual unsigned int GetValueSize() const =0
BlockHash hashBlock
Definition: coins.h:233
virtual ~CCoinsViewCursor()
Definition: coins.h:220
virtual bool GetKey(COutPoint &key) const =0
const BlockHash & GetBestBlock() const
Get best block at the time this cursor was created.
Definition: coins.h:230
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:551
void AddReadErrCallback(std::function< void()> f)
Definition: coins.h:556
std::optional< Coin > GetCoin(const COutPoint &outpoint) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:451
std::vector< std::function< void()> > m_err_callbacks
A list of callbacks to execute upon leveldb read error.
Definition: coins.h:567
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
Definition: coins.cpp:456
CCoinsViewErrorCatcher(CCoinsView *view)
Definition: coins.h:553
Abstract view on the open txout dataset.
Definition: coins.h:304
virtual void BatchWrite(CoinsViewCacheCursor &cursor, const BlockHash &hashBlock)
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: coins.cpp:22
virtual std::optional< Coin > GetCoin(const COutPoint &outpoint) 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:28
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:331
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:31
virtual size_t EstimateSize() const
Estimate database size (0 if not implemented)
Definition: coins.h:334
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:31
uint32_t GetHeight() const
Definition: coins.h:48
bool IsCoinBase() const
Definition: coins.h:49
void Clear()
Definition: coins.h:55
Coin(CTxOut outIn, uint32_t nHeightIn, bool IsCoinbase)
Constructor from a CTxOut and height/coinbase information.
Definition: coins.h:44
void Serialize(Stream &s) const
Definition: coins.h:60
CTxOut & GetTxOut()
Definition: coins.h:52
uint32_t nHeightAndIsCoinBase
Whether containing transaction was a coinbase and height at which the transaction was included into a...
Definition: coins.h:37
Coin()
Empty constructor.
Definition: coins.h:41
CTxOut out
Unspent transaction output.
Definition: coins.h:33
const CTxOut & GetTxOut() const
Definition: coins.h:53
bool IsSpent() const
Definition: coins.h:50
void Unserialize(Stream &s)
Definition: coins.h:66
size_t DynamicMemoryUsage() const
Definition: coins.h:71
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:419
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:158
std::pair< const COutPoint, CCoinsCacheEntry > CoinsCachePair
Definition: coins.h:77
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:212
CCoinsMap::allocator_type::ResourceType CCoinsMapMemoryResource
Definition: coins.h:214
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
constexpr bool TrySub(T &i, const U j) noexcept
Definition: overflow.h:32
#define VARINT(obj)
Definition: serialize.h:635
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:96
Coin coin
Definition: coins.h:130
CCoinsCacheEntry() noexcept=default
Flags
Definition: coins.h:132
@ 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:150
@ DIRTY
DIRTY means the CCoinsCacheEntry is potentially different from the version in the parent cache.
Definition: coins.h:140
void SetClean() noexcept
Definition: coins.h:166
static void SetFresh(CoinsCachePair &pair, CoinsCachePair &sentinel) noexcept
Definition: coins.h:161
uint8_t m_flags
Definition: coins.h:110
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:114
CoinsCachePair * m_next
Definition: coins.h:109
bool IsFresh() const noexcept
Definition: coins.h:176
~CCoinsCacheEntry()
Definition: coins.h:155
static void SetDirty(CoinsCachePair &pair, CoinsCachePair &sentinel) noexcept
Definition: coins.h:157
void SelfRef(CoinsCachePair &pair) noexcept
Only use this for initializing the linked list sentinel.
Definition: coins.h:191
bool IsDirty() const noexcept
Definition: coins.h:175
CoinsCachePair * m_prev
These are used to create a doubly linked list of flagged entries.
Definition: coins.h:108
CoinsCachePair * Next() const noexcept
Only call Next when this entry is DIRTY, FRESH, or both.
Definition: coins.h:179
CoinsCachePair * Prev() const noexcept
Only call Prev when this entry is DIRTY, FRESH, or both.
Definition: coins.h:185
Cursor for iterating over the linked list of flagged entries in CCoinsViewCache.
Definition: coins.h:250
CoinsCachePair & m_sentinel
Definition: coins.h:298
CoinsCachePair * NextAndMaybeErase(CoinsCachePair &current) noexcept
Return the next entry after current, possibly erasing current.
Definition: coins.h:273
size_t & m_dirty_count
Definition: coins.h:297
size_t GetTotalCount() const noexcept
Definition: coins.h:294
bool WillErase(CoinsCachePair &current) const noexcept
Definition: coins.h:290
size_t GetDirtyCount() const noexcept
Definition: coins.h:293
CCoinsMap & m_map
Definition: coins.h:299
CoinsCachePair * Begin() const noexcept
Definition: coins.h:267
CoinsViewCacheCursor(size_t &dirty_count 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:261
CoinsCachePair * End() const noexcept
Definition: coins.h:270
A TxId is the identifier of a transaction.
Definition: txid.h:14
assert(!tx.IsCoinBase())