| 1818 | } |
| 1819 | |
| 1820 | static RPCMethod getchaintxstats() |
| 1821 | { |
| 1822 | return RPCMethod{ |
| 1823 | "getchaintxstats", |
| 1824 | "Compute statistics about the total number and rate of transactions in the chain.\n", |
| 1825 | { |
| 1826 | {"nblocks", RPCArg::Type::NUM, RPCArg::DefaultHint{"one month"}, "Size of the window in number of blocks"}, |
| 1827 | {"blockhash", RPCArg::Type::STR_HEX, RPCArg::DefaultHint{"chain tip"}, "The hash of the block that ends the window."}, |
| 1828 | }, |
| 1829 | RPCResult{ |
| 1830 | RPCResult::Type::OBJ, "", "", |
| 1831 | { |
| 1832 | {RPCResult::Type::NUM_TIME, "time", "The timestamp for the final block in the window, expressed in " + UNIX_EPOCH_TIME}, |
| 1833 | {RPCResult::Type::NUM, "txcount", /*optional=*/true, |
| 1834 | "The total number of transactions in the chain up to that point, if known. " |
| 1835 | "It may be unknown when using assumeutxo."}, |
| 1836 | {RPCResult::Type::STR_HEX, "window_final_block_hash", "The hash of the final block in the window"}, |
| 1837 | {RPCResult::Type::NUM, "window_final_block_height", "The height of the final block in the window."}, |
| 1838 | {RPCResult::Type::NUM, "window_block_count", "Size of the window in number of blocks"}, |
| 1839 | {RPCResult::Type::NUM, "window_interval", /*optional=*/true, "The elapsed time in the window in seconds. Only returned if \"window_block_count\" is > 0"}, |
| 1840 | {RPCResult::Type::NUM, "window_tx_count", /*optional=*/true, |
| 1841 | "The number of transactions in the window. " |
| 1842 | "Only returned if \"window_block_count\" is > 0 and if txcount exists for the start and end of the window."}, |
| 1843 | {RPCResult::Type::NUM, "txrate", /*optional=*/true, |
| 1844 | "The average rate of transactions per second in the window. " |
| 1845 | "Only returned if \"window_interval\" is > 0 and if window_tx_count exists."}, |
| 1846 | }}, |
| 1847 | RPCExamples{ |
| 1848 | HelpExampleCli("getchaintxstats", "") |
| 1849 | + HelpExampleRpc("getchaintxstats", "2016") |
| 1850 | }, |
| 1851 | [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue |
| 1852 | { |
| 1853 | ChainstateManager& chainman = EnsureAnyChainman(request.context); |
| 1854 | const CBlockIndex* pindex; |
| 1855 | int blockcount = 30 * 24 * 60 * 60 / chainman.GetParams().GetConsensus().nPowTargetSpacing; // By default: 1 month |
| 1856 | |
| 1857 | if (request.params[1].isNull()) { |
| 1858 | LOCK(cs_main); |
| 1859 | pindex = chainman.ActiveChain().Tip(); |
| 1860 | } else { |
| 1861 | uint256 hash(ParseHashV(request.params[1], "blockhash")); |
| 1862 | LOCK(cs_main); |
| 1863 | pindex = chainman.m_blockman.LookupBlockIndex(hash); |
| 1864 | if (!pindex) { |
| 1865 | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); |
| 1866 | } |
| 1867 | if (!chainman.ActiveChain().Contains(*pindex)) { |
| 1868 | throw JSONRPCError(RPC_INVALID_PARAMETER, "Block is not in main chain"); |
| 1869 | } |
| 1870 | } |
| 1871 | |
| 1872 | CHECK_NONFATAL(pindex != nullptr); |
| 1873 | |
| 1874 | if (request.params[0].isNull()) { |
| 1875 | blockcount = std::max(0, std::min(blockcount, pindex->nHeight - 1)); |
| 1876 | } else { |
| 1877 | blockcount = request.params[0].getInt<int>(); |
nothing calls this directly
no test coverage detected