From 605884ef21318fc3f326dbdf4901cb353ba63fab Mon Sep 17 00:00:00 2001 From: Fabian Jahr Date: Tue, 2 Jun 2020 23:41:04 +0200 Subject: refactor: Extract GetBogoSize function --- src/node/coinstats.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/node') diff --git a/src/node/coinstats.cpp b/src/node/coinstats.cpp index e3c4c828b6..faa62420cd 100644 --- a/src/node/coinstats.cpp +++ b/src/node/coinstats.cpp @@ -8,12 +8,22 @@ #include #include #include -#include #include #include +#include #include +static uint64_t GetBogoSize(const CScript& scriptPubKey) +{ + return 32 /* txid */ + + 4 /* vout index */ + + 4 /* height + coinbase */ + + 8 /* amount */ + + 2 /* scriptPubKey len */ + + scriptPubKey.size() /* scriptPubKey */; +} + static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash, const std::map& outputs) { assert(!outputs.empty()); @@ -26,8 +36,7 @@ static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash, ss << VARINT_MODE(output.second.out.nValue, VarIntMode::NONNEGATIVE_SIGNED); stats.nTransactionOutputs++; stats.nTotalAmount += output.second.out.nValue; - stats.nBogoSize += 32 /* txid */ + 4 /* vout index */ + 4 /* height + coinbase */ + 8 /* amount */ + - 2 /* scriptPubKey len */ + output.second.out.scriptPubKey.size() /* scriptPubKey */; + stats.nBogoSize += GetBogoSize(output.second.out.scriptPubKey); } ss << VARINT(0u); } -- cgit v1.2.3 From a712cf6f6801157667fcf36d1c498b6fff6d328a Mon Sep 17 00:00:00 2001 From: Fabian Jahr Date: Tue, 2 Jun 2020 23:52:34 +0200 Subject: rpc: gettxoutsetinfo can specify hash_type (only legacy option for now) --- src/node/coinstats.cpp | 40 +++++++++++++++++++++++++++++++++------- src/node/coinstats.h | 6 +++++- 2 files changed, 38 insertions(+), 8 deletions(-) (limited to 'src/node') diff --git a/src/node/coinstats.cpp b/src/node/coinstats.cpp index faa62420cd..cc5e3cb627 100644 --- a/src/node/coinstats.cpp +++ b/src/node/coinstats.cpp @@ -24,7 +24,7 @@ static uint64_t GetBogoSize(const CScript& scriptPubKey) scriptPubKey.size() /* scriptPubKey */; } -static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash, const std::map& outputs) +static void ApplyStats(CCoinsStats& stats, CHashWriter& ss, const uint256& hash, const std::map& outputs) { assert(!outputs.empty()); ss << hash; @@ -42,19 +42,21 @@ static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash, } //! Calculate statistics about the unspent transaction output set -bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, const std::function& interruption_point) +template +static bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, const std::function& interruption_point) { stats = CCoinsStats(); std::unique_ptr pcursor(view->Cursor()); assert(pcursor); - CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); stats.hashBlock = pcursor->GetBestBlock(); { LOCK(cs_main); stats.nHeight = LookupBlockIndex(stats.hashBlock)->nHeight; } - ss << stats.hashBlock; + + PrepareHash(hash_obj, stats); + uint256 prevkey; std::map outputs; while (pcursor->Valid()) { @@ -63,7 +65,7 @@ bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, const std::functionGetKey(key) && pcursor->GetValue(coin)) { if (!outputs.empty() && key.hash != prevkey) { - ApplyStats(stats, ss, prevkey, outputs); + ApplyStats(stats, hash_obj, prevkey, outputs); outputs.clear(); } prevkey = key.hash; @@ -75,9 +77,33 @@ bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, const std::functionNext(); } if (!outputs.empty()) { - ApplyStats(stats, ss, prevkey, outputs); + ApplyStats(stats, hash_obj, prevkey, outputs); } - stats.hashSerialized = ss.GetHash(); + + FinalizeHash(hash_obj, stats); + stats.nDiskSize = view->EstimateSize(); return true; } + +bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, CoinStatsHashType hash_type, const std::function& interruption_point) +{ + switch (hash_type) { + case(CoinStatsHashType::HASH_SERIALIZED): { + CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); + return GetUTXOStats(view, stats, ss, interruption_point); + } + } // no default case, so the compiler can warn about missing cases + assert(false); +} + +// The legacy hash serializes the hashBlock +static void PrepareHash(CHashWriter& ss, CCoinsStats& stats) +{ + ss << stats.hashBlock; +} + +static void FinalizeHash(CHashWriter& ss, CCoinsStats& stats) +{ + stats.hashSerialized = ss.GetHash(); +} diff --git a/src/node/coinstats.h b/src/node/coinstats.h index d9cdaa3036..1d0270d56d 100644 --- a/src/node/coinstats.h +++ b/src/node/coinstats.h @@ -14,6 +14,10 @@ class CCoinsView; +enum class CoinStatsHashType { + HASH_SERIALIZED, +}; + struct CCoinsStats { int nHeight{0}; @@ -30,6 +34,6 @@ struct CCoinsStats }; //! Calculate statistics about the unspent transaction output set -bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, const std::function& interruption_point = {}); +bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, const CoinStatsHashType hash_type, const std::function& interruption_point = {}); #endif // BITCOIN_NODE_COINSTATS_H -- cgit v1.2.3 From f17a4d1c4ddce6935a353004898fb4e8618a213e Mon Sep 17 00:00:00 2001 From: Fabian Jahr Date: Tue, 2 Jun 2020 23:56:28 +0200 Subject: rpc: Add hash_type NONE to gettxoutsetinfo --- src/node/coinstats.cpp | 16 ++++++++++++++++ src/node/coinstats.h | 1 + 2 files changed, 17 insertions(+) (limited to 'src/node') diff --git a/src/node/coinstats.cpp b/src/node/coinstats.cpp index cc5e3cb627..fb46ea1731 100644 --- a/src/node/coinstats.cpp +++ b/src/node/coinstats.cpp @@ -41,6 +41,17 @@ static void ApplyStats(CCoinsStats& stats, CHashWriter& ss, const uint256& hash, ss << VARINT(0u); } +static void ApplyStats(CCoinsStats& stats, std::nullptr_t, const uint256& hash, const std::map& outputs) +{ + assert(!outputs.empty()); + stats.nTransactions++; + for (const auto& output : outputs) { + stats.nTransactionOutputs++; + stats.nTotalAmount += output.second.out.nValue; + stats.nBogoSize += GetBogoSize(output.second.out.scriptPubKey); + } +} + //! Calculate statistics about the unspent transaction output set template static bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, const std::function& interruption_point) @@ -93,6 +104,9 @@ bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, CoinStatsHashType hash_t CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); return GetUTXOStats(view, stats, ss, interruption_point); } + case(CoinStatsHashType::NONE): { + return GetUTXOStats(view, stats, nullptr, interruption_point); + } } // no default case, so the compiler can warn about missing cases assert(false); } @@ -102,8 +116,10 @@ static void PrepareHash(CHashWriter& ss, CCoinsStats& stats) { ss << stats.hashBlock; } +static void PrepareHash(std::nullptr_t, CCoinsStats& stats) {} static void FinalizeHash(CHashWriter& ss, CCoinsStats& stats) { stats.hashSerialized = ss.GetHash(); } +static void FinalizeHash(std::nullptr_t, CCoinsStats& stats) {} diff --git a/src/node/coinstats.h b/src/node/coinstats.h index 1d0270d56d..2a7441c10e 100644 --- a/src/node/coinstats.h +++ b/src/node/coinstats.h @@ -16,6 +16,7 @@ class CCoinsView; enum class CoinStatsHashType { HASH_SERIALIZED, + NONE, }; struct CCoinsStats -- cgit v1.2.3