6
6
#include < node/coinstats.h>
7
7
8
8
#include < coins.h>
9
+ #include < crypto/muhash.h>
9
10
#include < hash.h>
10
11
#include < serialize.h>
11
12
#include < uint256.h>
@@ -27,21 +28,48 @@ static uint64_t GetBogoSize(const CScript& scriptPubKey)
27
28
scriptPubKey.size () /* scriptPubKey */ ;
28
29
}
29
30
30
- static void ApplyStats (CCoinsStats& stats, CHashWriter& ss, const uint256& hash, const std::map<uint32_t , Coin>& outputs)
31
+ static void ApplyHash (CCoinsStats& stats, CHashWriter& ss, const uint256& hash, const std::map<uint32_t , Coin>& outputs, std::map<uint32_t , Coin>::const_iterator it)
32
+ {
33
+ if (it == outputs.begin ()) {
34
+ ss << hash;
35
+ ss << VARINT (it->second .nHeight * 2 + it->second .fCoinBase ? 1u : 0u );
36
+ }
37
+
38
+ ss << VARINT (it->first + 1 );
39
+ ss << it->second .out .scriptPubKey ;
40
+ ss << VARINT (it->second .out .nValue , VarIntMode::NONNEGATIVE_SIGNED);
41
+
42
+ if (it == std::prev (outputs.end ())) {
43
+ ss << VARINT (0u );
44
+ }
45
+ }
46
+
47
+ static void ApplyHash (CCoinsStats& stats, std::nullptr_t , const uint256& hash, const std::map<uint32_t , Coin>& outputs, std::map<uint32_t , Coin>::const_iterator it) {}
48
+
49
+ static void ApplyHash (CCoinsStats& stats, MuHash3072& muhash, const uint256& hash, const std::map<uint32_t , Coin>& outputs, std::map<uint32_t , Coin>::const_iterator it)
50
+ {
51
+ COutPoint outpoint = COutPoint (hash, it->first );
52
+ Coin coin = it->second ;
53
+
54
+ CDataStream ss (SER_DISK, PROTOCOL_VERSION);
55
+ ss << outpoint;
56
+ ss << static_cast <uint32_t >(coin.nHeight * 2 + coin.fCoinBase );
57
+ ss << coin.out ;
58
+ muhash.Insert (MakeUCharSpan (ss));
59
+ }
60
+
61
+ template <typename T>
62
+ static void ApplyStats (CCoinsStats& stats, T& hash_obj, const uint256& hash, const std::map<uint32_t , Coin>& outputs)
31
63
{
32
64
assert (!outputs.empty ());
33
- ss << hash;
34
- ss << VARINT (outputs.begin ()->second .nHeight * 2 + outputs.begin ()->second .fCoinBase ? 1u : 0u );
35
65
stats.nTransactions ++;
36
- for (const auto & output : outputs) {
37
- ss << VARINT (output.first + 1 );
38
- ss << output.second .out .scriptPubKey ;
39
- ss << VARINT (output.second .out .nValue , VarIntMode::NONNEGATIVE_SIGNED);
66
+ for (auto it = outputs.begin (); it != outputs.end (); ++it) {
67
+ ApplyHash (stats, hash_obj, hash, outputs, it);
68
+
40
69
stats.nTransactionOutputs ++;
41
- stats.nTotalAmount += output. second .out .nValue ;
42
- stats.nBogoSize += GetBogoSize (output. second .out .scriptPubKey );
70
+ stats.nTotalAmount += it-> second .out .nValue ;
71
+ stats.nBogoSize += GetBogoSize (it-> second .out .scriptPubKey );
43
72
}
44
- ss << VARINT (0u );
45
73
}
46
74
47
75
static void ApplyStats (CCoinsStats& stats, std::nullptr_t , const uint256& hash, const std::map<uint32_t , Coin>& outputs)
@@ -105,6 +133,10 @@ bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, CoinStatsHashType hash_t
105
133
CHashWriter ss (SER_GETHASH, PROTOCOL_VERSION);
106
134
return GetUTXOStats (view, stats, ss);
107
135
}
136
+ case (CoinStatsHashType::MUHASH): {
137
+ MuHash3072 muhash;
138
+ return GetUTXOStats (view, stats, muhash);
139
+ }
108
140
case (CoinStatsHashType::NONE): {
109
141
return GetUTXOStats (view, stats, nullptr );
110
142
}
@@ -117,10 +149,18 @@ static void PrepareHash(CHashWriter& ss, CCoinsStats& stats)
117
149
{
118
150
ss << stats.hashBlock ;
119
151
}
152
+ // MuHash does not need the prepare step
153
+ static void PrepareHash (MuHash3072& muhash, CCoinsStats& stats) {}
120
154
static void PrepareHash (std::nullptr_t , CCoinsStats& stats) {}
121
155
122
156
static void FinalizeHash (CHashWriter& ss, CCoinsStats& stats)
123
157
{
124
158
stats.hashSerialized = ss.GetHash ();
125
159
}
160
+ static void FinalizeHash (MuHash3072& muhash, CCoinsStats& stats)
161
+ {
162
+ uint256 out;
163
+ muhash.Finalize (out);
164
+ stats.hashSerialized = out;
165
+ }
126
166
static void FinalizeHash (std::nullptr_t , CCoinsStats& stats) {}
0 commit comments