Skip to content

Commit

Permalink
Add getchaintxstats RPC
Browse files Browse the repository at this point in the history
  • Loading branch information
sipa committed Feb 10, 2017
1 parent 36f9d3a commit 53d4292
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
66 changes: 66 additions & 0 deletions src/rpc/blockchain.cpp
Expand Up @@ -1413,10 +1413,76 @@ UniValue reconsiderblock(const JSONRPCRequest& request)
return NullUniValue;
}

UniValue getchaintxstats(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() > 2)
throw 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 statistics in UNIX format.\n"
" \"txcount\": xxxxx, (numeric) The total number of transactions in the chain up to that point.\n"
" \"txrate\": x.xx, (numeric) The average rate of transactions per second in the window.\n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("gettxratestats", "")
+ HelpExampleRpc("gettxratestats", "2016")
);

CBlockIndex* pindex;
int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month

if (request.params.size() > 0 && !request.params[0].isNull()) {
blockcount = request.params[0].get_int();
}

bool havehash = request.params.size() > 1 && !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();
}
}

if (blockcount < 1 || blockcount >= pindex->nHeight) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block count: should be between 1 and the block's height");
}

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("txrate", ((double)nTxDiff) / nTimeDiff));

return ret;
}

static const CRPCCommand commands[] =
{ // category name actor (function) okSafe argNames
// --------------------- ------------------------ ----------------------- ------ ----------
{ "blockchain", "getblockchaininfo", &getblockchaininfo, true, {} },
{ "blockchain", "getchaintxstats", &getchaintxstats, true, {"nblocks", "blockhash"} },
{ "blockchain", "getbestblockhash", &getbestblockhash, true, {} },
{ "blockchain", "getblockcount", &getblockcount, true, {} },
{ "blockchain", "getblock", &getblock, true, {"blockhash","verbose"} },
Expand Down
1 change: 1 addition & 0 deletions src/rpc/client.cpp
Expand Up @@ -81,6 +81,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "listunspent", 2, "addresses" },
{ "getblock", 1, "verbose" },
{ "getblockheader", 1, "verbose" },
{ "getchaintxstats", 0, "nblocks" },
{ "gettransaction", 1, "include_watchonly" },
{ "getrawtransaction", 1, "verbose" },
{ "createrawtransaction", 0, "transactions" },
Expand Down

0 comments on commit 53d4292

Please sign in to comment.