Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/blockchain.cpp
Show First 20 Lines • Show All 1,616 Lines • ▼ Show 20 Lines | UniValue reconsiderblock(const Config &config, const JSONRPCRequest &request) { | ||||
if (!state.IsValid()) { | if (!state.IsValid()) { | ||||
throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); | throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); | ||||
} | } | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
UniValue getchaintxstats(const Config &config, const JSONRPCRequest &request) { | |||||
if (request.fHelp || request.params.size() > 2) { | |||||
throw std::runtime_error( | |||||
"getchaintxstats ( nblocks blockhash )\n" | |||||
"\nCompute statistics about the total number and rate of " | |||||
"transactions in the chain.\n" | |||||
"\nArguments:\n" | |||||
"1. nblocks (numeric, optional) Size of the window in number " | |||||
"of blocks (default: one month).\n" | |||||
"2. \"blockhash\" (string, optional) The hash of the block that " | |||||
"ends the window.\n" | |||||
"\nResult:\n" | |||||
"{\n" | |||||
" \"time\": xxxxx, (numeric) The timestamp for the " | |||||
"final block in the window in UNIX format.\n" | |||||
" \"txcount\": xxxxx, (numeric) The total number of " | |||||
"transactions in the chain up to that point.\n" | |||||
" \"window_block_count\": xxxxx, (numeric) Size of the window in " | |||||
"number of blocks.\n" | |||||
" \"window_tx_count\": xxxxx, (numeric) The number of " | |||||
"transactions in the window. Only returned if " | |||||
"\"window_block_count\" is > 0.\n" | |||||
" \"window_interval\": xxxxx, (numeric) The elapsed time in " | |||||
"the window in seconds. Only returned if \"window_block_count\" is " | |||||
"> 0.\n" | |||||
" \"txrate\": x.xx, (numeric) The average rate of " | |||||
"transactions per second in the window. Only returned if " | |||||
"\"window_interval\" is > 0.\n" | |||||
"}\n" | |||||
"\nExamples:\n" + | |||||
HelpExampleCli("getchaintxstats", "") + | |||||
HelpExampleRpc("getchaintxstats", "2016")); | |||||
} | |||||
const CBlockIndex *pindex; | |||||
// By default: 1 month | |||||
int blockcount = | |||||
30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; | |||||
bool havehash = !request.params[1].isNull(); | |||||
uint256 hash; | |||||
if (havehash) { | |||||
hash = uint256S(request.params[1].get_str()); | |||||
} | |||||
{ | |||||
LOCK(cs_main); | |||||
if (havehash) { | |||||
auto it = mapBlockIndex.find(hash); | |||||
if (it == mapBlockIndex.end()) { | |||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | |||||
"Block not found"); | |||||
} | |||||
pindex = it->second; | |||||
if (!chainActive.Contains(pindex)) { | |||||
throw JSONRPCError(RPC_INVALID_PARAMETER, | |||||
"Block is not in main chain"); | |||||
} | |||||
} else { | |||||
pindex = chainActive.Tip(); | |||||
} | |||||
} | |||||
assert(pindex != nullptr); | |||||
if (request.params[0].isNull()) { | |||||
blockcount = std::max(0, std::min(blockcount, pindex->nHeight - 1)); | |||||
} else { | |||||
blockcount = request.params[0].get_int(); | |||||
if (blockcount < 0 || | |||||
(blockcount > 0 && blockcount >= pindex->nHeight)) { | |||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block count: " | |||||
"should be between 0 and " | |||||
"the block's height - 1"); | |||||
} | |||||
} | |||||
const CBlockIndex *pindexPast = | |||||
pindex->GetAncestor(pindex->nHeight - blockcount); | |||||
int nTimeDiff = | |||||
pindex->GetMedianTimePast() - pindexPast->GetMedianTimePast(); | |||||
int nTxDiff = pindex->nChainTx - pindexPast->nChainTx; | |||||
UniValue ret(UniValue::VOBJ); | |||||
ret.push_back(Pair("time", (int64_t)pindex->nTime)); | |||||
ret.push_back(Pair("txcount", (int64_t)pindex->nChainTx)); | |||||
ret.push_back(Pair("window_block_count", blockcount)); | |||||
if (blockcount > 0) { | |||||
ret.push_back(Pair("window_tx_count", nTxDiff)); | |||||
ret.push_back(Pair("window_interval", nTimeDiff)); | |||||
if (nTimeDiff > 0) { | |||||
ret.push_back(Pair("txrate", ((double)nTxDiff) / nTimeDiff)); | |||||
} | |||||
} | |||||
return ret; | |||||
} | |||||
// clang-format off | // clang-format off | ||||
static const CRPCCommand commands[] = { | static const CRPCCommand commands[] = { | ||||
// category name actor (function) okSafe argNames | // category name actor (function) okSafe argNames | ||||
// ------------------- ------------------------ ---------------------- ------ ---------- | // ------------------- ------------------------ ---------------------- ------ ---------- | ||||
{ "blockchain", "getblockchaininfo", getblockchaininfo, true, {} }, | { "blockchain", "getblockchaininfo", getblockchaininfo, true, {} }, | ||||
{ "blockchain", "getchaintxstats", &getchaintxstats, true, {"nblocks", "blockhash"} }, | |||||
{ "blockchain", "getbestblockhash", getbestblockhash, true, {} }, | { "blockchain", "getbestblockhash", getbestblockhash, true, {} }, | ||||
{ "blockchain", "getblockcount", getblockcount, true, {} }, | { "blockchain", "getblockcount", getblockcount, true, {} }, | ||||
{ "blockchain", "getblock", getblock, true, {"blockhash","verbose"} }, | { "blockchain", "getblock", getblock, true, {"blockhash","verbose"} }, | ||||
{ "blockchain", "getblockhash", getblockhash, true, {"height"} }, | { "blockchain", "getblockhash", getblockhash, true, {"height"} }, | ||||
{ "blockchain", "getblockheader", getblockheader, true, {"blockhash","verbose"} }, | { "blockchain", "getblockheader", getblockheader, true, {"blockhash","verbose"} }, | ||||
{ "blockchain", "getchaintips", getchaintips, true, {} }, | { "blockchain", "getchaintips", getchaintips, true, {} }, | ||||
{ "blockchain", "getdifficulty", getdifficulty, true, {} }, | { "blockchain", "getdifficulty", getdifficulty, true, {} }, | ||||
{ "blockchain", "getmempoolancestors", getmempoolancestors, true, {"txid","verbose"} }, | { "blockchain", "getmempoolancestors", getmempoolancestors, true, {"txid","verbose"} }, | ||||
Show All 24 Lines |