Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/blockchain.cpp
Show First 20 Lines • Show All 851 Lines • ▼ Show 20 Lines | UniValue getblock(const Config &config, const JSONRPCRequest &request) { | ||||
return blockToJSON(block, pblockindex); | return blockToJSON(block, pblockindex); | ||||
} | } | ||||
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 nSerializedSize; | uint64_t nBogoSize; | ||||
uint256 hashSerialized; | uint256 hashSerialized; | ||||
uint64_t nDiskSize; | |||||
CAmount nTotalAmount; | CAmount nTotalAmount; | ||||
CCoinsStats() | CCoinsStats() | ||||
: nHeight(0), nTransactions(0), nTransactionOutputs(0), | : nHeight(0), nTransactions(0), nTransactionOutputs(0), nBogoSize(0), | ||||
nSerializedSize(0), nTotalAmount(0) {} | nDiskSize(0), nTotalAmount(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()); | ||||
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; | ||||
CAmount nTotalAmount = 0; | CAmount nTotalAmount = 0; | ||||
while (pcursor->Valid()) { | while (pcursor->Valid()) { | ||||
boost::this_thread::interruption_point(); | boost::this_thread::interruption_point(); | ||||
uint256 key; | uint256 key; | ||||
CCoins coins; | CCoins coins; | ||||
if (pcursor->GetKey(key) && pcursor->GetValue(coins)) { | if (pcursor->GetKey(key) && pcursor->GetValue(coins)) { | ||||
stats.nTransactions++; | stats.nTransactions++; | ||||
ss << key; | ss << key; | ||||
ss << VARINT(coins.nHeight * 2 + coins.fCoinBase); | |||||
for (size_t i = 0; i < coins.vout.size(); i++) { | for (size_t i = 0; i < coins.vout.size(); i++) { | ||||
const CTxOut &out = coins.vout[i]; | const CTxOut &out = coins.vout[i]; | ||||
if (!out.IsNull()) { | if (!out.IsNull()) { | ||||
stats.nTransactionOutputs++; | stats.nTransactionOutputs++; | ||||
ss << VARINT(i + 1); | ss << VARINT(i + 1); | ||||
ss << out; | ss << out; | ||||
nTotalAmount += out.nValue; | nTotalAmount += out.nValue; | ||||
stats.nBogoSize += | |||||
32 /* txid */ + 4 /* vout index */ + | |||||
4 /* height + coinbase */ + 8 /* amount */ + | |||||
2 /* scriptPubKey len */ + | |||||
out.scriptPubKey.size() /* scriptPubKey */; | |||||
} | } | ||||
} | } | ||||
stats.nSerializedSize += 32 + pcursor->GetValueSize(); | |||||
ss << VARINT(0); | ss << VARINT(0); | ||||
} else { | } else { | ||||
return error("%s: unable to read value", __func__); | return error("%s: unable to read value", __func__); | ||||
} | } | ||||
pcursor->Next(); | pcursor->Next(); | ||||
} | } | ||||
stats.hashSerialized = ss.GetHash(); | stats.hashSerialized = ss.GetHash(); | ||||
stats.nTotalAmount = nTotalAmount; | stats.nTotalAmount = nTotalAmount; | ||||
stats.nDiskSize = view->EstimateSize(); | |||||
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 63 Lines • ▼ Show 20 Lines | if (request.fHelp || request.params.size() != 0) { | ||||
"Note this call may take some time.\n" | "Note this call may take some time.\n" | ||||
"\nResult:\n" | "\nResult:\n" | ||||
"{\n" | "{\n" | ||||
" \"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" | ||||
" \"bytes_serialized\": n, (numeric) The serialized size\n" | " \"bogosize\": n, (numeric) A database-independent " | ||||
"metric for UTXO set size\n" | |||||
" \"hash_serialized\": \"hash\", (string) The serialized hash\n" | " \"hash_serialized\": \"hash\", (string) The serialized hash\n" | ||||
" \"disk_size\": n, (numeric) The estimated size of the " | |||||
"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("bytes_serialized", int64_t(stats.nSerializedSize))); | 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("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 630 Lines • Show Last 20 Lines |