aboutsummaryrefslogtreecommitdiff
path: root/src/rpc/blockchain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc/blockchain.cpp')
-rw-r--r--src/rpc/blockchain.cpp159
1 files changed, 107 insertions, 52 deletions
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 24e0405a84..8d01d8ba9c 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -24,6 +24,7 @@
#include "util.h"
#include "utilstrencodings.h"
#include "hash.h"
+#include "warnings.h"
#include <stdint.h>
@@ -77,6 +78,7 @@ double GetDifficulty(const CBlockIndex* blockindex)
UniValue blockheaderToJSON(const CBlockIndex* blockindex)
{
+ AssertLockHeld(cs_main);
UniValue result(UniValue::VOBJ);
result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
int confirmations = -1;
@@ -105,6 +107,7 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex)
UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails)
{
+ AssertLockHeld(cs_main);
UniValue result(UniValue::VOBJ);
result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
int confirmations = -1;
@@ -125,7 +128,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx
if(txDetails)
{
UniValue objTx(UniValue::VOBJ);
- TxToUniv(*tx, uint256(), objTx);
+ TxToUniv(*tx, uint256(), objTx, true, RPCSerializationFlags());
txs.push_back(objTx);
}
else
@@ -343,6 +346,7 @@ std::string EntryDescriptionString()
" \"ancestorcount\" : n, (numeric) number of in-mempool ancestor transactions (including this one)\n"
" \"ancestorsize\" : n, (numeric) virtual transaction size of in-mempool ancestors (including this one)\n"
" \"ancestorfees\" : n, (numeric) modified fees (see above) of in-mempool ancestors (including this one)\n"
+ " \"wtxid\" : hash, (string) hash of serialized transaction, including witness data\n"
" \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
" \"transactionid\", (string) parent transaction id\n"
" ... ]\n";
@@ -363,6 +367,7 @@ void entryToJSON(UniValue &info, const CTxMemPoolEntry &e)
info.push_back(Pair("ancestorcount", e.GetCountWithAncestors()));
info.push_back(Pair("ancestorsize", e.GetSizeWithAncestors()));
info.push_back(Pair("ancestorfees", e.GetModFeesWithAncestors()));
+ info.push_back(Pair("wtxid", mempool.vTxHashes[e.vTxHashesIdx].first.ToString()));
const CTransaction& tx = e.GetTx();
std::set<std::string> setDepends;
for (const CTxIn& txin : tx.vin)
@@ -812,6 +817,7 @@ static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash,
static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
{
std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
+ assert(pcursor);
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
stats.hashBlock = pcursor->GetBestBlock();
@@ -944,9 +950,10 @@ UniValue gettxout(const JSONRPCRequest& request)
"gettxout \"txid\" n ( include_mempool )\n"
"\nReturns details about an unspent transaction output.\n"
"\nArguments:\n"
- "1. \"txid\" (string, required) The transaction id\n"
- "2. n (numeric, required) vout number\n"
- "3. include_mempool (boolean, optional) Whether to include the mempool\n"
+ "1. \"txid\" (string, required) The transaction id\n"
+ "2. \"n\" (numeric, required) vout number\n"
+ "3. \"include_mempool\" (boolean, optional) Whether to include the mempool. Default: true."
+ " Note that an unspent output that is spent in the mempool won't appear.\n"
"\nResult:\n"
"{\n"
" \"bestblock\" : \"hash\", (string) the block hash\n"
@@ -1131,8 +1138,11 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
" \"mediantime\": xxxxxx, (numeric) median time for the current best block\n"
" \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
" \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
+ " \"size_on_disk\": xxxxxx, (numeric) the estimated size of the block and undo files on disk\n"
" \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
- " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n"
+ " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored (only present if pruning is enabled)\n"
+ " \"automatic_pruning\": xx, (boolean) whether automatic pruning is enabled (only present if pruning is enabled)\n"
+ " \"prune_target_size\": xxxxxx, (numeric) the target size used by pruning (only present if automatic pruning is enabled)\n"
" \"softforks\": [ (array) status of softforks in progress\n"
" {\n"
" \"id\": \"xxxx\", (string) name of softfork\n"
@@ -1158,6 +1168,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
" }\n"
" }\n"
" }\n"
+ " \"warnings\" : \"...\", (string) any network and blockchain warnings.\n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("getblockchaininfo", "")
@@ -1175,7 +1186,24 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast()));
obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip())));
obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
+ obj.push_back(Pair("size_on_disk", CalculateCurrentUsage()));
obj.push_back(Pair("pruned", fPruneMode));
+ if (fPruneMode) {
+ CBlockIndex* block = chainActive.Tip();
+ assert(block);
+ while (block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) {
+ block = block->pprev;
+ }
+
+ obj.push_back(Pair("pruneheight", block->nHeight));
+
+ // if 0, execution bypasses the whole if block.
+ bool automatic_pruning = (gArgs.GetArg("-prune", 0) != 1);
+ obj.push_back(Pair("automatic_pruning", automatic_pruning));
+ if (automatic_pruning) {
+ obj.push_back(Pair("prune_target_size", nPruneTarget));
+ }
+ }
const Consensus::Params& consensusParams = Params().GetConsensus();
CBlockIndex* tip = chainActive.Tip();
@@ -1189,14 +1217,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
obj.push_back(Pair("softforks", softforks));
obj.push_back(Pair("bip9_softforks", bip9_softforks));
- if (fPruneMode)
- {
- CBlockIndex *block = chainActive.Tip();
- while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
- block = block->pprev;
-
- obj.push_back(Pair("pruneheight", block->nHeight));
- }
+ obj.push_back(Pair("warnings", GetWarnings("statusbar")));
return obj;
}
@@ -1343,7 +1364,7 @@ UniValue getmempoolinfo(const JSONRPCRequest& request)
" \"bytes\": xxxxx, (numeric) Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted\n"
" \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n"
" \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n"
- " \"mempoolminfee\": xxxxx (numeric) Minimum feerate (" + CURRENCY_UNIT + " per KB) for tx to be accepted\n"
+ " \"mempoolminfee\": xxxxx (numeric) Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted\n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("getmempoolinfo", "")
@@ -1477,9 +1498,12 @@ UniValue getchaintxstats(const JSONRPCRequest& request)
"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"
+ " \"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", "")
@@ -1489,11 +1513,7 @@ UniValue getchaintxstats(const JSONRPCRequest& request)
const 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();
+ bool havehash = !request.params[1].isNull();
uint256 hash;
if (havehash) {
hash = uint256S(request.params[1].get_str());
@@ -1514,9 +1534,17 @@ UniValue getchaintxstats(const JSONRPCRequest& request)
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 < 1 || blockcount >= pindex->nHeight) {
- throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block count: should be between 1 and the block's height");
+ 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);
@@ -1526,41 +1554,68 @@ UniValue getchaintxstats(const JSONRPCRequest& request)
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));
+ 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;
}
+UniValue savemempool(const JSONRPCRequest& request)
+{
+ if (request.fHelp || request.params.size() != 0) {
+ throw std::runtime_error(
+ "savemempool\n"
+ "\nDumps the mempool to disk.\n"
+ "\nExamples:\n"
+ + HelpExampleCli("savemempool", "")
+ + HelpExampleRpc("savemempool", "")
+ );
+ }
+
+ if (!DumpMempool()) {
+ throw JSONRPCError(RPC_MISC_ERROR, "Unable to dump mempool to disk");
+ }
+
+ return NullUniValue;
+}
+
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","verbosity|verbose"} },
- { "blockchain", "getblockhash", &getblockhash, true, {"height"} },
- { "blockchain", "getblockheader", &getblockheader, true, {"blockhash","verbose"} },
- { "blockchain", "getchaintips", &getchaintips, true, {} },
- { "blockchain", "getdifficulty", &getdifficulty, true, {} },
- { "blockchain", "getmempoolancestors", &getmempoolancestors, true, {"txid","verbose"} },
- { "blockchain", "getmempooldescendants", &getmempooldescendants, true, {"txid","verbose"} },
- { "blockchain", "getmempoolentry", &getmempoolentry, true, {"txid"} },
- { "blockchain", "getmempoolinfo", &getmempoolinfo, true, {} },
- { "blockchain", "getrawmempool", &getrawmempool, true, {"verbose"} },
- { "blockchain", "gettxout", &gettxout, true, {"txid","n","include_mempool"} },
- { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, {} },
- { "blockchain", "pruneblockchain", &pruneblockchain, true, {"height"} },
- { "blockchain", "verifychain", &verifychain, true, {"checklevel","nblocks"} },
-
- { "blockchain", "preciousblock", &preciousblock, true, {"blockhash"} },
+{ // category name actor (function) argNames
+ // --------------------- ------------------------ ----------------------- ----------
+ { "blockchain", "getblockchaininfo", &getblockchaininfo, {} },
+ { "blockchain", "getchaintxstats", &getchaintxstats, {"nblocks", "blockhash"} },
+ { "blockchain", "getbestblockhash", &getbestblockhash, {} },
+ { "blockchain", "getblockcount", &getblockcount, {} },
+ { "blockchain", "getblock", &getblock, {"blockhash","verbosity|verbose"} },
+ { "blockchain", "getblockhash", &getblockhash, {"height"} },
+ { "blockchain", "getblockheader", &getblockheader, {"blockhash","verbose"} },
+ { "blockchain", "getchaintips", &getchaintips, {} },
+ { "blockchain", "getdifficulty", &getdifficulty, {} },
+ { "blockchain", "getmempoolancestors", &getmempoolancestors, {"txid","verbose"} },
+ { "blockchain", "getmempooldescendants", &getmempooldescendants, {"txid","verbose"} },
+ { "blockchain", "getmempoolentry", &getmempoolentry, {"txid"} },
+ { "blockchain", "getmempoolinfo", &getmempoolinfo, {} },
+ { "blockchain", "getrawmempool", &getrawmempool, {"verbose"} },
+ { "blockchain", "gettxout", &gettxout, {"txid","n","include_mempool"} },
+ { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, {} },
+ { "blockchain", "pruneblockchain", &pruneblockchain, {"height"} },
+ { "blockchain", "savemempool", &savemempool, {} },
+ { "blockchain", "verifychain", &verifychain, {"checklevel","nblocks"} },
+
+ { "blockchain", "preciousblock", &preciousblock, {"blockhash"} },
/* Not shown in help */
- { "hidden", "invalidateblock", &invalidateblock, true, {"blockhash"} },
- { "hidden", "reconsiderblock", &reconsiderblock, true, {"blockhash"} },
- { "hidden", "waitfornewblock", &waitfornewblock, true, {"timeout"} },
- { "hidden", "waitforblock", &waitforblock, true, {"blockhash","timeout"} },
- { "hidden", "waitforblockheight", &waitforblockheight, true, {"height","timeout"} },
+ { "hidden", "invalidateblock", &invalidateblock, {"blockhash"} },
+ { "hidden", "reconsiderblock", &reconsiderblock, {"blockhash"} },
+ { "hidden", "waitfornewblock", &waitfornewblock, {"timeout"} },
+ { "hidden", "waitforblock", &waitforblock, {"blockhash","timeout"} },
+ { "hidden", "waitforblockheight", &waitforblockheight, {"height","timeout"} },
};
void RegisterBlockchainRPCCommands(CRPCTable &t)