@@ -48,15 +48,35 @@ uint64_t GetBogoSize(const CScript& script_pub_key)
48
48
script_pub_key.size () /* scriptPubKey */ ;
49
49
}
50
50
51
- DataStream TxOutSer (const COutPoint& outpoint, const Coin& coin)
51
+ template <typename T>
52
+ static void TxOutSer (T& ss, const COutPoint& outpoint, const Coin& coin)
52
53
{
53
- DataStream ss{};
54
54
ss << outpoint;
55
- ss << static_cast <uint32_t >(coin.nHeight * 2 + coin.fCoinBase );
55
+ ss << static_cast <uint32_t >(( coin.nHeight << 1 ) + coin.fCoinBase );
56
56
ss << coin.out ;
57
- return ss;
58
57
}
59
58
59
+ static void ApplyCoinHash (HashWriter& ss, const COutPoint& outpoint, const Coin& coin)
60
+ {
61
+ TxOutSer (ss, outpoint, coin);
62
+ }
63
+
64
+ void ApplyCoinHash (MuHash3072& muhash, const COutPoint& outpoint, const Coin& coin)
65
+ {
66
+ DataStream ss{};
67
+ TxOutSer (ss, outpoint, coin);
68
+ muhash.Insert (MakeUCharSpan (ss));
69
+ }
70
+
71
+ void RemoveCoinHash (MuHash3072& muhash, const COutPoint& outpoint, const Coin& coin)
72
+ {
73
+ DataStream ss{};
74
+ TxOutSer (ss, outpoint, coin);
75
+ muhash.Remove (MakeUCharSpan (ss));
76
+ }
77
+
78
+ static void ApplyCoinHash (std::nullptr_t , const COutPoint& outpoint, const Coin& coin) {}
79
+
60
80
// ! Warning: be very careful when changing this! assumeutxo and UTXO snapshot
61
81
// ! validation commitments are reliant on the hash constructed by this
62
82
// ! function.
@@ -69,32 +89,13 @@ DataStream TxOutSer(const COutPoint& outpoint, const Coin& coin)
69
89
// ! It is also possible, though very unlikely, that a change in this
70
90
// ! construction could cause a previously invalid (and potentially malicious)
71
91
// ! UTXO snapshot to be considered valid.
72
- static void ApplyHash (HashWriter& ss, const uint256& hash, const std::map<uint32_t , Coin>& outputs)
73
- {
74
- for (auto it = outputs.begin (); it != outputs.end (); ++it) {
75
- if (it == outputs.begin ()) {
76
- ss << hash;
77
- ss << VARINT (it->second .nHeight * 2 + it->second .fCoinBase ? 1u : 0u );
78
- }
79
-
80
- ss << VARINT (it->first + 1 );
81
- ss << it->second .out .scriptPubKey ;
82
- ss << VARINT_MODE (it->second .out .nValue , VarIntMode::NONNEGATIVE_SIGNED);
83
-
84
- if (it == std::prev (outputs.end ())) {
85
- ss << VARINT (0u );
86
- }
87
- }
88
- }
89
-
90
- static void ApplyHash (std::nullptr_t , const uint256& hash, const std::map<uint32_t , Coin>& outputs) {}
91
-
92
- static void ApplyHash (MuHash3072& muhash, const uint256& hash, const std::map<uint32_t , Coin>& outputs)
92
+ template <typename T>
93
+ static void ApplyHash (T& hash_obj, const uint256& hash, const std::map<uint32_t , Coin>& outputs)
93
94
{
94
95
for (auto it = outputs.begin (); it != outputs.end (); ++it) {
95
96
COutPoint outpoint = COutPoint (hash, it->first );
96
97
Coin coin = it->second ;
97
- muhash. Insert ( MakeUCharSpan ( TxOutSer ( outpoint, coin)) );
98
+ ApplyCoinHash (hash_obj, outpoint, coin);
98
99
}
99
100
}
100
101
@@ -118,8 +119,6 @@ static bool ComputeUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, c
118
119
std::unique_ptr<CCoinsViewCursor> pcursor (view->Cursor ());
119
120
assert (pcursor);
120
121
121
- PrepareHash (hash_obj, stats);
122
-
123
122
uint256 prevkey;
124
123
std::map<uint32_t , Coin> outputs;
125
124
while (pcursor->Valid ()) {
@@ -180,15 +179,6 @@ std::optional<CCoinsStats> ComputeUTXOStats(CoinStatsHashType hash_type, CCoinsV
180
179
return stats;
181
180
}
182
181
183
- // The legacy hash serializes the hashBlock
184
- static void PrepareHash (HashWriter& ss, const CCoinsStats& stats)
185
- {
186
- ss << stats.hashBlock ;
187
- }
188
- // MuHash does not need the prepare step
189
- static void PrepareHash (MuHash3072& muhash, CCoinsStats& stats) {}
190
- static void PrepareHash (std::nullptr_t , CCoinsStats& stats) {}
191
-
192
182
static void FinalizeHash (HashWriter& ss, CCoinsStats& stats)
193
183
{
194
184
stats.hashSerialized = ss.GetHash ();
0 commit comments