Skip to content

Commit 569cff5

Browse files
sipafjahr
authored andcommitted
muhash in gettxoutsetinfo
1 parent d55a51d commit 569cff5

File tree

2 files changed

+57
-17
lines changed

2 files changed

+57
-17
lines changed

src/hash.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <crypto/common.h>
1010
#include <crypto/ripemd160.h>
1111
#include <crypto/sha256.h>
12+
#include <crypto/sha512.h>
1213
#include <prevector.h>
1314
#include <serialize.h>
1415
#include <uint256.h>
@@ -191,6 +192,41 @@ class CHashVerifier : public CHashWriter
191192
}
192193
};
193194

195+
/** A writer stream that computes a 256-bit truncated SHA512. */
196+
class TruncatedSHA512Writer
197+
{
198+
private:
199+
CSHA512 ctx;
200+
201+
const int nType;
202+
const int nVersion;
203+
public:
204+
205+
TruncatedSHA512Writer(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) {}
206+
207+
int GetType() const { return nType; }
208+
int GetVersion() const { return nVersion; }
209+
210+
void write(const char *pch, size_t size) {
211+
ctx.Write((const unsigned char*)pch, size);
212+
}
213+
214+
uint256 GetHash() {
215+
unsigned char out[64];
216+
ctx.Finalize(out);
217+
uint256 result;
218+
memcpy((unsigned char*)&result, out, 32);
219+
return result;
220+
}
221+
222+
template<typename T>
223+
TruncatedSHA512Writer& operator<<(const T& obj) {
224+
// Serialize to this stream
225+
::Serialize(*this, obj);
226+
return (*this);
227+
}
228+
};
229+
194230
/** Compute the 256-bit hash of an object's serialization. */
195231
template<typename T>
196232
uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)

src/rpc/blockchain.cpp

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <chainparams.h>
1212
#include <coins.h>
1313
#include <consensus/validation.h>
14+
#include <crypto/muhash.h>
1415
#include <core_io.h>
1516
#include <hash.h>
1617
#include <index/blockfilterindex.h>
@@ -35,6 +36,7 @@
3536
#include <warnings.h>
3637

3738
#include <assert.h>
39+
3840
#include <stdint.h>
3941

4042
#include <univalue.h>
@@ -916,29 +918,28 @@ struct CCoinsStats
916918
uint64_t nTransactions;
917919
uint64_t nTransactionOutputs;
918920
uint64_t nBogoSize;
919-
uint256 hashSerialized;
921+
uint256 muhash;
920922
uint64_t nDiskSize;
921923
CAmount nTotalAmount;
922924

923925
CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nBogoSize(0), nDiskSize(0), nTotalAmount(0) {}
924926
};
925927

926-
static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash, const std::map<uint32_t, Coin>& outputs)
928+
static void ApplyStats(CCoinsStats &stats, MuHash3072& acc, const uint256& hash, const std::map<uint32_t, Coin>& outputs)
927929
{
928930
assert(!outputs.empty());
929-
ss << hash;
930-
ss << VARINT(outputs.begin()->second.nHeight * 2 + outputs.begin()->second.fCoinBase ? 1u : 0u);
931931
stats.nTransactions++;
932-
for (const auto& output : outputs) {
933-
ss << VARINT(output.first + 1);
934-
ss << output.second.out.scriptPubKey;
935-
ss << VARINT(output.second.out.nValue, VarIntMode::NONNEGATIVE_SIGNED);
932+
for (const auto output : outputs) {
933+
TruncatedSHA512Writer ss(SER_DISK, 0);
934+
ss << COutPoint(hash, output.first);
935+
ss << (uint32_t)(output.second.nHeight * 2 + output.second.fCoinBase);
936+
ss << output.second.out;
937+
acc *= MuHash3072(ss.GetHash().begin());
936938
stats.nTransactionOutputs++;
937939
stats.nTotalAmount += output.second.out.nValue;
938940
stats.nBogoSize += 32 /* txid */ + 4 /* vout index */ + 4 /* height + coinbase */ + 8 /* amount */ +
939941
2 /* scriptPubKey len */ + output.second.out.scriptPubKey.size() /* scriptPubKey */;
940942
}
941-
ss << VARINT(0u);
942943
}
943944

944945
//! Calculate statistics about the unspent transaction output set
@@ -947,22 +948,21 @@ static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
947948
std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
948949
assert(pcursor);
949950

950-
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
951951
stats.hashBlock = pcursor->GetBestBlock();
952952
{
953953
LOCK(cs_main);
954954
stats.nHeight = LookupBlockIndex(stats.hashBlock)->nHeight;
955955
}
956-
ss << stats.hashBlock;
957-
uint256 prevkey;
956+
MuHash3072 acc;
958957
std::map<uint32_t, Coin> outputs;
958+
uint256 prevkey;
959959
while (pcursor->Valid()) {
960960
boost::this_thread::interruption_point();
961961
COutPoint key;
962962
Coin coin;
963963
if (pcursor->GetKey(key) && pcursor->GetValue(coin)) {
964964
if (!outputs.empty() && key.hash != prevkey) {
965-
ApplyStats(stats, ss, prevkey, outputs);
965+
ApplyStats(stats, acc, prevkey, outputs);
966966
outputs.clear();
967967
}
968968
prevkey = key.hash;
@@ -973,9 +973,13 @@ static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
973973
pcursor->Next();
974974
}
975975
if (!outputs.empty()) {
976-
ApplyStats(stats, ss, prevkey, outputs);
976+
ApplyStats(stats, acc, prevkey, outputs);
977977
}
978-
stats.hashSerialized = ss.GetHash();
978+
unsigned char data[384];
979+
acc.Finalize(data);
980+
TruncatedSHA512Writer ss(SER_DISK, 0);
981+
ss << FLATDATA(data);
982+
stats.muhash = ss.GetHash();
979983
stats.nDiskSize = view->EstimateSize();
980984
return true;
981985
}
@@ -1049,7 +1053,7 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request)
10491053
" \"transactions\": n, (numeric) The number of transactions with unspent outputs\n"
10501054
" \"txouts\": n, (numeric) The number of unspent transaction outputs\n"
10511055
" \"bogosize\": n, (numeric) A meaningless metric for UTXO set size\n"
1052-
" \"hash_serialized_2\": \"hash\", (string) The serialized hash\n"
1056+
" \"muhash\": \"hash\", (string) Rolling UTXO set hash\n"
10531057
" \"disk_size\": n, (numeric) The estimated size of the chainstate on disk\n"
10541058
" \"total_amount\": x.xxx (numeric) The total amount\n"
10551059
"}\n"
@@ -1072,7 +1076,7 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request)
10721076
ret.pushKV("transactions", (int64_t)stats.nTransactions);
10731077
ret.pushKV("txouts", (int64_t)stats.nTransactionOutputs);
10741078
ret.pushKV("bogosize", (int64_t)stats.nBogoSize);
1075-
ret.pushKV("hash_serialized_2", stats.hashSerialized.GetHex());
1079+
ret.pushKV("muhash", stats.muhash.GetHex());
10761080
ret.pushKV("disk_size", stats.nDiskSize);
10771081
ret.pushKV("total_amount", ValueFromAmount(stats.nTotalAmount));
10781082
} else {

0 commit comments

Comments
 (0)