@@ -1415,10 +1415,76 @@ UniValue reconsiderblock(const JSONRPCRequest& request)
14151415 return NullUniValue;
14161416}
14171417
1418+ UniValue getchaintxstats (const JSONRPCRequest& request)
1419+ {
1420+ if (request.fHelp || request.params .size () > 2 )
1421+ throw std::runtime_error (
1422+ " getchaintxstats ( nblocks blockhash )\n "
1423+ " \n Compute statistics about the total number and rate of transactions in the chain.\n "
1424+ " \n Arguments:\n "
1425+ " 1. nblocks (numeric, optional) Size of the window in number of blocks (default: one month).\n "
1426+ " 2. \" blockhash\" (string, optional) The hash of the block that ends the window.\n "
1427+ " \n Result:\n "
1428+ " {\n "
1429+ " \" time\" : xxxxx, (numeric) The timestamp for the statistics in UNIX format.\n "
1430+ " \" txcount\" : xxxxx, (numeric) The total number of transactions in the chain up to that point.\n "
1431+ " \" txrate\" : x.xx, (numeric) The average rate of transactions per second in the window.\n "
1432+ " }\n "
1433+ " \n Examples:\n "
1434+ + HelpExampleCli (" getchaintxstats" , " " )
1435+ + HelpExampleRpc (" getchaintxstats" , " 2016" )
1436+ );
1437+
1438+ const CBlockIndex* pindex;
1439+ int blockcount = 30 * 24 * 60 * 60 / Params ().GetConsensus ().nPowTargetSpacing ; // By default: 1 month
1440+
1441+ if (request.params .size () > 0 && !request.params [0 ].isNull ()) {
1442+ blockcount = request.params [0 ].get_int ();
1443+ }
1444+
1445+ bool havehash = request.params .size () > 1 && !request.params [1 ].isNull ();
1446+ uint256 hash;
1447+ if (havehash) {
1448+ hash = uint256S (request.params [1 ].get_str ());
1449+ }
1450+
1451+ {
1452+ LOCK (cs_main);
1453+ if (havehash) {
1454+ auto it = mapBlockIndex.find (hash);
1455+ if (it == mapBlockIndex.end ()) {
1456+ throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, " Block not found" );
1457+ }
1458+ pindex = it->second ;
1459+ if (!chainActive.Contains (pindex)) {
1460+ throw JSONRPCError (RPC_INVALID_PARAMETER, " Block is not in main chain" );
1461+ }
1462+ } else {
1463+ pindex = chainActive.Tip ();
1464+ }
1465+ }
1466+
1467+ if (blockcount < 1 || blockcount >= pindex->nHeight ) {
1468+ throw JSONRPCError (RPC_INVALID_PARAMETER, " Invalid block count: should be between 1 and the block's height" );
1469+ }
1470+
1471+ const CBlockIndex* pindexPast = pindex->GetAncestor (pindex->nHeight - blockcount);
1472+ int nTimeDiff = pindex->GetMedianTimePast () - pindexPast->GetMedianTimePast ();
1473+ int nTxDiff = pindex->nChainTx - pindexPast->nChainTx ;
1474+
1475+ UniValue ret (UniValue::VOBJ);
1476+ ret.push_back (Pair (" time" , (int64_t )pindex->nTime ));
1477+ ret.push_back (Pair (" txcount" , (int64_t )pindex->nChainTx ));
1478+ ret.push_back (Pair (" txrate" , ((double )nTxDiff) / nTimeDiff));
1479+
1480+ return ret;
1481+ }
1482+
14181483static const CRPCCommand commands[] =
14191484{ // category name actor (function) okSafe argNames
14201485 // --------------------- ------------------------ ----------------------- ------ ----------
14211486 { " blockchain" , " getblockchaininfo" , &getblockchaininfo, true , {} },
1487+ { " blockchain" , " getchaintxstats" , &getchaintxstats, true , {" nblocks" , " blockhash" } },
14221488 { " blockchain" , " getbestblockhash" , &getbestblockhash, true , {} },
14231489 { " blockchain" , " getblockcount" , &getblockcount, true , {} },
14241490 { " blockchain" , " getblock" , &getblock, true , {" blockhash" ," verbose" } },
0 commit comments