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