Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/blockchain.cpp
Show First 20 Lines • Show All 851 Lines • ▼ Show 20 Lines | |||||
struct CCoinsStats { | struct CCoinsStats { | ||||
int nHeight; | int nHeight; | ||||
uint256 hashBlock; | uint256 hashBlock; | ||||
uint64_t nTransactions; | uint64_t nTransactions; | ||||
uint64_t nTransactionOutputs; | uint64_t nTransactionOutputs; | ||||
uint64_t nBogoSize; | uint64_t nBogoSize; | ||||
uint256 hashSerialized; | uint256 hashSerialized; | ||||
uint256 hashCommitment; | |||||
uint256 hashCommitmentCalculated; | |||||
uint64_t nDiskSize; | uint64_t nDiskSize; | ||||
Amount nTotalAmount; | Amount nTotalAmount; | ||||
CCoinsStats() | CCoinsStats() | ||||
: nHeight(0), nTransactions(0), nTransactionOutputs(0), nBogoSize(0), | : nHeight(0), nTransactions(0), nTransactionOutputs(0), nBogoSize(0), | ||||
nDiskSize(0), nTotalAmount(0) {} | nDiskSize(0), nTotalAmount(0) {} | ||||
}; | }; | ||||
Show All 17 Lines | static void ApplyStats(CCoinsStats &stats, CHashWriter &ss, const uint256 &hash, | ||||
} | } | ||||
ss << VARINT(0); | ss << VARINT(0); | ||||
} | } | ||||
//! Calculate statistics about the unspent transaction output set | //! Calculate statistics about the unspent transaction output set | ||||
static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) { | static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) { | ||||
std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor()); | std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor()); | ||||
CUtxoCommit commitmentCalculated; | |||||
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); | CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); | ||||
stats.hashBlock = pcursor->GetBestBlock(); | stats.hashBlock = pcursor->GetBestBlock(); | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight; | stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight; | ||||
} | } | ||||
ss << stats.hashBlock; | ss << stats.hashBlock; | ||||
uint256 prevkey; | uint256 prevkey; | ||||
std::map<uint32_t, Coin> outputs; | std::map<uint32_t, Coin> outputs; | ||||
while (pcursor->Valid()) { | while (pcursor->Valid()) { | ||||
boost::this_thread::interruption_point(); | boost::this_thread::interruption_point(); | ||||
COutPoint key; | COutPoint key; | ||||
Coin coin; | Coin coin; | ||||
if (pcursor->GetKey(key) && pcursor->GetValue(coin)) { | if (pcursor->GetKey(key) && pcursor->GetValue(coin)) { | ||||
commitmentCalculated.Add(key, coin); | |||||
if (!outputs.empty() && key.hash != prevkey) { | if (!outputs.empty() && key.hash != prevkey) { | ||||
ApplyStats(stats, ss, prevkey, outputs); | ApplyStats(stats, ss, prevkey, outputs); | ||||
outputs.clear(); | outputs.clear(); | ||||
} | } | ||||
prevkey = key.hash; | prevkey = key.hash; | ||||
outputs[key.n] = std::move(coin); | outputs[key.n] = std::move(coin); | ||||
} else { | } else { | ||||
return error("%s: unable to read value", __func__); | return error("%s: unable to read value", __func__); | ||||
} | } | ||||
pcursor->Next(); | pcursor->Next(); | ||||
} | } | ||||
if (!outputs.empty()) { | if (!outputs.empty()) { | ||||
ApplyStats(stats, ss, prevkey, outputs); | ApplyStats(stats, ss, prevkey, outputs); | ||||
} | } | ||||
stats.hashSerialized = ss.GetHash(); | stats.hashSerialized = ss.GetHash(); | ||||
stats.nDiskSize = view->EstimateSize(); | stats.nDiskSize = view->EstimateSize(); | ||||
CUtxoCommit *commitment = view->GetCommitment(); | |||||
stats.hashCommitment = | |||||
(commitment == nullptr ? uint256() : commitment->GetHash()); | |||||
stats.hashCommitmentCalculated = commitmentCalculated.GetHash(); | |||||
return true; | return true; | ||||
} | } | ||||
UniValue pruneblockchain(const Config &config, const JSONRPCRequest &request) { | UniValue pruneblockchain(const Config &config, const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 1) { | if (request.fHelp || request.params.size() != 1) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
"pruneblockchain\n" | "pruneblockchain\n" | ||||
"\nArguments:\n" | "\nArguments:\n" | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | if (request.fHelp || request.params.size() != 0) { | ||||
" \"height\":n, (numeric) The current block height (index)\n" | " \"height\":n, (numeric) The current block height (index)\n" | ||||
" \"bestblock\": \"hex\", (string) the best block hash hex\n" | " \"bestblock\": \"hex\", (string) the best block hash hex\n" | ||||
" \"transactions\": n, (numeric) The number of transactions\n" | " \"transactions\": n, (numeric) The number of transactions\n" | ||||
" \"txouts\": n, (numeric) The number of output " | " \"txouts\": n, (numeric) The number of output " | ||||
"transactions\n" | "transactions\n" | ||||
" \"bogosize\": n, (numeric) A database-independent " | " \"bogosize\": n, (numeric) A database-independent " | ||||
"metric for UTXO set size\n" | "metric for UTXO set size\n" | ||||
" \"hash_serialized\": \"hash\", (string) The serialized hash\n" | " \"hash_serialized\": \"hash\", (string) The serialized hash\n" | ||||
" \"commitment\": \"hash\", (string) The current UTXO commitment\n" | |||||
" \"commitment_calculated\": \"hash\", (string) The UTXO " | |||||
"commitment recalculated\n" | |||||
" \"disk_size\": n, (numeric) The estimated size of the " | " \"disk_size\": n, (numeric) The estimated size of the " | ||||
"chainstate on disk\n" | "chainstate on disk\n" | ||||
" \"total_amount\": x.xxx (numeric) The total amount\n" | " \"total_amount\": x.xxx (numeric) The total amount\n" | ||||
"}\n" | "}\n" | ||||
"\nExamples:\n" + | "\nExamples:\n" + | ||||
HelpExampleCli("gettxoutsetinfo", "") + | HelpExampleCli("gettxoutsetinfo", "") + | ||||
HelpExampleRpc("gettxoutsetinfo", "")); | HelpExampleRpc("gettxoutsetinfo", "")); | ||||
} | } | ||||
UniValue ret(UniValue::VOBJ); | UniValue ret(UniValue::VOBJ); | ||||
CCoinsStats stats; | CCoinsStats stats; | ||||
FlushStateToDisk(); | FlushStateToDisk(); | ||||
if (GetUTXOStats(pcoinsTip, stats)) { | if (GetUTXOStats(pcoinsTip, stats)) { | ||||
ret.push_back(Pair("height", int64_t(stats.nHeight))); | ret.push_back(Pair("height", int64_t(stats.nHeight))); | ||||
ret.push_back(Pair("bestblock", stats.hashBlock.GetHex())); | ret.push_back(Pair("bestblock", stats.hashBlock.GetHex())); | ||||
ret.push_back(Pair("transactions", int64_t(stats.nTransactions))); | ret.push_back(Pair("transactions", int64_t(stats.nTransactions))); | ||||
ret.push_back(Pair("txouts", int64_t(stats.nTransactionOutputs))); | ret.push_back(Pair("txouts", int64_t(stats.nTransactionOutputs))); | ||||
ret.push_back(Pair("bogosize", int64_t(stats.nBogoSize))); | ret.push_back(Pair("bogosize", int64_t(stats.nBogoSize))); | ||||
ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex())); | ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex())); | ||||
ret.push_back(Pair("commitment", stats.hashCommitment.GetHex())); | |||||
ret.push_back(Pair("commitment_calculated", | |||||
stats.hashCommitmentCalculated.GetHex())); | |||||
ret.push_back(Pair("disk_size", stats.nDiskSize)); | ret.push_back(Pair("disk_size", stats.nDiskSize)); | ||||
ret.push_back( | ret.push_back( | ||||
Pair("total_amount", ValueFromAmount(stats.nTotalAmount))); | Pair("total_amount", ValueFromAmount(stats.nTotalAmount))); | ||||
} else { | } else { | ||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set"); | throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set"); | ||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 730 Lines • Show Last 20 Lines |