Bitcoin Core  0.20.99
P2P Digital Currency
coinstats.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2020 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 #include <node/coinstats.h>
7 
8 #include <coins.h>
9 #include <hash.h>
10 #include <serialize.h>
11 #include <uint256.h>
12 #include <util/system.h>
13 #include <validation.h>
14 
15 #include <map>
16 
17 static uint64_t GetBogoSize(const CScript& scriptPubKey)
18 {
19  return 32 /* txid */ +
20  4 /* vout index */ +
21  4 /* height + coinbase */ +
22  8 /* amount */ +
23  2 /* scriptPubKey len */ +
24  scriptPubKey.size() /* scriptPubKey */;
25 }
26 
27 static void ApplyStats(CCoinsStats& stats, CHashWriter& ss, const uint256& hash, const std::map<uint32_t, Coin>& outputs)
28 {
29  assert(!outputs.empty());
30  ss << hash;
31  ss << VARINT(outputs.begin()->second.nHeight * 2 + outputs.begin()->second.fCoinBase ? 1u : 0u);
32  stats.nTransactions++;
33  for (const auto& output : outputs) {
34  ss << VARINT(output.first + 1);
35  ss << output.second.out.scriptPubKey;
36  ss << VARINT_MODE(output.second.out.nValue, VarIntMode::NONNEGATIVE_SIGNED);
37  stats.nTransactionOutputs++;
38  stats.nTotalAmount += output.second.out.nValue;
39  stats.nBogoSize += GetBogoSize(output.second.out.scriptPubKey);
40  }
41  ss << VARINT(0u);
42 }
43 
44 static void ApplyStats(CCoinsStats& stats, std::nullptr_t, const uint256& hash, const std::map<uint32_t, Coin>& outputs)
45 {
46  assert(!outputs.empty());
47  stats.nTransactions++;
48  for (const auto& output : outputs) {
49  stats.nTransactionOutputs++;
50  stats.nTotalAmount += output.second.out.nValue;
51  stats.nBogoSize += GetBogoSize(output.second.out.scriptPubKey);
52  }
53 }
54 
56 template <typename T>
57 static bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, const std::function<void()>& interruption_point)
58 {
59  stats = CCoinsStats();
60  std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
61  assert(pcursor);
62 
63  stats.hashBlock = pcursor->GetBestBlock();
64  {
65  LOCK(cs_main);
66  stats.nHeight = LookupBlockIndex(stats.hashBlock)->nHeight;
67  }
68 
69  PrepareHash(hash_obj, stats);
70 
71  uint256 prevkey;
72  std::map<uint32_t, Coin> outputs;
73  while (pcursor->Valid()) {
74  interruption_point();
75  COutPoint key;
76  Coin coin;
77  if (pcursor->GetKey(key) && pcursor->GetValue(coin)) {
78  if (!outputs.empty() && key.hash != prevkey) {
79  ApplyStats(stats, hash_obj, prevkey, outputs);
80  outputs.clear();
81  }
82  prevkey = key.hash;
83  outputs[key.n] = std::move(coin);
84  stats.coins_count++;
85  } else {
86  return error("%s: unable to read value", __func__);
87  }
88  pcursor->Next();
89  }
90  if (!outputs.empty()) {
91  ApplyStats(stats, hash_obj, prevkey, outputs);
92  }
93 
94  FinalizeHash(hash_obj, stats);
95 
96  stats.nDiskSize = view->EstimateSize();
97  return true;
98 }
99 
100 bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, CoinStatsHashType hash_type, const std::function<void()>& interruption_point)
101 {
102  switch (hash_type) {
105  return GetUTXOStats(view, stats, ss, interruption_point);
106  }
107  case(CoinStatsHashType::NONE): {
108  return GetUTXOStats(view, stats, nullptr, interruption_point);
109  }
110  } // no default case, so the compiler can warn about missing cases
111  assert(false);
112 }
113 
114 // The legacy hash serializes the hashBlock
115 static void PrepareHash(CHashWriter& ss, CCoinsStats& stats)
116 {
117  ss << stats.hashBlock;
118 }
119 static void PrepareHash(std::nullptr_t, CCoinsStats& stats) {}
120 
121 static void FinalizeHash(CHashWriter& ss, CCoinsStats& stats)
122 {
123  stats.hashSerialized = ss.GetHash();
124 }
125 static void FinalizeHash(std::nullptr_t, CCoinsStats& stats) {}
#define VARINT(obj)
Definition: serialize.h:479
uint64_t nTransactionOutputs
Definition: coinstats.h:27
uint256 hashBlock
Definition: coinstats.h:25
A UTXO entry.
Definition: coins.h:30
int nHeight
Definition: coinstats.h:24
static uint64_t GetBogoSize(const CScript &scriptPubKey)
Definition: coinstats.cpp:17
virtual CCoinsViewCursor * Cursor() const
Get a cursor to iterate over the whole state.
Definition: coins.cpp:16
uint64_t nTransactions
Definition: coinstats.h:26
uint64_t nDiskSize
Definition: coinstats.h:30
uint64_t nBogoSize
Definition: coinstats.h:28
CAmount nTotalAmount
Definition: coinstats.h:31
uint256 hashSerialized
Definition: coinstats.h:29
static void FinalizeHash(CHashWriter &ss, CCoinsStats &stats)
Definition: coinstats.cpp:121
CoinStatsHashType
Definition: coinstats.h:17
#define VARINT_MODE(obj, mode)
Definition: serialize.h:478
Abstract view on the open txout dataset.
Definition: coins.h:180
#define LOCK(cs)
Definition: sync.h:230
uint64_t coins_count
The number of coins contained.
Definition: coinstats.h:34
uint32_t n
Definition: transaction.h:30
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
Definition: validation.cpp:129
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:26
static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats, T hash_obj, const std::function< void()> &interruption_point)
Calculate statistics about the unspent transaction output set.
Definition: coinstats.cpp:57
uint256 GetHash()
Compute the double-SHA256 hash of all data written to this object.
Definition: hash.h:122
CBlockIndex * LookupBlockIndex(const uint256 &hash)
Definition: validation.cpp:173
256-bit opaque blob.
Definition: uint256.h:124
static void ApplyStats(CCoinsStats &stats, CHashWriter &ss, const uint256 &hash, const std::map< uint32_t, Coin > &outputs)
Definition: coinstats.cpp:27
virtual size_t EstimateSize() const
Estimate database size (0 if not implemented)
Definition: coins.h:212
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:404
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:12
static void PrepareHash(CHashWriter &ss, CCoinsStats &stats)
Definition: coinstats.cpp:115
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:100
size_type size() const
Definition: prevector.h:282
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:150
bool error(const char *fmt, const Args &... args)
Definition: system.h:52
uint256 hash
Definition: transaction.h:29