77
88#include < coins.h>
99#include < hash.h>
10+ #include < index/utxosethash.h>
1011#include < serialize.h>
11- #include < validation.h>
1212#include < uint256.h>
1313#include < util/system.h>
14+ #include < validation.h>
1415
1516#include < map>
1617
1718#include < boost/thread.hpp>
1819
19-
20- static void ApplyStats (CCoinsStats &stats, CHashWriter& ss, const uint256& hash, const std::map<uint32_t , Coin>& outputs)
20+ static void ApplyStats (CCoinsStats &stats, const COutPoint outpoint, const Coin& coin)
2121{
22- assert (!outputs.empty ());
23- ss << hash;
24- ss << VARINT (outputs.begin ()->second .nHeight * 2 + outputs.begin ()->second .fCoinBase ? 1u : 0u );
2522 stats.nTransactions ++;
26- for (const auto & output : outputs) {
27- ss << VARINT (output.first + 1 );
28- ss << output.second .out .scriptPubKey ;
29- ss << VARINT (output.second .out .nValue , VarIntMode::NONNEGATIVE_SIGNED);
30- stats.nTransactionOutputs ++;
31- stats.nTotalAmount += output.second .out .nValue ;
32- stats.nBogoSize += 32 /* txid */ + 4 /* vout index */ + 4 /* height + coinbase */ + 8 /* amount */ +
33- 2 /* scriptPubKey len */ + output.second .out .scriptPubKey .size () /* scriptPubKey */ ;
34- }
35- ss << VARINT (0u );
23+ stats.nTransactionOutputs ++;
24+ stats.nTotalAmount += coin.out .nValue ;
25+ stats.nBogoSize += 32 /* txid */ + 4 /* vout index */ + 4 /* height + coinbase */ + 8 /* amount */ +
26+ 2 /* scriptPubKey len */ + coin.out .scriptPubKey .size () /* scriptPubKey */ ;
3627}
3728
3829// ! Calculate statistics about the unspent transaction output set
@@ -41,35 +32,34 @@ bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
4132 std::unique_ptr<CCoinsViewCursor> pcursor (view->Cursor ());
4233 assert (pcursor);
4334
44- CHashWriter ss (SER_GETHASH, PROTOCOL_VERSION);
35+ uint256 muhash_buf;
36+ const CBlockIndex* block_index;
4537 stats.hashBlock = pcursor->GetBestBlock ();
4638 {
4739 LOCK (cs_main);
48- stats. nHeight = LookupBlockIndex (stats.hashBlock )-> nHeight ;
40+ block_index = LookupBlockIndex (stats.hashBlock );
4941 }
50- ss << stats.hashBlock ;
51- uint256 prevkey;
52- std::map<uint32_t , Coin> outputs;
42+
43+ stats.nHeight = block_index->nHeight ;
44+
45+ if (!g_utxo_set_hash->LookupHash (block_index, muhash_buf)) {
46+ return false ;
47+ }
48+
49+ stats.hashSerialized = muhash_buf;
50+
5351 while (pcursor->Valid ()) {
5452 boost::this_thread::interruption_point ();
5553 COutPoint key;
5654 Coin coin;
5755 if (pcursor->GetKey (key) && pcursor->GetValue (coin)) {
58- if (!outputs.empty () && key.hash != prevkey) {
59- ApplyStats (stats, ss, prevkey, outputs);
60- outputs.clear ();
61- }
62- prevkey = key.hash ;
63- outputs[key.n ] = std::move (coin);
56+ ApplyStats (stats, key, coin);
6457 } else {
6558 return error (" %s: unable to read value" , __func__);
6659 }
6760 pcursor->Next ();
6861 }
69- if (!outputs.empty ()) {
70- ApplyStats (stats, ss, prevkey, outputs);
71- }
72- stats.hashSerialized = ss.GetHash ();
62+
7363 stats.nDiskSize = view->EstimateSize ();
7464 return true ;
7565}
0 commit comments