Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/blockchain.cpp
Show All 10 Lines | |||||
#include <checkpoints.h> | #include <checkpoints.h> | ||||
#include <coins.h> | #include <coins.h> | ||||
#include <config.h> | #include <config.h> | ||||
#include <consensus/validation.h> | #include <consensus/validation.h> | ||||
#include <core_io.h> | #include <core_io.h> | ||||
#include <hash.h> | #include <hash.h> | ||||
#include <index/txindex.h> | #include <index/txindex.h> | ||||
#include <key_io.h> | #include <key_io.h> | ||||
#include <node/coinstats.h> | |||||
#include <policy/policy.h> | #include <policy/policy.h> | ||||
#include <primitives/transaction.h> | #include <primitives/transaction.h> | ||||
#include <rpc/server.h> | #include <rpc/server.h> | ||||
#include <rpc/util.h> | #include <rpc/util.h> | ||||
#include <script/descriptor.h> | #include <script/descriptor.h> | ||||
#include <streams.h> | #include <streams.h> | ||||
#include <sync.h> | #include <sync.h> | ||||
#include <txdb.h> | #include <txdb.h> | ||||
▲ Show 20 Lines • Show All 1,011 Lines • ▼ Show 20 Lines | if (verbosity <= 0) { | ||||
std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); | std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); | ||||
return strHex; | return strHex; | ||||
} | } | ||||
return blockToJSON(block, ::ChainActive().Tip(), pblockindex, | return blockToJSON(block, ::ChainActive().Tip(), pblockindex, | ||||
verbosity >= 2); | verbosity >= 2); | ||||
} | } | ||||
struct CCoinsStats { | |||||
int nHeight; | |||||
BlockHash hashBlock; | |||||
uint64_t nTransactions; | |||||
uint64_t nTransactionOutputs; | |||||
uint64_t nBogoSize; | |||||
uint256 hashSerialized; | |||||
uint64_t nDiskSize; | |||||
Amount nTotalAmount; | |||||
CCoinsStats() | |||||
: nHeight(0), nTransactions(0), nTransactionOutputs(0), nBogoSize(0), | |||||
nDiskSize(0), nTotalAmount() {} | |||||
}; | |||||
static void ApplyStats(CCoinsStats &stats, CHashWriter &ss, const uint256 &hash, | |||||
const std::map<uint32_t, Coin> &outputs) { | |||||
assert(!outputs.empty()); | |||||
ss << hash; | |||||
ss << VARINT(outputs.begin()->second.GetHeight() * 2 + | |||||
outputs.begin()->second.IsCoinBase()); | |||||
stats.nTransactions++; | |||||
for (const auto &output : outputs) { | |||||
ss << VARINT(output.first + 1); | |||||
ss << output.second.GetTxOut().scriptPubKey; | |||||
ss << VARINT(output.second.GetTxOut().nValue / SATOSHI, | |||||
VarIntMode::NONNEGATIVE_SIGNED); | |||||
stats.nTransactionOutputs++; | |||||
stats.nTotalAmount += output.second.GetTxOut().nValue; | |||||
stats.nBogoSize += | |||||
32 /* txid */ + 4 /* vout index */ + 4 /* height + coinbase */ + | |||||
8 /* amount */ + 2 /* scriptPubKey len */ + | |||||
output.second.GetTxOut().scriptPubKey.size() /* scriptPubKey */; | |||||
} | |||||
ss << VARINT(0u); | |||||
} | |||||
//! Calculate statistics about the unspent transaction output set | |||||
static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) { | |||||
std::unique_ptr<CCoinsViewCursor> 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; | |||||
uint256 prevkey; | |||||
std::map<uint32_t, Coin> outputs; | |||||
while (pcursor->Valid()) { | |||||
boost::this_thread::interruption_point(); | |||||
COutPoint key; | |||||
Coin coin; | |||||
if (pcursor->GetKey(key) && pcursor->GetValue(coin)) { | |||||
if (!outputs.empty() && key.GetTxId() != prevkey) { | |||||
ApplyStats(stats, ss, prevkey, outputs); | |||||
outputs.clear(); | |||||
} | |||||
prevkey = key.GetTxId(); | |||||
outputs[key.GetN()] = std::move(coin); | |||||
} else { | |||||
return error("%s: unable to read value", __func__); | |||||
} | |||||
pcursor->Next(); | |||||
} | |||||
if (!outputs.empty()) { | |||||
ApplyStats(stats, ss, prevkey, outputs); | |||||
} | |||||
stats.hashSerialized = ss.GetHash(); | |||||
stats.nDiskSize = view->EstimateSize(); | |||||
return true; | |||||
} | |||||
static UniValue pruneblockchain(const Config &config, | static UniValue pruneblockchain(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 1) { | if (request.fHelp || request.params.size() != 1) { | ||||
throw std::runtime_error(RPCHelpMan{ | throw std::runtime_error(RPCHelpMan{ | ||||
"pruneblockchain", | "pruneblockchain", | ||||
"", | "", | ||||
{ | { | ||||
{"height", RPCArg::Type::NUM, /* opt */ false, | {"height", RPCArg::Type::NUM, /* opt */ false, | ||||
▲ Show 20 Lines • Show All 1,702 Lines • Show Last 20 Lines |