node/coinstats: Pass in BlockManager to GetUTXOStats

pull/826/head
Carl Dong 4 years ago
parent 2c3ba00693
commit 106bcd4f39

@ -83,7 +83,7 @@ static void ApplyStats(CCoinsStats& stats, T& hash_obj, const uint256& hash, con
//! Calculate statistics about the unspent transaction output set //! Calculate statistics about the unspent transaction output set
template <typename T> template <typename T>
static bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, const std::function<void()>& interruption_point) static bool GetUTXOStats(CCoinsView* view, BlockManager& blockman, CCoinsStats& stats, T hash_obj, const std::function<void()>& interruption_point)
{ {
stats = CCoinsStats(); stats = CCoinsStats();
std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor()); std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
@ -92,7 +92,8 @@ static bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, const
stats.hashBlock = pcursor->GetBestBlock(); stats.hashBlock = pcursor->GetBestBlock();
{ {
LOCK(cs_main); LOCK(cs_main);
stats.nHeight = g_chainman.m_blockman.LookupBlockIndex(stats.hashBlock)->nHeight; assert(std::addressof(g_chainman.m_blockman) == std::addressof(blockman));
stats.nHeight = blockman.LookupBlockIndex(stats.hashBlock)->nHeight;
} }
PrepareHash(hash_obj, stats); PrepareHash(hash_obj, stats);
@ -126,19 +127,19 @@ static bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, const
return true; return true;
} }
bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, CoinStatsHashType hash_type, const std::function<void()>& interruption_point) bool GetUTXOStats(CCoinsView* view, BlockManager& blockman, CCoinsStats& stats, CoinStatsHashType hash_type, const std::function<void()>& interruption_point)
{ {
switch (hash_type) { switch (hash_type) {
case(CoinStatsHashType::HASH_SERIALIZED): { case(CoinStatsHashType::HASH_SERIALIZED): {
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
return GetUTXOStats(view, stats, ss, interruption_point); return GetUTXOStats(view, blockman, stats, ss, interruption_point);
} }
case(CoinStatsHashType::MUHASH): { case(CoinStatsHashType::MUHASH): {
MuHash3072 muhash; MuHash3072 muhash;
return GetUTXOStats(view, stats, muhash, interruption_point); return GetUTXOStats(view, blockman, stats, muhash, interruption_point);
} }
case(CoinStatsHashType::NONE): { case(CoinStatsHashType::NONE): {
return GetUTXOStats(view, stats, nullptr, interruption_point); return GetUTXOStats(view, blockman, stats, nullptr, interruption_point);
} }
} // no default case, so the compiler can warn about missing cases } // no default case, so the compiler can warn about missing cases
assert(false); assert(false);

@ -8,6 +8,7 @@
#include <amount.h> #include <amount.h>
#include <uint256.h> #include <uint256.h>
#include <validation.h>
#include <cstdint> #include <cstdint>
#include <functional> #include <functional>
@ -36,6 +37,6 @@ struct CCoinsStats
}; };
//! Calculate statistics about the unspent transaction output set //! Calculate statistics about the unspent transaction output set
bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats, const CoinStatsHashType hash_type, const std::function<void()>& interruption_point = {}); bool GetUTXOStats(CCoinsView* view, BlockManager& blockman, CCoinsStats& stats, const CoinStatsHashType hash_type, const std::function<void()>& interruption_point = {});
#endif // BITCOIN_NODE_COINSTATS_H #endif // BITCOIN_NODE_COINSTATS_H

@ -1073,9 +1073,9 @@ static RPCHelpMan gettxoutsetinfo()
const CoinStatsHashType hash_type{request.params[0].isNull() ? CoinStatsHashType::HASH_SERIALIZED : ParseHashType(request.params[0].get_str())}; const CoinStatsHashType hash_type{request.params[0].isNull() ? CoinStatsHashType::HASH_SERIALIZED : ParseHashType(request.params[0].get_str())};
CCoinsView* coins_view = WITH_LOCK(cs_main, return &ChainstateActive().CoinsDB()); CCoinsView* coins_view = WITH_LOCK(::cs_main, return &::ChainstateActive().CoinsDB());
NodeContext& node = EnsureNodeContext(request.context); NodeContext& node = EnsureNodeContext(request.context);
if (GetUTXOStats(coins_view, stats, hash_type, node.rpc_interruption_point)) { if (GetUTXOStats(coins_view, WITH_LOCK(::cs_main, return std::ref(g_chainman.m_blockman)), stats, hash_type, node.rpc_interruption_point)) {
ret.pushKV("height", (int64_t)stats.nHeight); ret.pushKV("height", (int64_t)stats.nHeight);
ret.pushKV("bestblock", stats.hashBlock.GetHex()); ret.pushKV("bestblock", stats.hashBlock.GetHex());
ret.pushKV("transactions", (int64_t)stats.nTransactions); ret.pushKV("transactions", (int64_t)stats.nTransactions);
@ -2444,7 +2444,7 @@ UniValue CreateUTXOSnapshot(NodeContext& node, CChainState& chainstate, CAutoFil
chainstate.ForceFlushStateToDisk(); chainstate.ForceFlushStateToDisk();
if (!GetUTXOStats(&chainstate.CoinsDB(), stats, CoinStatsHashType::NONE, node.rpc_interruption_point)) { if (!GetUTXOStats(&chainstate.CoinsDB(), chainstate.m_blockman, stats, CoinStatsHashType::NONE, node.rpc_interruption_point)) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set"); throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
} }

@ -264,7 +264,7 @@ FUZZ_TARGET_INIT(coins_view, initialize_coins_view)
CCoinsStats stats; CCoinsStats stats;
bool expected_code_path = false; bool expected_code_path = false;
try { try {
(void)GetUTXOStats(&coins_view_cache, stats, CoinStatsHashType::HASH_SERIALIZED); (void)GetUTXOStats(&coins_view_cache, WITH_LOCK(::cs_main, return std::ref(g_chainman.m_blockman)), stats, CoinStatsHashType::HASH_SERIALIZED);
} catch (const std::logic_error&) { } catch (const std::logic_error&) {
expected_code_path = true; expected_code_path = true;
} }

@ -5425,7 +5425,7 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
// about the snapshot_chainstate. // about the snapshot_chainstate.
CCoinsViewDB* snapshot_coinsdb = WITH_LOCK(::cs_main, return &snapshot_chainstate.CoinsDB()); CCoinsViewDB* snapshot_coinsdb = WITH_LOCK(::cs_main, return &snapshot_chainstate.CoinsDB());
if (!GetUTXOStats(snapshot_coinsdb, stats, CoinStatsHashType::HASH_SERIALIZED, breakpoint_fnc)) { if (!GetUTXOStats(snapshot_coinsdb, WITH_LOCK(::cs_main, return std::ref(m_blockman)), stats, CoinStatsHashType::HASH_SERIALIZED, breakpoint_fnc)) {
LogPrintf("[snapshot] failed to generate coins stats\n"); LogPrintf("[snapshot] failed to generate coins stats\n");
return false; return false;
} }

Loading…
Cancel
Save