Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/blockchain.cpp
Show First 20 Lines • Show All 148 Lines • ▼ Show 20 Lines | if (pnext) { | ||||
result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex()); | result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex()); | ||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
static UniValue getblockcount(const Config &config, | static UniValue getblockcount(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 0) { | if (request.fHelp || request.params.size() != 0) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"getblockcount", | "getblockcount", | ||||
"\nReturns the number of blocks in the longest blockchain.\n", | "\nReturns the number of blocks in the longest blockchain.\n", | ||||
{}} | {}, | ||||
.ToString() + | RPCResult{"n (numeric) The current block count\n"}, | ||||
"\nResult:\n" | RPCExamples{HelpExampleCli("getblockcount", "") + | ||||
"n (numeric) The current block count\n" | HelpExampleRpc("getblockcount", "")}, | ||||
"\nExamples:\n" + | } | ||||
HelpExampleCli("getblockcount", "") + | .ToString()); | ||||
HelpExampleRpc("getblockcount", "")); | |||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
return ::ChainActive().Height(); | return ::ChainActive().Height(); | ||||
} | } | ||||
static UniValue getbestblockhash(const Config &config, | static UniValue getbestblockhash(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 0) { | if (request.fHelp || request.params.size() != 0) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"getbestblockhash", | "getbestblockhash", | ||||
"\nReturns the hash of the best (tip) block in the " | "\nReturns the hash of the best (tip) block in the " | ||||
"longest blockchain.\n", | "longest blockchain.\n", | ||||
{}} | {}, | ||||
.ToString() + | RPCResult{"\"hex\" (string) the block hash, hex-encoded\n"}, | ||||
"\nResult:\n" | RPCExamples{HelpExampleCli("getbestblockhash", "") + | ||||
"\"hex\" (string) the block hash hex-encoded\n" | HelpExampleRpc("getbestblockhash", "")}, | ||||
"\nExamples:\n" + | } | ||||
HelpExampleCli("getbestblockhash", "") + | .ToString()); | ||||
HelpExampleRpc("getbestblockhash", "")); | |||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
return ::ChainActive().Tip()->GetBlockHash().GetHex(); | return ::ChainActive().Tip()->GetBlockHash().GetHex(); | ||||
} | } | ||||
UniValue getfinalizedblockhash(const Config &config, | UniValue getfinalizedblockhash(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 0) { | if (request.fHelp || request.params.size() != 0) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"getfinalizedblockhash", | "getfinalizedblockhash", | ||||
"\nReturns the hash of the currently finalized block\n", | "\nReturns the hash of the currently finalized block\n", | ||||
{}} | {}, | ||||
.ToString() + | RPCResult{"\"hex\" (string) the block hash hex-encoded\n"}, | ||||
"\nResult:\n" | RPCExamples{HelpExampleCli("getfinalizedblockhash", "") + | ||||
"\"hex\" (string) the block hash hex-encoded\n"); | HelpExampleRpc("getfinalizedblockhash", "")}, | ||||
} | |||||
.ToString()); | |||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
const CBlockIndex *blockIndexFinalized = GetFinalizedBlock(); | const CBlockIndex *blockIndexFinalized = GetFinalizedBlock(); | ||||
if (blockIndexFinalized) { | if (blockIndexFinalized) { | ||||
return blockIndexFinalized->GetBlockHash().GetHex(); | return blockIndexFinalized->GetBlockHash().GetHex(); | ||||
} | } | ||||
return UniValue(UniValue::VSTR); | return UniValue(UniValue::VSTR); | ||||
} | } | ||||
void RPCNotifyBlockChange(bool ibd, const CBlockIndex *pindex) { | void RPCNotifyBlockChange(bool ibd, const CBlockIndex *pindex) { | ||||
if (pindex) { | if (pindex) { | ||||
std::lock_guard<std::mutex> lock(cs_blockchange); | std::lock_guard<std::mutex> lock(cs_blockchange); | ||||
latestblock.hash = pindex->GetBlockHash(); | latestblock.hash = pindex->GetBlockHash(); | ||||
latestblock.height = pindex->nHeight; | latestblock.height = pindex->nHeight; | ||||
} | } | ||||
cond_blockchange.notify_all(); | cond_blockchange.notify_all(); | ||||
} | } | ||||
static UniValue waitfornewblock(const Config &config, | static UniValue waitfornewblock(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() > 1) { | if (request.fHelp || request.params.size() > 1) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"waitfornewblock", | "waitfornewblock", | ||||
"\nWaits for a specific new block and returns useful " | "\nWaits for a specific new block and returns useful " | ||||
"info about it.\n" | "info about it.\n" | ||||
"\nReturns the current block on timeout or exit.\n", | "\nReturns the current block on timeout or exit.\n", | ||||
{ | { | ||||
{"timeout", RPCArg::Type::NUM, /* opt */ true, | {"timeout", RPCArg::Type::NUM, /* opt */ true, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"Time in milliseconds to wait for a response. 0 " | "Time in milliseconds to wait for a response. 0 " | ||||
"indicates no timeout."}, | "indicates no timeout."}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{"{ (json object)\n" | ||||
"\nResult:\n" | |||||
"{ (json object)\n" | |||||
" \"hash\" : { (string) The blockhash\n" | " \"hash\" : { (string) The blockhash\n" | ||||
" \"height\" : { (int) Block height\n" | " \"height\" : { (int) Block height\n" | ||||
"}\n" | "}\n"}, | ||||
"\nExamples:\n" + | RPCExamples{HelpExampleCli("waitfornewblock", "1000") + | ||||
HelpExampleCli("waitfornewblock", "1000") + | HelpExampleRpc("waitfornewblock", "1000")}, | ||||
HelpExampleRpc("waitfornewblock", "1000")); | } | ||||
.ToString()); | |||||
} | } | ||||
int timeout = 0; | int timeout = 0; | ||||
if (!request.params[0].isNull()) { | if (!request.params[0].isNull()) { | ||||
timeout = request.params[0].get_int(); | timeout = request.params[0].get_int(); | ||||
} | } | ||||
CUpdatedBlock block; | CUpdatedBlock block; | ||||
{ | { | ||||
WAIT_LOCK(cs_blockchange, lock); | WAIT_LOCK(cs_blockchange, lock); | ||||
Show All 17 Lines | static UniValue waitfornewblock(const Config &config, | ||||
ret.pushKV("height", block.height); | ret.pushKV("height", block.height); | ||||
return ret; | return ret; | ||||
} | } | ||||
static UniValue waitforblock(const Config &config, | static UniValue waitforblock(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() < 1 || | if (request.fHelp || request.params.size() < 1 || | ||||
request.params.size() > 2) { | request.params.size() > 2) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"waitforblock", | "waitforblock", | ||||
"\nWaits for a specific new block and returns useful " | "\nWaits for a specific new block and returns useful " | ||||
"info about it.\n" | "info about it.\n" | ||||
"\nReturns the current block on timeout or exit.\n", | "\nReturns the current block on timeout or exit.\n", | ||||
{ | { | ||||
{"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | {"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | ||||
/* default_val */ "", "Block hash to wait for."}, | /* default_val */ "", "Block hash to wait for."}, | ||||
{"timeout", RPCArg::Type::NUM, /* opt */ true, | {"timeout", RPCArg::Type::NUM, /* opt */ true, | ||||
/* default_val */ "0", | /* default_val */ "0", | ||||
"Time in milliseconds to wait for a response. 0 " | "Time in milliseconds to wait for a response. 0 " | ||||
"indicates no timeout."}, | "indicates no timeout."}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{"{ (json object)\n" | ||||
"\nResult:\n" | |||||
"{ (json object)\n" | |||||
" \"hash\" : { (string) The blockhash\n" | " \"hash\" : { (string) The blockhash\n" | ||||
" \"height\" : { (int) Block height\n" | " \"height\" : { (int) Block height\n" | ||||
"}\n" | "}\n"}, | ||||
"\nExamples:\n" + | RPCExamples{HelpExampleCli("waitforblock", | ||||
HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4" | "\"0000000000079f8ef3d2c688c244eb7a4" | ||||
"570b24c9ed7b4a8c619eb02596f8862\", " | "570b24c9ed7b4a8c619eb02596f8862\", " | ||||
"1000") + | "1000") + | ||||
HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4" | HelpExampleRpc("waitforblock", | ||||
"\"0000000000079f8ef3d2c688c244eb7a4" | |||||
"570b24c9ed7b4a8c619eb02596f8862\", " | "570b24c9ed7b4a8c619eb02596f8862\", " | ||||
"1000")); | "1000")}, | ||||
} | |||||
.ToString()); | |||||
} | } | ||||
int timeout = 0; | int timeout = 0; | ||||
BlockHash hash(ParseHashV(request.params[0], "blockhash")); | BlockHash hash(ParseHashV(request.params[0], "blockhash")); | ||||
if (!request.params[1].isNull()) { | if (!request.params[1].isNull()) { | ||||
timeout = request.params[1].get_int(); | timeout = request.params[1].get_int(); | ||||
Show All 20 Lines | static UniValue waitforblock(const Config &config, | ||||
ret.pushKV("height", block.height); | ret.pushKV("height", block.height); | ||||
return ret; | return ret; | ||||
} | } | ||||
static UniValue waitforblockheight(const Config &config, | static UniValue waitforblockheight(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() < 1 || | if (request.fHelp || request.params.size() < 1 || | ||||
request.params.size() > 2) { | request.params.size() > 2) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"waitforblockheight", | "waitforblockheight", | ||||
"\nWaits for (at least) block height and returns the " | "\nWaits for (at least) block height and returns the " | ||||
"height and hash\nof the current tip.\n" | "height and hash\nof the current tip.\n" | ||||
"\nReturns the current block on timeout or exit.\n", | "\nReturns the current block on timeout or exit.\n", | ||||
{ | { | ||||
{"height", RPCArg::Type::NUM, /* opt */ false, | {"height", RPCArg::Type::NUM, /* opt */ false, | ||||
/* default_val */ "", "Block height to wait for."}, | /* default_val */ "", "Block height to wait for."}, | ||||
{"timeout", RPCArg::Type::NUM, /* opt */ true, | {"timeout", RPCArg::Type::NUM, /* opt */ true, | ||||
/* default_val */ "0", | /* default_val */ "0", | ||||
"Time in milliseconds to wait for a response. 0 " | "Time in milliseconds to wait for a response. 0 " | ||||
"indicates no timeout."}, | "indicates no timeout."}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{"{ (json object)\n" | ||||
"\nResult:\n" | |||||
"{ (json object)\n" | |||||
" \"hash\" : { (string) The blockhash\n" | " \"hash\" : { (string) The blockhash\n" | ||||
" \"height\" : { (int) Block height\n" | " \"height\" : { (int) Block height\n" | ||||
"}\n" | "}\n"}, | ||||
"\nExamples:\n" + | RPCExamples{HelpExampleCli("waitforblockheight", "\"100\", 1000") + | ||||
HelpExampleCli("waitforblockheight", "\"100\", 1000") + | HelpExampleRpc("waitforblockheight", "\"100\", 1000")}, | ||||
HelpExampleRpc("waitforblockheight", "\"100\", 1000")); | } | ||||
.ToString()); | |||||
} | } | ||||
int timeout = 0; | int timeout = 0; | ||||
int height = request.params[0].get_int(); | int height = request.params[0].get_int(); | ||||
if (!request.params[1].isNull()) { | if (!request.params[1].isNull()) { | ||||
timeout = request.params[1].get_int(); | timeout = request.params[1].get_int(); | ||||
Show All 19 Lines | static UniValue waitforblockheight(const Config &config, | ||||
ret.pushKV("height", block.height); | ret.pushKV("height", block.height); | ||||
return ret; | return ret; | ||||
} | } | ||||
static UniValue | static UniValue | ||||
syncwithvalidationinterfacequeue(const Config &config, | syncwithvalidationinterfacequeue(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() > 0) { | if (request.fHelp || request.params.size() > 0) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"syncwithvalidationinterfacequeue", | "syncwithvalidationinterfacequeue", | ||||
"\nWaits for the validation interface queue to catch up on " | "\nWaits for the validation interface queue to catch up on " | ||||
"everything that was there when we entered this function.\n", | "everything that was there when we entered this function.\n", | ||||
{}} | {}, | ||||
.ToString() + | RPCResults{}, | ||||
"\nExamples:\n" + | RPCExamples{HelpExampleCli("syncwithvalidationinterfacequeue", "") + | ||||
HelpExampleCli("syncwithvalidationinterfacequeue", "") + | HelpExampleRpc("syncwithvalidationinterfacequeue", "")}, | ||||
HelpExampleRpc("syncwithvalidationinterfacequeue", "")); | } | ||||
.ToString()); | |||||
} | } | ||||
SyncWithValidationInterfaceQueue(); | SyncWithValidationInterfaceQueue(); | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
static UniValue getdifficulty(const Config &config, | static UniValue getdifficulty(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 0) { | if (request.fHelp || request.params.size() != 0) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"getdifficulty", | "getdifficulty", | ||||
"\nReturns the proof-of-work difficulty as a " | "\nReturns the proof-of-work difficulty as a multiple of the " | ||||
"multiple of the minimum difficulty.\n", | "minimum difficulty.\n", | ||||
{}} | {}, | ||||
.ToString() + | RPCResult{"n.nnn (numeric) the proof-of-work difficulty as a " | ||||
"\nResult:\n" | "multiple of the minimum difficulty.\n"}, | ||||
"n.nnn (numeric) the proof-of-work " | RPCExamples{HelpExampleCli("getdifficulty", "") + | ||||
"difficulty as a multiple of the minimum " | HelpExampleRpc("getdifficulty", "")}, | ||||
"difficulty.\n" | } | ||||
"\nExamples:\n" + | .ToString()); | ||||
HelpExampleCli("getdifficulty", "") + | |||||
HelpExampleRpc("getdifficulty", "")); | |||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
return GetDifficulty(::ChainActive().Tip()); | return GetDifficulty(::ChainActive().Tip()); | ||||
} | } | ||||
static std::string EntryDescriptionString() { | static std::string EntryDescriptionString() { | ||||
return " \"size\" : n, (numeric) transaction size.\n" | return " \"size\" : n, (numeric) transaction size.\n" | ||||
▲ Show 20 Lines • Show All 115 Lines • ▼ Show 20 Lines | if (verbose) { | ||||
return a; | return a; | ||||
} | } | ||||
} | } | ||||
static UniValue getrawmempool(const Config &config, | static UniValue getrawmempool(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() > 1) { | if (request.fHelp || request.params.size() > 1) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"getrawmempool", | "getrawmempool", | ||||
"\nReturns all transaction ids in memory pool as a json " | "\nReturns all transaction ids in memory pool as a json " | ||||
"array of string transaction ids.\n" | "array of string transaction ids.\n" | ||||
"\nHint: use getmempoolentry to fetch a specific " | "\nHint: use getmempoolentry to fetch a specific " | ||||
"transaction from the mempool.\n", | "transaction from the mempool.\n", | ||||
{ | { | ||||
{"verbose", RPCArg::Type::BOOL, /* opt */ true, | {"verbose", RPCArg::Type::BOOL, /* opt */ true, | ||||
/* default_val */ "false", | /* default_val */ "false", | ||||
"True for a json object, false for array of " | "True for a json object, false for array of " | ||||
"transaction ids"}, | "transaction ids"}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{"for verbose = false", | ||||
"\nResult: (for verbose = false):\n" | |||||
"[ (json array of string)\n" | "[ (json array of string)\n" | ||||
" \"transactionid\" (string) The transaction id\n" | " \"transactionid\" (string) The transaction id\n" | ||||
" ,...\n" | " ,...\n" | ||||
"]\n" | "]\n" | ||||
"\nResult: (for verbose = true):\n" | "\nResult: (for verbose = true):\n" | ||||
"{ (json object)\n" | "{ (json object)\n" | ||||
" \"transactionid\" : { (json object)\n" + | " \"transactionid\" : { (json object)\n" + | ||||
EntryDescriptionString() + | EntryDescriptionString() + | ||||
" }, ...\n" | " }, ...\n" | ||||
"}\n" | "}\n"}, | ||||
"\nExamples:\n" + | RPCExamples{HelpExampleCli("getrawmempool", "true") + | ||||
HelpExampleCli("getrawmempool", "true") + | HelpExampleRpc("getrawmempool", "true")}, | ||||
HelpExampleRpc("getrawmempool", "true")); | } | ||||
.ToString()); | |||||
} | } | ||||
bool fVerbose = false; | bool fVerbose = false; | ||||
if (!request.params[0].isNull()) { | if (!request.params[0].isNull()) { | ||||
fVerbose = request.params[0].get_bool(); | fVerbose = request.params[0].get_bool(); | ||||
} | } | ||||
return MempoolToJSON(::g_mempool, fVerbose); | return MempoolToJSON(::g_mempool, fVerbose); | ||||
} | } | ||||
static UniValue getmempoolancestors(const Config &config, | static UniValue getmempoolancestors(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() < 1 || | if (request.fHelp || request.params.size() < 1 || | ||||
request.params.size() > 2) { | request.params.size() > 2) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"getmempoolancestors", | "getmempoolancestors", | ||||
"\nIf txid is in the mempool, returns all in-mempool " | "\nIf txid is in the mempool, returns all in-mempool " | ||||
"ancestors.\n", | "ancestors.\n", | ||||
{ | { | ||||
{"txid", RPCArg::Type::STR_HEX, /* opt */ false, | {"txid", RPCArg::Type::STR_HEX, /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"The transaction id (must be in mempool)"}, | "The transaction id (must be in mempool)"}, | ||||
{"verbose", RPCArg::Type::BOOL, /* opt */ true, | {"verbose", RPCArg::Type::BOOL, /* opt */ true, | ||||
/* default_val */ "false", | /* default_val */ "false", | ||||
"True for a json object, false for array of " | "True for a json object, false for array of " | ||||
"transaction ids"}, | "transaction ids"}, | ||||
}} | }, | ||||
.ToString() + | { | ||||
"\nResult (for verbose = false):\n" | RPCResult{"for verbose = false", | ||||
"[ (json array of strings)\n" | "[ (json array of strings)\n" | ||||
" \"transactionid\" (string) The transaction id of an " | " \"transactionid\" (string) The " | ||||
"transaction id of an " | |||||
"in-mempool ancestor transaction\n" | "in-mempool ancestor transaction\n" | ||||
" ,...\n" | " ,...\n" | ||||
"]\n" | "]\n"}, | ||||
"\nResult (for verbose = true):\n" | RPCResult{"for verbose = true", | ||||
"{ (json object)\n" | "{ (json object)\n" | ||||
" \"transactionid\" : { (json object)\n" + | " \"transactionid\" : { (json object)\n" + | ||||
EntryDescriptionString() + | EntryDescriptionString() + | ||||
" }, ...\n" | " }, ...\n" | ||||
"}\n" | "}\n"}, | ||||
"\nExamples:\n" + | }, | ||||
HelpExampleCli("getmempoolancestors", "\"mytxid\"") + | RPCExamples{HelpExampleCli("getmempoolancestors", "\"mytxid\"") + | ||||
HelpExampleRpc("getmempoolancestors", "\"mytxid\"")); | HelpExampleRpc("getmempoolancestors", "\"mytxid\"")}, | ||||
} | |||||
.ToString()); | |||||
} | } | ||||
bool fVerbose = false; | bool fVerbose = false; | ||||
if (!request.params[1].isNull()) { | if (!request.params[1].isNull()) { | ||||
fVerbose = request.params[1].get_bool(); | fVerbose = request.params[1].get_bool(); | ||||
} | } | ||||
TxId txid(ParseHashV(request.params[0], "parameter 1")); | TxId txid(ParseHashV(request.params[0], "parameter 1")); | ||||
Show All 31 Lines | if (!fVerbose) { | ||||
return o; | return o; | ||||
} | } | ||||
} | } | ||||
static UniValue getmempooldescendants(const Config &config, | static UniValue getmempooldescendants(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() < 1 || | if (request.fHelp || request.params.size() < 1 || | ||||
request.params.size() > 2) { | request.params.size() > 2) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"getmempooldescendants", | "getmempooldescendants", | ||||
"\nIf txid is in the mempool, returns all in-mempool " | "\nIf txid is in the mempool, returns all in-mempool " | ||||
"descendants.\n", | "descendants.\n", | ||||
{ | { | ||||
{"txid", RPCArg::Type::STR_HEX, /* opt */ false, | {"txid", RPCArg::Type::STR_HEX, /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"The transaction id (must be in mempool)"}, | "The transaction id (must be in mempool)"}, | ||||
{"verbose", RPCArg::Type::BOOL, /* opt */ true, | {"verbose", RPCArg::Type::BOOL, /* opt */ true, | ||||
/* default_val */ "false", | /* default_val */ "false", | ||||
"True for a json object, false for array of " | "True for a json object, false for array of " | ||||
"transaction ids"}, | "transaction ids"}, | ||||
}} | }, | ||||
.ToString() + | { | ||||
"\nResult (for verbose = false):\n" | RPCResult{"for verbose = false", | ||||
"[ (json array of strings)\n" | "[ (json array of strings)\n" | ||||
" \"transactionid\" (string) The transaction id of an " | " \"transactionid\" (string) The " | ||||
"transaction id of an " | |||||
"in-mempool descendant transaction\n" | "in-mempool descendant transaction\n" | ||||
" ,...\n" | " ,...\n" | ||||
"]\n" | "]\n"}, | ||||
"\nResult (for verbose = true):\n" | RPCResult{"for verbose = true", | ||||
"{ (json object)\n" | "{ (json object)\n" | ||||
" \"transactionid\" : { (json object)\n" + | " \"transactionid\" : { (json object)\n" + | ||||
EntryDescriptionString() + | EntryDescriptionString() + | ||||
" }, ...\n" | " }, ...\n" | ||||
"}\n" | "}\n"}, | ||||
"\nExamples:\n" + | }, | ||||
HelpExampleCli("getmempooldescendants", "\"mytxid\"") + | RPCExamples{HelpExampleCli("getmempooldescendants", "\"mytxid\"") + | ||||
HelpExampleRpc("getmempooldescendants", "\"mytxid\"")); | HelpExampleRpc("getmempooldescendants", "\"mytxid\"")}, | ||||
} | |||||
.ToString()); | |||||
} | } | ||||
bool fVerbose = false; | bool fVerbose = false; | ||||
if (!request.params[1].isNull()) { | if (!request.params[1].isNull()) { | ||||
fVerbose = request.params[1].get_bool(); | fVerbose = request.params[1].get_bool(); | ||||
} | } | ||||
TxId txid(ParseHashV(request.params[0], "parameter 1")); | TxId txid(ParseHashV(request.params[0], "parameter 1")); | ||||
Show All 29 Lines | if (!fVerbose) { | ||||
} | } | ||||
return o; | return o; | ||||
} | } | ||||
} | } | ||||
static UniValue getmempoolentry(const Config &config, | static UniValue getmempoolentry(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 1) { | if (request.fHelp || request.params.size() != 1) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"getmempoolentry", | "getmempoolentry", | ||||
"\nReturns mempool data for given transaction\n", | "\nReturns mempool data for given transaction\n", | ||||
{ | { | ||||
{"txid", RPCArg::Type::STR_HEX, /* opt */ false, | {"txid", RPCArg::Type::STR_HEX, /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"The transaction id (must be in mempool)"}, | "The transaction id (must be in mempool)"}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{"{ (json object)\n" + | ||||
"\nResult:\n" | EntryDescriptionString() + "}\n"}, | ||||
"{ (json object)\n" + | RPCExamples{HelpExampleCli("getmempoolentry", "\"mytxid\"") + | ||||
EntryDescriptionString() + | HelpExampleRpc("getmempoolentry", "\"mytxid\"")}, | ||||
"}\n" | } | ||||
"\nExamples:\n" + | .ToString()); | ||||
HelpExampleCli("getmempoolentry", "\"mytxid\"") + | |||||
HelpExampleRpc("getmempoolentry", "\"mytxid\"")); | |||||
} | } | ||||
TxId txid(ParseHashV(request.params[0], "parameter 1")); | TxId txid(ParseHashV(request.params[0], "parameter 1")); | ||||
LOCK(g_mempool.cs); | LOCK(g_mempool.cs); | ||||
CTxMemPool::txiter it = g_mempool.mapTx.find(txid); | CTxMemPool::txiter it = g_mempool.mapTx.find(txid); | ||||
if (it == g_mempool.mapTx.end()) { | if (it == g_mempool.mapTx.end()) { | ||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | ||||
"Transaction not in mempool"); | "Transaction not in mempool"); | ||||
} | } | ||||
const CTxMemPoolEntry &e = *it; | const CTxMemPoolEntry &e = *it; | ||||
UniValue info(UniValue::VOBJ); | UniValue info(UniValue::VOBJ); | ||||
entryToJSON(::g_mempool, info, e); | entryToJSON(::g_mempool, info, e); | ||||
return info; | return info; | ||||
} | } | ||||
static UniValue getblockhash(const Config &config, | static UniValue getblockhash(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 1) { | if (request.fHelp || request.params.size() != 1) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"getblockhash", | "getblockhash", | ||||
"\nReturns hash of block in best-block-chain at height " | "\nReturns hash of block in best-block-chain at height " | ||||
"provided.\n", | "provided.\n", | ||||
{ | { | ||||
{"height", RPCArg::Type::NUM, /* opt */ false, | {"height", RPCArg::Type::NUM, /* opt */ false, | ||||
/* default_val */ "", "The height index"}, | /* default_val */ "", "The height index"}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{"\"hash\" (string) The block hash\n"}, | ||||
"\nResult:\n" | RPCExamples{HelpExampleCli("getblockhash", "1000") + | ||||
"\"hash\" (string) The block hash\n" | HelpExampleRpc("getblockhash", "1000")}, | ||||
"\nExamples:\n" + | } | ||||
HelpExampleCli("getblockhash", "1000") + | .ToString()); | ||||
HelpExampleRpc("getblockhash", "1000")); | |||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
int nHeight = request.params[0].get_int(); | int nHeight = request.params[0].get_int(); | ||||
if (nHeight < 0 || nHeight > ::ChainActive().Height()) { | if (nHeight < 0 || nHeight > ::ChainActive().Height()) { | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); | throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); | ||||
} | } | ||||
CBlockIndex *pblockindex = ::ChainActive()[nHeight]; | CBlockIndex *pblockindex = ::ChainActive()[nHeight]; | ||||
return pblockindex->GetBlockHash().GetHex(); | return pblockindex->GetBlockHash().GetHex(); | ||||
} | } | ||||
static UniValue getblockheader(const Config &config, | static UniValue getblockheader(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() < 1 || | if (request.fHelp || request.params.size() < 1 || | ||||
request.params.size() > 2) { | request.params.size() > 2) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"getblockheader", | "getblockheader", | ||||
"\nIf verbose is false, returns a string that is " | "\nIf verbose is false, returns a string that is " | ||||
"serialized, hex-encoded data for blockheader 'hash'.\n" | "serialized, hex-encoded data for blockheader 'hash'.\n" | ||||
"If verbose is true, returns an Object with information " | "If verbose is true, returns an Object with information " | ||||
"about blockheader <hash>.\n", | "about blockheader <hash>.\n", | ||||
{ | { | ||||
{"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | {"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | ||||
/* default_val */ "", "The block hash"}, | /* default_val */ "", "The block hash"}, | ||||
{"verbose", RPCArg::Type::BOOL, /* opt */ true, | {"verbose", RPCArg::Type::BOOL, /* opt */ true, | ||||
/* default_val */ "true", | /* default_val */ "true", | ||||
"true for a json object, false for the hex-encoded data"}, | "true for a json object, false for the hex-encoded data"}, | ||||
}} | }, | ||||
.ToString() + | { | ||||
"\nResult (for verbose = true):\n" | RPCResult{ | ||||
"for verbose = true", | |||||
"{\n" | "{\n" | ||||
" \"hash\" : \"hash\", (string) the block hash (same as " | " \"hash\" : \"hash\", (string) the block hash (same " | ||||
"as " | |||||
"provided)\n" | "provided)\n" | ||||
" \"confirmations\" : n, (numeric) The number of confirmations, " | " \"confirmations\" : n, (numeric) The number of " | ||||
"confirmations, " | |||||
"or -1 if the block is not on the main chain\n" | "or -1 if the block is not on the main chain\n" | ||||
" \"height\" : n, (numeric) The block height or index\n" | " \"height\" : n, (numeric) The block height or " | ||||
"index\n" | |||||
" \"version\" : n, (numeric) The block version\n" | " \"version\" : n, (numeric) The block version\n" | ||||
" \"versionHex\" : \"00000000\", (string) The block version " | " \"versionHex\" : \"00000000\", (string) The block " | ||||
"version " | |||||
"formatted in hexadecimal\n" | "formatted in hexadecimal\n" | ||||
" \"merkleroot\" : \"xxxx\", (string) The merkle root\n" | " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" | ||||
" \"time\" : ttt, (numeric) The block time in seconds " | " \"time\" : ttt, (numeric) The block time in " | ||||
"seconds " | |||||
"since epoch (Jan 1 1970 GMT)\n" | "since epoch (Jan 1 1970 GMT)\n" | ||||
" \"mediantime\" : ttt, (numeric) The median block time in " | " \"mediantime\" : ttt, (numeric) The median block " | ||||
"time in " | |||||
"seconds since epoch (Jan 1 1970 GMT)\n" | "seconds since epoch (Jan 1 1970 GMT)\n" | ||||
" \"nonce\" : n, (numeric) The nonce\n" | " \"nonce\" : n, (numeric) The nonce\n" | ||||
" \"bits\" : \"1d00ffff\", (string) The bits\n" | " \"bits\" : \"1d00ffff\", (string) The bits\n" | ||||
" \"difficulty\" : x.xxx, (numeric) The difficulty\n" | " \"difficulty\" : x.xxx, (numeric) The difficulty\n" | ||||
" \"chainwork\" : \"0000...1f3\" (string) Expected number of " | " \"chainwork\" : \"0000...1f3\" (string) Expected " | ||||
"number of " | |||||
"hashes required to produce the current chain (in hex)\n" | "hashes required to produce the current chain (in hex)\n" | ||||
" \"nTx\" : n, (numeric) The number of transactions " | " \"nTx\" : n, (numeric) The number of " | ||||
"transactions " | |||||
"in the block.\n" | "in the block.\n" | ||||
" \"previousblockhash\" : \"hash\", (string) The hash of the " | " \"previousblockhash\" : \"hash\", (string) The hash of " | ||||
"the " | |||||
"previous block\n" | "previous block\n" | ||||
" \"nextblockhash\" : \"hash\", (string) The hash of the " | " \"nextblockhash\" : \"hash\", (string) The hash of " | ||||
"the " | |||||
"next block\n" | "next block\n" | ||||
"}\n" | "}\n"}, | ||||
"\nResult (for verbose=false):\n" | RPCResult{"for verbose=false):\n" | ||||
"\"data\" (string) A string that is serialized, " | "\"data\" (string) A string that is " | ||||
"hex-encoded data for block 'hash'.\n" | "serialized, " | ||||
"\nExamples:\n" + | "hex-encoded data for block 'hash'.\n"}, | ||||
HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec3" | }, | ||||
RPCExamples{HelpExampleCli("getblockheader", | |||||
"\"00000000c937983704a73af28acdec3" | |||||
"7b049d214adbda81d7e2a3dd146f6ed09" | "7b049d214adbda81d7e2a3dd146f6ed09" | ||||
"\"") + | "\"") + | ||||
HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec3" | HelpExampleRpc("getblockheader", | ||||
"\"00000000c937983704a73af28acdec3" | |||||
"7b049d214adbda81d7e2a3dd146f6ed09" | "7b049d214adbda81d7e2a3dd146f6ed09" | ||||
"\"")); | "\"")}, | ||||
} | |||||
.ToString()); | |||||
} | } | ||||
BlockHash hash(ParseHashV(request.params[0], "hash")); | BlockHash hash(ParseHashV(request.params[0], "hash")); | ||||
bool fVerbose = true; | bool fVerbose = true; | ||||
if (!request.params[1].isNull()) { | if (!request.params[1].isNull()) { | ||||
fVerbose = request.params[1].get_bool(); | fVerbose = request.params[1].get_bool(); | ||||
} | } | ||||
Show All 37 Lines | static CBlock GetBlockChecked(const Config &config, | ||||
} | } | ||||
return block; | return block; | ||||
} | } | ||||
static UniValue getblock(const Config &config, const JSONRPCRequest &request) { | static UniValue getblock(const Config &config, const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() < 1 || | if (request.fHelp || request.params.size() < 1 || | ||||
request.params.size() > 2) { | request.params.size() > 2) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"getblock", | "getblock", | ||||
"\nIf verbosity is 0 or false, returns a string that is " | "\nIf verbosity is 0 or false, returns a string that is " | ||||
"serialized, hex-encoded data for block 'hash'.\n" | "serialized, hex-encoded data for block 'hash'.\n" | ||||
"If verbosity is 1 or true, returns an Object with information " | "If verbosity is 1 or true, returns an Object with information " | ||||
"about block <hash>.\n" | "about block <hash>.\n" | ||||
"If verbosity is 2, returns an Object with information about " | "If verbosity is 2, returns an Object with information about " | ||||
"block <hash> and information about each transaction.\n", | "block <hash> and information about each transaction.\n", | ||||
{ | { | ||||
{"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | {"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | ||||
/* default_val */ "", "The block hash"}, | /* default_val */ "", "The block hash"}, | ||||
{"verbosity", RPCArg::Type::NUM, /* opt */ true, | {"verbosity", RPCArg::Type::NUM, /* opt */ true, | ||||
/* default_val */ "1", | /* default_val */ "1", | ||||
"0 for hex-encoded data, 1 for a json object, and 2 for " | "0 for hex-encoded data, 1 for a json object, and 2 for " | ||||
"json object with transaction data"}, | "json object with transaction data"}, | ||||
}} | }, | ||||
.ToString() + | { | ||||
"\nResult (for verbosity = 0):\n" | RPCResult{"for verbosity = 0", | ||||
"\"data\" (string) A string that is serialized, " | "\"data\" (string) A string that " | ||||
"is serialized, " | |||||
"hex-encoded data for block 'hash'.\n" | "hex-encoded data for block 'hash'.\n" | ||||
"\nResult (for verbosity = 1):\n" | "\nResult (for verbosity = 1):\n"}, | ||||
RPCResult{ | |||||
"for verbosity = 1", | |||||
"{\n" | "{\n" | ||||
" \"hash\" : \"hash\", (string) The block hash (same as " | " \"hash\" : \"hash\", (string) The block hash " | ||||
"(same as " | |||||
"provided)\n" | "provided)\n" | ||||
" \"confirmations\" : n, (numeric) The number of confirmations, " | " \"confirmations\" : n, (numeric) The number of " | ||||
"confirmations, " | |||||
"or -1 if the block is not on the main chain\n" | "or -1 if the block is not on the main chain\n" | ||||
" \"size\" : n, (numeric) The block size\n" | " \"size\" : n, (numeric) The block size\n" | ||||
" \"height\" : n, (numeric) The block height or index\n" | " \"height\" : n, (numeric) The block height or " | ||||
"index\n" | |||||
" \"version\" : n, (numeric) The block version\n" | " \"version\" : n, (numeric) The block version\n" | ||||
" \"versionHex\" : \"00000000\", (string) The block version " | " \"versionHex\" : \"00000000\", (string) The block " | ||||
"version " | |||||
"formatted in hexadecimal\n" | "formatted in hexadecimal\n" | ||||
" \"merkleroot\" : \"xxxx\", (string) The merkle root\n" | " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" | ||||
" \"tx\" : [ (array of string) The transaction ids\n" | " \"tx\" : [ (array of string) The " | ||||
"transaction ids\n" | |||||
" \"transactionid\" (string) The transaction id\n" | " \"transactionid\" (string) The transaction id\n" | ||||
" ,...\n" | " ,...\n" | ||||
" ],\n" | " ],\n" | ||||
" \"time\" : ttt, (numeric) The block time in seconds " | " \"time\" : ttt, (numeric) The block time in " | ||||
"seconds " | |||||
"since epoch (Jan 1 1970 GMT)\n" | "since epoch (Jan 1 1970 GMT)\n" | ||||
" \"mediantime\" : ttt, (numeric) The median block time in " | " \"mediantime\" : ttt, (numeric) The median block " | ||||
"time in " | |||||
"seconds since epoch (Jan 1 1970 GMT)\n" | "seconds since epoch (Jan 1 1970 GMT)\n" | ||||
" \"nonce\" : n, (numeric) The nonce\n" | " \"nonce\" : n, (numeric) The nonce\n" | ||||
" \"bits\" : \"1d00ffff\", (string) The bits\n" | " \"bits\" : \"1d00ffff\", (string) The bits\n" | ||||
" \"difficulty\" : x.xxx, (numeric) The difficulty\n" | " \"difficulty\" : x.xxx, (numeric) The difficulty\n" | ||||
" \"chainwork\" : \"xxxx\", (string) Expected number of hashes " | " \"chainwork\" : \"xxxx\", (string) Expected number of " | ||||
"hashes " | |||||
"required to produce the chain up to this block (in hex)\n" | "required to produce the chain up to this block (in hex)\n" | ||||
" \"nTx\" : n, (numeric) The number of transactions " | " \"nTx\" : n, (numeric) The number of " | ||||
"transactions " | |||||
"in the block.\n" | "in the block.\n" | ||||
" \"previousblockhash\" : \"hash\", (string) The hash of the " | " \"previousblockhash\" : \"hash\", (string) The hash of " | ||||
"the " | |||||
"previous block\n" | "previous block\n" | ||||
" \"nextblockhash\" : \"hash\" (string) The hash of the " | " \"nextblockhash\" : \"hash\" (string) The hash of " | ||||
"the " | |||||
"next block\n" | "next block\n" | ||||
"}\n" | "}\n"}, | ||||
"\nResult (for verbosity = 2):\n" | RPCResult{ | ||||
"for verbosity = 2", | |||||
"{\n" | "{\n" | ||||
" ..., Same output as verbosity = 1\n" | " ..., Same output as verbosity = 1\n" | ||||
" \"tx\" : [ (array of Objects) The transactions in " | " \"tx\" : [ (array of Objects) The " | ||||
"the format of the getrawtransaction RPC; different from verbosity " | "transactions in " | ||||
"the format of the getrawtransaction RPC; different from " | |||||
"verbosity " | |||||
"= 1 \"tx\" result\n" | "= 1 \"tx\" result\n" | ||||
" ...\n" | " ...\n" | ||||
" ],\n" | " ],\n" | ||||
" ... Same output as verbosity = 1\n" | " ... Same output as verbosity = 1\n" | ||||
"}\n" | "}\n"}, | ||||
"\nExamples:\n" + | }, | ||||
HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d" | RPCExamples{HelpExampleCli("getblock", | ||||
"\"00000000c937983704a73af28acdec37b049d" | |||||
"214adbda81d7e2a3dd146f6ed09\"") + | "214adbda81d7e2a3dd146f6ed09\"") + | ||||
HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d" | HelpExampleRpc("getblock", | ||||
"214adbda81d7e2a3dd146f6ed09\"")); | "\"00000000c937983704a73af28acdec37b049d" | ||||
"214adbda81d7e2a3dd146f6ed09\"")}, | |||||
} | |||||
.ToString()); | |||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
BlockHash hash(ParseHashV(request.params[0], "blockhash")); | BlockHash hash(ParseHashV(request.params[0], "blockhash")); | ||||
int verbosity = 1; | int verbosity = 1; | ||||
if (!request.params[1].isNull()) { | if (!request.params[1].isNull()) { | ||||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) { | ||||
stats.hashSerialized = ss.GetHash(); | stats.hashSerialized = ss.GetHash(); | ||||
stats.nDiskSize = view->EstimateSize(); | stats.nDiskSize = view->EstimateSize(); | ||||
return true; | return true; | ||||
} | } | ||||
static UniValue pruneblockchain(const Config &config, | static UniValue pruneblockchain(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 1) { | if (request.fHelp || request.params.size() != 1) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"pruneblockchain", | "pruneblockchain", | ||||
"", | "", | ||||
{ | { | ||||
{"height", RPCArg::Type::NUM, /* opt */ false, | {"height", RPCArg::Type::NUM, /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"The block height to prune up to. May be set to a " | "The block height to prune up to. May be set to a " | ||||
"discrete height, or a unix timestamp\n"}, | "discrete height, or a unix timestamp\n"}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{"n (numeric) Height of the last block pruned.\n"}, | ||||
"\nResult:\n" | RPCExamples{HelpExampleCli("pruneblockchain", "1000") + | ||||
"n (numeric) Height of the last block pruned.\n" | HelpExampleRpc("pruneblockchain", "1000")}, | ||||
"\nExamples:\n" + | } | ||||
HelpExampleCli("pruneblockchain", "1000") + | .ToString()); | ||||
HelpExampleRpc("pruneblockchain", "1000")); | |||||
} | } | ||||
if (!fPruneMode) { | if (!fPruneMode) { | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_MISC_ERROR, | RPC_MISC_ERROR, | ||||
"Cannot prune blocks because node is not in prune mode."); | "Cannot prune blocks because node is not in prune mode."); | ||||
} | } | ||||
Show All 36 Lines | static UniValue pruneblockchain(const Config &config, | ||||
PruneBlockFilesManual(height); | PruneBlockFilesManual(height); | ||||
return uint64_t(height); | return uint64_t(height); | ||||
} | } | ||||
static UniValue gettxoutsetinfo(const Config &config, | static UniValue gettxoutsetinfo(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 0) { | if (request.fHelp || request.params.size() != 0) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"gettxoutsetinfo", | "gettxoutsetinfo", | ||||
"\nReturns statistics about the unspent transaction " | "\nReturns statistics about the unspent transaction output set.\n" | ||||
"output set.\n" | |||||
"Note this call may take some time.\n", | "Note this call may take some time.\n", | ||||
{}} | {}, | ||||
.ToString() + | RPCResult{ | ||||
"\nResult:\n" | |||||
"{\n" | "{\n" | ||||
" \"height\":n, (numeric) The current block height (index)\n" | " \"height\":n, (numeric) The current block height " | ||||
"(index)\n" | |||||
" \"bestblock\": \"hex\", (string) the best block hash hex\n" | " \"bestblock\": \"hex\", (string) the best block hash hex\n" | ||||
" \"transactions\": n, (numeric) The number of transactions\n" | " \"transactions\": n, (numeric) The number of " | ||||
"transactions\n" | |||||
" \"txouts\": n, (numeric) The number of output " | " \"txouts\": n, (numeric) The number of output " | ||||
"transactions\n" | "transactions\n" | ||||
" \"bogosize\": n, (numeric) A database-independent " | " \"bogosize\": n, (numeric) A database-independent " | ||||
"metric for UTXO set size\n" | "metric for UTXO set size\n" | ||||
" \"hash_serialized\": \"hash\", (string) The serialized hash\n" | " \"hash_serialized\": \"hash\", (string) The serialized " | ||||
" \"disk_size\": n, (numeric) The estimated size of the " | "hash\n" | ||||
" \"disk_size\": n, (numeric) The estimated size of " | |||||
"the " | |||||
"chainstate on disk\n" | "chainstate on disk\n" | ||||
" \"total_amount\": x.xxx (numeric) The total amount\n" | " \"total_amount\": x.xxx (numeric) The total " | ||||
"}\n" | "amount\n" | ||||
"\nExamples:\n" + | "}\n"}, | ||||
HelpExampleCli("gettxoutsetinfo", "") + | RPCExamples{HelpExampleCli("gettxoutsetinfo", "") + | ||||
HelpExampleRpc("gettxoutsetinfo", "")); | HelpExampleRpc("gettxoutsetinfo", "")}, | ||||
} | |||||
.ToString()); | |||||
} | } | ||||
UniValue ret(UniValue::VOBJ); | UniValue ret(UniValue::VOBJ); | ||||
CCoinsStats stats; | CCoinsStats stats; | ||||
FlushStateToDisk(); | FlushStateToDisk(); | ||||
if (GetUTXOStats(pcoinsdbview.get(), stats)) { | if (GetUTXOStats(pcoinsdbview.get(), stats)) { | ||||
ret.pushKV("height", int64_t(stats.nHeight)); | ret.pushKV("height", int64_t(stats.nHeight)); | ||||
ret.pushKV("bestblock", stats.hashBlock.GetHex()); | ret.pushKV("bestblock", stats.hashBlock.GetHex()); | ||||
ret.pushKV("transactions", int64_t(stats.nTransactions)); | ret.pushKV("transactions", int64_t(stats.nTransactions)); | ||||
ret.pushKV("txouts", int64_t(stats.nTransactionOutputs)); | ret.pushKV("txouts", int64_t(stats.nTransactionOutputs)); | ||||
ret.pushKV("bogosize", int64_t(stats.nBogoSize)); | ret.pushKV("bogosize", int64_t(stats.nBogoSize)); | ||||
ret.pushKV("hash_serialized", stats.hashSerialized.GetHex()); | ret.pushKV("hash_serialized", stats.hashSerialized.GetHex()); | ||||
ret.pushKV("disk_size", stats.nDiskSize); | ret.pushKV("disk_size", stats.nDiskSize); | ||||
ret.pushKV("total_amount", ValueFromAmount(stats.nTotalAmount)); | ret.pushKV("total_amount", ValueFromAmount(stats.nTotalAmount)); | ||||
} else { | } else { | ||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set"); | throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set"); | ||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
UniValue gettxout(const Config &config, const JSONRPCRequest &request) { | UniValue gettxout(const Config &config, const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() < 2 || | if (request.fHelp || request.params.size() < 2 || | ||||
request.params.size() > 3) { | request.params.size() > 3) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"gettxout", | "gettxout", | ||||
"\nReturns details about an unspent transaction output.\n", | "\nReturns details about an unspent transaction output.\n", | ||||
{ | { | ||||
{"txid", RPCArg::Type::STR_HEX, /* opt */ false, | {"txid", RPCArg::Type::STR_HEX, /* opt */ false, | ||||
/* default_val */ "", "The transaction id"}, | /* default_val */ "", "The transaction id"}, | ||||
{"n", RPCArg::Type::NUM, /* opt */ false, | {"n", RPCArg::Type::NUM, /* opt */ false, | ||||
/* default_val */ "", "vout number"}, | /* default_val */ "", "vout number"}, | ||||
{"include_mempool", RPCArg::Type::BOOL, /* opt */ true, | {"include_mempool", RPCArg::Type::BOOL, /* opt */ true, | ||||
/* default_val */ "true", | /* default_val */ "true", | ||||
"Whether to include the mempool. Note that an unspent " | "Whether to include the mempool. Note that an unspent " | ||||
"output that is spent in the mempool won't appear."}, | "output that is spent in the mempool won't appear."}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{ | ||||
"\nResult:\n" | |||||
"{\n" | "{\n" | ||||
" \"bestblock\" : \"hash\", (string) the block hash\n" | " \"bestblock\" : \"hash\", (string) the block hash\n" | ||||
" \"confirmations\" : n, (numeric) The number of " | " \"confirmations\" : n, (numeric) The number of " | ||||
"confirmations\n" | "confirmations\n" | ||||
" \"value\" : x.xxx, (numeric) The transaction value " | " \"value\" : x.xxx, (numeric) The transaction " | ||||
"value " | |||||
"in " + | "in " + | ||||
CURRENCY_UNIT + | CURRENCY_UNIT + | ||||
"\n" | "\n" | ||||
" \"scriptPubKey\" : { (json object)\n" | " \"scriptPubKey\" : { (json object)\n" | ||||
" \"asm\" : \"code\", (string) \n" | " \"asm\" : \"code\", (string) \n" | ||||
" \"hex\" : \"hex\", (string) \n" | " \"hex\" : \"hex\", (string) \n" | ||||
" \"reqSigs\" : n, (numeric) Number of required " | " \"reqSigs\" : n, (numeric) Number of required " | ||||
"signatures\n" | "signatures\n" | ||||
" \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n" | " \"type\" : \"pubkeyhash\", (string) The type, eg " | ||||
"pubkeyhash\n" | |||||
" \"addresses\" : [ (array of string) array of " | " \"addresses\" : [ (array of string) array of " | ||||
"bitcoin addresses\n" | "bitcoin addresses\n" | ||||
" \"address\" (string) bitcoin address\n" | " \"address\" (string) bitcoin address\n" | ||||
" ,...\n" | " ,...\n" | ||||
" ]\n" | " ]\n" | ||||
" },\n" | " },\n" | ||||
" \"coinbase\" : true|false (boolean) Coinbase or not\n" | " \"coinbase\" : true|false (boolean) Coinbase or not\n" | ||||
"}\n" | "}\n"}, | ||||
RPCExamples{"\nGet unspent transactions\n" + | |||||
"\nExamples:\n" | HelpExampleCli("listunspent", "") + | ||||
"\nGet unspent transactions\n" + | "\nView the details\n" + | ||||
HelpExampleCli("listunspent", "") + "\nView the details\n" + | |||||
HelpExampleCli("gettxout", "\"txid\" 1") + | HelpExampleCli("gettxout", "\"txid\" 1") + | ||||
"\nAs a JSON-RPC call\n" + | "\nAs a JSON-RPC call\n" + | ||||
HelpExampleRpc("gettxout", "\"txid\", 1")); | HelpExampleRpc("gettxout", "\"txid\", 1")}, | ||||
} | |||||
.ToString()); | |||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
UniValue ret(UniValue::VOBJ); | UniValue ret(UniValue::VOBJ); | ||||
TxId txid(ParseHashV(request.params[0], "txid")); | TxId txid(ParseHashV(request.params[0], "txid")); | ||||
int n = request.params[1].get_int(); | int n = request.params[1].get_int(); | ||||
Show All 33 Lines | UniValue gettxout(const Config &config, const JSONRPCRequest &request) { | ||||
return ret; | return ret; | ||||
} | } | ||||
static UniValue verifychain(const Config &config, | static UniValue verifychain(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
int nCheckLevel = gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL); | int nCheckLevel = gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL); | ||||
int nCheckDepth = gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS); | int nCheckDepth = gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS); | ||||
if (request.fHelp || request.params.size() > 2) { | if (request.fHelp || request.params.size() > 2) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"verifychain", | "verifychain", | ||||
"\nVerifies blockchain database.\n", | "\nVerifies blockchain database.\n", | ||||
{ | { | ||||
{"checklevel", RPCArg::Type::NUM, /* opt */ true, | {"checklevel", RPCArg::Type::NUM, /* opt */ true, | ||||
/* default_val */ strprintf("%d, range=0-4", nCheckLevel), | /* default_val */ strprintf("%d, range=0-4", nCheckLevel), | ||||
"How thorough the block verification is."}, | "How thorough the block verification is."}, | ||||
{"nblocks", RPCArg::Type::NUM, /* opt */ true, | {"nblocks", RPCArg::Type::NUM, /* opt */ true, | ||||
/* default_val */ strprintf("%d, 0=all", nCheckDepth), | /* default_val */ strprintf("%d, 0=all", nCheckDepth), | ||||
"The number of blocks to check."}, | "The number of blocks to check."}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{"true|false (boolean) Verified or not\n"}, | ||||
"\nResult:\n" | RPCExamples{HelpExampleCli("verifychain", "") + | ||||
"true|false (boolean) Verified or not\n" | HelpExampleRpc("verifychain", "")}, | ||||
"\nExamples:\n" + | } | ||||
HelpExampleCli("verifychain", "") + | .ToString()); | ||||
HelpExampleRpc("verifychain", "")); | |||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
if (!request.params[0].isNull()) { | if (!request.params[0].isNull()) { | ||||
nCheckLevel = request.params[0].get_int(); | nCheckLevel = request.params[0].get_int(); | ||||
} | } | ||||
if (!request.params[1].isNull()) { | if (!request.params[1].isNull()) { | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | static void BIP9SoftForkDescPushBack(UniValue &softforks, | ||||
rv.pushKV("active", ThresholdState::ACTIVE == thresholdState); | rv.pushKV("active", ThresholdState::ACTIVE == thresholdState); | ||||
softforks.pushKV(VersionBitsDeploymentInfo[id].name, rv); | softforks.pushKV(VersionBitsDeploymentInfo[id].name, rv); | ||||
} | } | ||||
UniValue getblockchaininfo(const Config &config, | UniValue getblockchaininfo(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 0) { | if (request.fHelp || request.params.size() != 0) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"getblockchaininfo", | "getblockchaininfo", | ||||
"Returns an object containing various state info " | "Returns an object containing various state info " | ||||
"regarding blockchain processing.\n", | "regarding blockchain processing.\n", | ||||
{}} | {}, | ||||
.ToString() + | RPCResult{ | ||||
"\nResult:\n" | |||||
"{\n" | "{\n" | ||||
" \"chain\": \"xxxx\", (string) current network name " | " \"chain\": \"xxxx\", (string) current network " | ||||
"name " | |||||
"as defined in BIP70 (main, test, regtest)\n" | "as defined in BIP70 (main, test, regtest)\n" | ||||
" \"blocks\": xxxxxx, (numeric) the current number of " | " \"blocks\": xxxxxx, (numeric) the current " | ||||
"number of " | |||||
"blocks processed in the server\n" | "blocks processed in the server\n" | ||||
" \"headers\": xxxxxx, (numeric) the current number of " | " \"headers\": xxxxxx, (numeric) the current " | ||||
"number of " | |||||
"headers we have validated\n" | "headers we have validated\n" | ||||
" \"bestblockhash\": \"...\", (string) the hash of the " | " \"bestblockhash\": \"...\", (string) the hash of the " | ||||
"currently best block\n" | "currently best block\n" | ||||
" \"difficulty\": xxxxxx, (numeric) the current " | " \"difficulty\": xxxxxx, (numeric) the current " | ||||
"difficulty\n" | "difficulty\n" | ||||
" \"mediantime\": xxxxxx, (numeric) median time for the " | " \"mediantime\": xxxxxx, (numeric) median time for " | ||||
"the " | |||||
"current best block\n" | "current best block\n" | ||||
" \"verificationprogress\": xxxx, (numeric) estimate of " | " \"verificationprogress\": xxxx, (numeric) estimate of " | ||||
"verification progress [0..1]\n" | "verification progress [0..1]\n" | ||||
" \"initialblockdownload\": xxxx, (bool) (debug information) " | " \"initialblockdownload\": xxxx, (bool) (debug information) " | ||||
"estimate of whether this node is in Initial Block Download mode.\n" | "estimate of whether this node is in Initial Block Download " | ||||
" \"chainwork\": \"xxxx\" (string) total amount of work " | "mode.\n" | ||||
" \"chainwork\": \"xxxx\" (string) total amount of " | |||||
"work " | |||||
"in active chain, in hexadecimal\n" | "in active chain, in hexadecimal\n" | ||||
" \"size_on_disk\": xxxxxx, (numeric) the estimated size of " | " \"size_on_disk\": xxxxxx, (numeric) the estimated " | ||||
"size of " | |||||
"the block and undo files on disk\n" | "the block and undo files on disk\n" | ||||
" \"pruned\": xx, (boolean) if the blocks are " | " \"pruned\": xx, (boolean) if the blocks are " | ||||
"subject to pruning\n" | "subject to pruning\n" | ||||
" \"pruneheight\": xxxxxx, (numeric) lowest-height " | " \"pruneheight\": xxxxxx, (numeric) lowest-height " | ||||
"complete block stored (only present if pruning is enabled)\n" | "complete block stored (only present if pruning is enabled)\n" | ||||
" \"automatic_pruning\": xx, (boolean) whether automatic " | " \"automatic_pruning\": xx, (boolean) whether automatic " | ||||
"pruning is enabled (only present if pruning is enabled)\n" | "pruning is enabled (only present if pruning is enabled)\n" | ||||
" \"prune_target_size\": xxxxxx, (numeric) the target size " | " \"prune_target_size\": xxxxxx, (numeric) the target size " | ||||
"used by pruning (only present if automatic pruning is enabled)\n" | "used by pruning (only present if automatic pruning is " | ||||
"enabled)\n" | |||||
" \"warnings\" : \"...\", (string) any network and " | " \"warnings\" : \"...\", (string) any network and " | ||||
"blockchain warnings.\n" | "blockchain warnings.\n" | ||||
"}\n" | "}\n"}, | ||||
"\nExamples:\n" + | RPCExamples{HelpExampleCli("getblockchaininfo", "") + | ||||
HelpExampleCli("getblockchaininfo", "") + | HelpExampleRpc("getblockchaininfo", "")}, | ||||
HelpExampleRpc("getblockchaininfo", "")); | } | ||||
.ToString()); | |||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
const CChainParams &chainparams = config.GetChainParams(); | const CChainParams &chainparams = config.GetChainParams(); | ||||
const CBlockIndex *tip = ::ChainActive().Tip(); | const CBlockIndex *tip = ::ChainActive().Tip(); | ||||
UniValue obj(UniValue::VOBJ); | UniValue obj(UniValue::VOBJ); | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | bool operator()(const CBlockIndex *a, const CBlockIndex *b) const { | ||||
return a < b; | return a < b; | ||||
} | } | ||||
}; | }; | ||||
static UniValue getchaintips(const Config &config, | static UniValue getchaintips(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 0) { | if (request.fHelp || request.params.size() != 0) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"getchaintips", | "getchaintips", | ||||
"Return information about all known tips in the block tree, " | "Return information about all known tips in the block tree, " | ||||
"including the main chain as well as orphaned branches.\n", | "including the main chain as well as orphaned branches.\n", | ||||
{}} | {}, | ||||
.ToString() + | RPCResult{ | ||||
"\nResult:\n" | |||||
"[\n" | "[\n" | ||||
" {\n" | " {\n" | ||||
" \"height\": xxxx, (numeric) height of the chain tip\n" | " \"height\": xxxx, (numeric) height of the chain " | ||||
" \"hash\": \"xxxx\", (string) block hash of the tip\n" | "tip\n" | ||||
" \"hash\": \"xxxx\", (string) block hash of the " | |||||
"tip\n" | |||||
" \"branchlen\": 0 (numeric) zero for main chain\n" | " \"branchlen\": 0 (numeric) zero for main chain\n" | ||||
" \"status\": \"active\" (string) \"active\" for the main " | " \"status\": \"active\" (string) \"active\" for the " | ||||
"main " | |||||
"chain\n" | "chain\n" | ||||
" },\n" | " },\n" | ||||
" {\n" | " {\n" | ||||
" \"height\": xxxx,\n" | " \"height\": xxxx,\n" | ||||
" \"hash\": \"xxxx\",\n" | " \"hash\": \"xxxx\",\n" | ||||
" \"branchlen\": 1 (numeric) length of branch " | " \"branchlen\": 1 (numeric) length of branch " | ||||
"connecting the tip to the main chain\n" | "connecting the tip to the main chain\n" | ||||
" \"status\": \"xxxx\" (string) status of the chain " | " \"status\": \"xxxx\" (string) status of the chain " | ||||
"(active, valid-fork, valid-headers, headers-only, invalid)\n" | "(active, valid-fork, valid-headers, headers-only, invalid)\n" | ||||
" }\n" | " }\n" | ||||
"]\n" | "]\n" | ||||
"Possible values for status:\n" | "Possible values for status:\n" | ||||
"1. \"invalid\" This branch contains at least one " | "1. \"invalid\" This branch contains at least " | ||||
"one " | |||||
"invalid block\n" | "invalid block\n" | ||||
"2. \"parked\" This branch contains at least one " | "2. \"parked\" This branch contains at least " | ||||
"one " | |||||
"parked block\n" | "parked block\n" | ||||
"3. \"headers-only\" Not all blocks for this branch are " | "3. \"headers-only\" Not all blocks for this branch " | ||||
"are " | |||||
"available, but the headers are valid\n" | "available, but the headers are valid\n" | ||||
"4. \"valid-headers\" All blocks are available for this " | "4. \"valid-headers\" All blocks are available for " | ||||
"this " | |||||
"branch, but they were never fully validated\n" | "branch, but they were never fully validated\n" | ||||
"5. \"valid-fork\" This branch is not part of the " | "5. \"valid-fork\" This branch is not part of the " | ||||
"active chain, but is fully validated\n" | "active chain, but is fully validated\n" | ||||
"6. \"active\" This is the tip of the active main " | "6. \"active\" This is the tip of the active " | ||||
"chain, which is certainly valid\n" | "main " | ||||
"\nExamples:\n" + | "chain, which is certainly valid\n"}, | ||||
HelpExampleCli("getchaintips", "") + | RPCExamples{HelpExampleCli("getchaintips", "") + | ||||
HelpExampleRpc("getchaintips", "")); | HelpExampleRpc("getchaintips", "")}, | ||||
} | |||||
.ToString()); | |||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
/** | /** | ||||
* Idea: the set of chain tips is ::ChainActive().tip, plus orphan blocks | * Idea: the set of chain tips is ::ChainActive().tip, plus orphan blocks | ||||
* which do not have another orphan building off of them. Algorithm: | * which do not have another orphan building off of them. Algorithm: | ||||
* - Make one pass through mapBlockIndex, picking out the orphan blocks, | * - Make one pass through mapBlockIndex, picking out the orphan blocks, | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | UniValue MempoolInfoToJSON(const CTxMemPool &pool) { | ||||
ret.pushKV("minrelaytxfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())); | ret.pushKV("minrelaytxfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())); | ||||
return ret; | return ret; | ||||
} | } | ||||
static UniValue getmempoolinfo(const Config &config, | static UniValue getmempoolinfo(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 0) { | if (request.fHelp || request.params.size() != 0) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"getmempoolinfo", | "getmempoolinfo", | ||||
"\nReturns details on the active state of the TX memory " | "\nReturns details on the active state of the TX memory " | ||||
"pool.\n", | "pool.\n", | ||||
{}} | {}, | ||||
.ToString() + | RPCResult{ | ||||
"\nResult:\n" | |||||
"{\n" | "{\n" | ||||
" \"loaded\": true|false (boolean) True if the mempool is " | " \"loaded\": true|false (boolean) True if the " | ||||
"mempool is " | |||||
"fully loaded\n" | "fully loaded\n" | ||||
" \"size\": xxxxx, (numeric) Current tx count\n" | " \"size\": xxxxx, (numeric) Current tx count\n" | ||||
" \"bytes\": xxxxx, (numeric) Transaction size.\n" | " \"bytes\": xxxxx, (numeric) Transaction size.\n" | ||||
" \"usage\": xxxxx, (numeric) Total memory usage for " | " \"usage\": xxxxx, (numeric) Total memory usage " | ||||
"for " | |||||
"the mempool\n" | "the mempool\n" | ||||
" \"maxmempool\": xxxxx, (numeric) Maximum memory usage " | " \"maxmempool\": xxxxx, (numeric) Maximum memory " | ||||
"usage " | |||||
"for the mempool\n" | "for the mempool\n" | ||||
" \"mempoolminfee\": xxxxx (numeric) Minimum fee rate in " + | " \"mempoolminfee\": xxxxx (numeric) Minimum fee rate " | ||||
"in " + | |||||
CURRENCY_UNIT + | CURRENCY_UNIT + | ||||
"/kB for tx to be accepted. Is the maximum of minrelaytxfee and " | "/kB for tx to be accepted. Is the maximum of minrelaytxfee " | ||||
"and " | |||||
"minimum mempool fee\n" | "minimum mempool fee\n" | ||||
" \"minrelaytxfee\": xxxxx (numeric) Current minimum relay " | " \"minrelaytxfee\": xxxxx (numeric) Current minimum " | ||||
"relay " | |||||
"fee for transactions\n" | "fee for transactions\n" | ||||
"}\n" | "}\n"}, | ||||
"\nExamples:\n" + | RPCExamples{HelpExampleCli("getmempoolinfo", "") + | ||||
HelpExampleCli("getmempoolinfo", "") + | HelpExampleRpc("getmempoolinfo", "")}, | ||||
HelpExampleRpc("getmempoolinfo", "")); | } | ||||
.ToString()); | |||||
} | } | ||||
return MempoolInfoToJSON(::g_mempool); | return MempoolInfoToJSON(::g_mempool); | ||||
} | } | ||||
static UniValue preciousblock(const Config &config, | static UniValue preciousblock(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 1) { | if (request.fHelp || request.params.size() != 1) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"preciousblock", | "preciousblock", | ||||
"\nTreats a block as if it were received before others " | "\nTreats a block as if it were received before others " | ||||
"with the same work.\n" | "with the same work.\n" | ||||
"\nA later preciousblock call can override the effect " | "\nA later preciousblock call can override the effect " | ||||
"of an earlier one.\n" | "of an earlier one.\n" | ||||
"\nThe effects of preciousblock are not retained across " | "\nThe effects of preciousblock are not retained across " | ||||
"restarts.\n", | "restarts.\n", | ||||
{ | { | ||||
{"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | {"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"the hash of the block to mark as precious"}, | "the hash of the block to mark as precious"}, | ||||
}} | }, | ||||
.ToString() + | RPCResults{}, | ||||
"\nResult:\n" | RPCExamples{HelpExampleCli("preciousblock", "\"blockhash\"") + | ||||
"\nExamples:\n" + | HelpExampleRpc("preciousblock", "\"blockhash\"")}, | ||||
HelpExampleCli("preciousblock", "\"blockhash\"") + | } | ||||
HelpExampleRpc("preciousblock", "\"blockhash\"")); | .ToString()); | ||||
} | } | ||||
BlockHash hash(ParseHashV(request.params[0], "blockhash")); | BlockHash hash(ParseHashV(request.params[0], "blockhash")); | ||||
CBlockIndex *pblockindex; | CBlockIndex *pblockindex; | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
pblockindex = LookupBlockIndex(hash); | pblockindex = LookupBlockIndex(hash); | ||||
Show All 9 Lines | if (!state.IsValid()) { | ||||
throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); | throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); | ||||
} | } | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
UniValue finalizeblock(const Config &config, const JSONRPCRequest &request) { | UniValue finalizeblock(const Config &config, const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 1) { | if (request.fHelp || request.params.size() != 1) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"finalizeblock", | "finalizeblock", | ||||
"\nTreats a block as final. It cannot be reorged. Any chain\n" | "\nTreats a block as final. It cannot be reorged. Any chain\n" | ||||
"that does not contain this block is invalid. Used on a less\n" | "that does not contain this block is invalid. Used on a less\n" | ||||
"work chain, it can effectively PUTS YOU OUT OF CONSENSUS.\n" | "work chain, it can effectively PUTS YOU OUT OF CONSENSUS.\n" | ||||
"USE WITH CAUTION!\n", | "USE WITH CAUTION!\n", | ||||
{ | { | ||||
{"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | {"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"the hash of the block to mark as invalid"}, | "the hash of the block to mark as invalid"}, | ||||
}} | }, | ||||
.ToString() + | RPCResults{}, | ||||
"\nResult:\n" | RPCExamples{HelpExampleCli("invalidateblock", "\"blockhash\"") + | ||||
"\nExamples:\n" + | HelpExampleRpc("invalidateblock", "\"blockhash\"")}, | ||||
HelpExampleCli("finalizeblock", "\"blockhash\"") + | } | ||||
HelpExampleRpc("finalizeblock", "\"blockhash\"")); | .ToString()); | ||||
} | } | ||||
std::string strHash = request.params[0].get_str(); | std::string strHash = request.params[0].get_str(); | ||||
BlockHash hash(uint256S(strHash)); | BlockHash hash(uint256S(strHash)); | ||||
CValidationState state; | CValidationState state; | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
Show All 14 Lines | UniValue finalizeblock(const Config &config, const JSONRPCRequest &request) { | ||||
} | } | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
static UniValue invalidateblock(const Config &config, | static UniValue invalidateblock(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 1) { | if (request.fHelp || request.params.size() != 1) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"invalidateblock", | "invalidateblock", | ||||
"\nPermanently marks a block as invalid, as if it " | "\nPermanently marks a block as invalid, as if it " | ||||
"violated a consensus rule.\n", | "violated a consensus rule.\n", | ||||
{ | { | ||||
{"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | {"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"the hash of the block to mark as invalid"}, | "the hash of the block to mark as invalid"}, | ||||
}} | }, | ||||
.ToString() + | RPCResults{}, | ||||
"\nResult:\n" | RPCExamples{HelpExampleCli("invalidateblock", "\"blockhash\"") + | ||||
"\nExamples:\n" + | HelpExampleRpc("invalidateblock", "\"blockhash\"")}, | ||||
HelpExampleCli("invalidateblock", "\"blockhash\"") + | } | ||||
HelpExampleRpc("invalidateblock", "\"blockhash\"")); | .ToString()); | ||||
} | } | ||||
const BlockHash hash(ParseHashV(request.params[0], "blockhash")); | const BlockHash hash(ParseHashV(request.params[0], "blockhash")); | ||||
CValidationState state; | CValidationState state; | ||||
CBlockIndex *pblockindex; | CBlockIndex *pblockindex; | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
Show All 12 Lines | if (!state.IsValid()) { | ||||
throw JSONRPCError(RPC_DATABASE_ERROR, FormatStateMessage(state)); | throw JSONRPCError(RPC_DATABASE_ERROR, FormatStateMessage(state)); | ||||
} | } | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
UniValue parkblock(const Config &config, const JSONRPCRequest &request) { | UniValue parkblock(const Config &config, const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 1) { | if (request.fHelp || request.params.size() != 1) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"parkblock", | "parkblock", | ||||
"\nMarks a block as parked.\n", | "\nMarks a block as parked.\n", | ||||
{ | { | ||||
{"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | {"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | ||||
/* default_val */ "", "the hash of the block to park"}, | /* default_val */ "", "the hash of the block to park"}, | ||||
}} | }, | ||||
.ToString() + | RPCResults{}, | ||||
"\nResult:\n" | RPCExamples{HelpExampleCli("parkblock", "\"blockhash\"") + | ||||
"\nExamples:\n" + | HelpExampleRpc("parkblock", "\"blockhash\"")}, | ||||
HelpExampleCli("parkblock", "\"blockhash\"") + | } | ||||
HelpExampleRpc("parkblock", "\"blockhash\"")); | .ToString()); | ||||
} | } | ||||
const std::string strHash = request.params[0].get_str(); | const std::string strHash = request.params[0].get_str(); | ||||
const BlockHash hash(uint256S(strHash)); | const BlockHash hash(uint256S(strHash)); | ||||
CValidationState state; | CValidationState state; | ||||
CBlockIndex *pblockindex; | CBlockIndex *pblockindex; | ||||
{ | { | ||||
Show All 15 Lines | UniValue parkblock(const Config &config, const JSONRPCRequest &request) { | ||||
} | } | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
static UniValue reconsiderblock(const Config &config, | static UniValue reconsiderblock(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 1) { | if (request.fHelp || request.params.size() != 1) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"reconsiderblock", | "reconsiderblock", | ||||
"\nRemoves invalidity status of a block and its descendants, " | "\nRemoves invalidity status of a block and its descendants, " | ||||
"reconsider them for activation.\n" | "reconsider them for activation.\n" | ||||
"This can be used to undo the effects of invalidateblock.\n", | "This can be used to undo the effects of invalidateblock.\n", | ||||
{ | { | ||||
{"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | {"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", "the hash of the block to reconsider"}, | ||||
"the hash of the block to reconsider"}, | }, | ||||
}} | RPCResults{}, | ||||
.ToString() + | RPCExamples{HelpExampleCli("reconsiderblock", "\"blockhash\"") + | ||||
"\nResult:\n" | HelpExampleRpc("reconsiderblock", "\"blockhash\"")}, | ||||
"\nExamples:\n" + | } | ||||
HelpExampleCli("reconsiderblock", "\"blockhash\"") + | .ToString()); | ||||
HelpExampleRpc("reconsiderblock", "\"blockhash\"")); | |||||
} | } | ||||
const BlockHash hash(ParseHashV(request.params[0], "blockhash")); | const BlockHash hash(ParseHashV(request.params[0], "blockhash")); | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
CBlockIndex *pblockindex = LookupBlockIndex(hash); | CBlockIndex *pblockindex = LookupBlockIndex(hash); | ||||
if (!pblockindex) { | if (!pblockindex) { | ||||
Show All 10 Lines | if (!state.IsValid()) { | ||||
throw JSONRPCError(RPC_DATABASE_ERROR, FormatStateMessage(state)); | throw JSONRPCError(RPC_DATABASE_ERROR, FormatStateMessage(state)); | ||||
} | } | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
UniValue unparkblock(const Config &config, const JSONRPCRequest &request) { | UniValue unparkblock(const Config &config, const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 1) { | if (request.fHelp || request.params.size() != 1) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"unparkblock", | "unparkblock", | ||||
"\nRemoves parked status of a block and its descendants, " | "\nRemoves parked status of a block and its descendants, " | ||||
"reconsider them for activation.\n" | "reconsider them for activation.\n" | ||||
"This can be used to undo the effects of parkblock.\n", | "This can be used to undo the effects of parkblock.\n", | ||||
{ | { | ||||
{"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | {"blockhash", RPCArg::Type::STR_HEX, /* opt */ false, | ||||
/* default_val */ "", "the hash of the block to unpark"}, | /* default_val */ "", "the hash of the block to unpark"}, | ||||
}} | }, | ||||
.ToString() + | RPCResults{}, | ||||
"\nResult:\n" | RPCExamples{HelpExampleCli("unparkblock", "\"blockhash\"") + | ||||
"\nExamples:\n" + | HelpExampleRpc("unparkblock", "\"blockhash\"")}, | ||||
HelpExampleCli("unparkblock", "\"blockhash\"") + | } | ||||
HelpExampleRpc("unparkblock", "\"blockhash\"")); | .ToString()); | ||||
} | } | ||||
const std::string strHash = request.params[0].get_str(); | const std::string strHash = request.params[0].get_str(); | ||||
const BlockHash hash(uint256S(strHash)); | const BlockHash hash(uint256S(strHash)); | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
if (mapBlockIndex.count(hash) == 0) { | if (mapBlockIndex.count(hash) == 0) { | ||||
Show All 12 Lines | UniValue unparkblock(const Config &config, const JSONRPCRequest &request) { | ||||
} | } | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
static UniValue getchaintxstats(const Config &config, | static UniValue getchaintxstats(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() > 2) { | if (request.fHelp || request.params.size() > 2) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"getchaintxstats", | "getchaintxstats", | ||||
"\nCompute statistics about the total number and rate " | "\nCompute statistics about the total number and rate " | ||||
"of transactions in the chain.\n", | "of transactions in the chain.\n", | ||||
{ | { | ||||
{"nblocks", RPCArg::Type::NUM, /* opt */ true, | {"nblocks", RPCArg::Type::NUM, /* opt */ true, | ||||
/* default_val */ "one month", | /* default_val */ "one month", | ||||
"Size of the window in number of blocks"}, | "Size of the window in number of blocks"}, | ||||
{"blockhash", RPCArg::Type::STR_HEX, /* opt */ true, | {"blockhash", RPCArg::Type::STR_HEX, /* opt */ true, | ||||
/* default_val */ "", | /* default_val */ "chain tip", | ||||
"The hash of the block that ends the window."}, | "The hash of the block that ends the window."}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{ | ||||
"\nResult:\n" | |||||
"{\n" | "{\n" | ||||
" \"time\": xxxxx, (numeric) The " | " \"time\": xxxxx, (numeric) The " | ||||
"timestamp for the final block in the window in UNIX format.\n" | "timestamp for the final block in the window in UNIX format.\n" | ||||
" \"txcount\": xxxxx, (numeric) The total " | " \"txcount\": xxxxx, (numeric) The " | ||||
"total " | |||||
"number of transactions in the chain up to that point.\n" | "number of transactions in the chain up to that point.\n" | ||||
" \"window_final_block_hash\": \"...\", (string) The hash of " | " \"window_final_block_hash\": \"...\", (string) The " | ||||
"hash of " | |||||
"the final block in the window.\n" | "the final block in the window.\n" | ||||
" \"window_block_count\": xxxxx, (numeric) Size of " | " \"window_block_count\": xxxxx, (numeric) Size of " | ||||
"the window in number of blocks.\n" | "the window in number of blocks.\n" | ||||
" \"window_tx_count\": xxxxx, (numeric) The number " | " \"window_tx_count\": xxxxx, (numeric) The " | ||||
"number " | |||||
"of transactions in the window. Only returned if " | "of transactions in the window. Only returned if " | ||||
"\"window_block_count\" is > 0.\n" | "\"window_block_count\" is > 0.\n" | ||||
" \"window_interval\": xxxxx, (numeric) The elapsed " | " \"window_interval\": xxxxx, (numeric) The " | ||||
"elapsed " | |||||
"time in the window in seconds. Only returned if " | "time in the window in seconds. Only returned if " | ||||
"\"window_block_count\" is > 0.\n" | "\"window_block_count\" is > 0.\n" | ||||
" \"txrate\": x.xx, (numeric) The average " | " \"txrate\": x.xx, (numeric) The " | ||||
"rate of transactions per second in the window. Only returned if " | "average " | ||||
"rate of transactions per second in the window. Only returned " | |||||
"if " | |||||
"\"window_interval\" is > 0.\n" | "\"window_interval\" is > 0.\n" | ||||
"}\n" | "}\n"}, | ||||
"\nExamples:\n" + | RPCExamples{HelpExampleCli("getchaintxstats", "") + | ||||
HelpExampleCli("getchaintxstats", "") + | HelpExampleRpc("getchaintxstats", "2016")}, | ||||
HelpExampleRpc("getchaintxstats", "2016")); | } | ||||
.ToString()); | |||||
} | } | ||||
const CBlockIndex *pindex; | const CBlockIndex *pindex; | ||||
// By default: 1 month | // By default: 1 month | ||||
int blockcount = 30 * 24 * 60 * 60 / | int blockcount = 30 * 24 * 60 * 60 / | ||||
config.GetChainParams().GetConsensus().nPowTargetSpacing; | config.GetChainParams().GetConsensus().nPowTargetSpacing; | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | |||||
// outpoint (needed for the utxo index) + nHeight + fCoinBase | // outpoint (needed for the utxo index) + nHeight + fCoinBase | ||||
static constexpr size_t PER_UTXO_OVERHEAD = | static constexpr size_t PER_UTXO_OVERHEAD = | ||||
sizeof(COutPoint) + sizeof(uint32_t) + sizeof(bool); | sizeof(COutPoint) + sizeof(uint32_t) + sizeof(bool); | ||||
static UniValue getblockstats(const Config &config, | static UniValue getblockstats(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() < 1 || | if (request.fHelp || request.params.size() < 1 || | ||||
request.params.size() > 4) { | request.params.size() > 4) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"getblockstats", | "getblockstats", | ||||
"\nCompute per block statistics for a given window. All " | "\nCompute per block statistics for a given window. All " | ||||
"amounts are in " + | "amounts are in " + | ||||
CURRENCY_UNIT + | CURRENCY_UNIT + | ||||
".\n" | ".\n" | ||||
"It won't work for some heights with pruning.\n" | "It won't work for some heights with pruning.\n" | ||||
"It won't work without -txindex for utxo_size_inc, *fee or " | "It won't work without -txindex for utxo_size_inc, *fee or " | ||||
"*feerate stats.\n", | "*feerate stats.\n", | ||||
{ | { | ||||
{"hash_or_height", | {"hash_or_height", | ||||
RPCArg::Type::NUM, | RPCArg::Type::NUM, | ||||
/* opt */ false, | /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"The block hash or height of the target block", | "The block hash or height of the target block", | ||||
"", | "", | ||||
{"", "string or numeric"}}, | {"", "string or numeric"}}, | ||||
{"stats", | {"stats", | ||||
RPCArg::Type::ARR, | RPCArg::Type::ARR, | ||||
/* opt */ true, | /* opt */ true, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"Values to plot, by default all values (see result below)", | "Values to plot, by default all values (see result below)", | ||||
{ | { | ||||
{"height", RPCArg::Type::STR, /* opt */ true, | {"height", RPCArg::Type::STR, /* opt */ true, | ||||
/* default_val */ "", "Selected statistic"}, | /* default_val */ "", "Selected statistic"}, | ||||
{"time", RPCArg::Type::STR, /* opt */ true, | {"time", RPCArg::Type::STR, /* opt */ true, | ||||
/* default_val */ "", "Selected statistic"}, | /* default_val */ "", "Selected statistic"}, | ||||
}, | }, | ||||
"stats"}, | "stats"}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{ | ||||
"\nResult:\n" | |||||
"{ (json object)\n" | "{ (json object)\n" | ||||
" \"avgfee\": x.xxx, (numeric) Average fee in the block\n" | " \"avgfee\": x.xxx, (numeric) Average fee in the " | ||||
"block\n" | |||||
" \"avgfeerate\": x.xxx, (numeric) Average feerate (in " + | " \"avgfeerate\": x.xxx, (numeric) Average feerate (in " + | ||||
CURRENCY_UNIT + | CURRENCY_UNIT + | ||||
" per byte)\n" | " per byte)\n" | ||||
" \"avgtxsize\": xxxxx, (numeric) Average transaction size\n" | " \"avgtxsize\": xxxxx, (numeric) Average transaction " | ||||
" \"blockhash\": xxxxx, (string) The block hash (to check " | "size\n" | ||||
" \"blockhash\": xxxxx, (string) The block hash (to " | |||||
"check " | |||||
"for potential reorgs)\n" | "for potential reorgs)\n" | ||||
" \"height\": xxxxx, (numeric) The height of the block\n" | " \"height\": xxxxx, (numeric) The height of the " | ||||
"block\n" | |||||
" \"ins\": xxxxx, (numeric) The number of inputs " | " \"ins\": xxxxx, (numeric) The number of inputs " | ||||
"(excluding coinbase)\n" | "(excluding coinbase)\n" | ||||
" \"maxfee\": xxxxx, (numeric) Maximum fee in the block\n" | " \"maxfee\": xxxxx, (numeric) Maximum fee in the " | ||||
"block\n" | |||||
" \"maxfeerate\": xxxxx, (numeric) Maximum feerate (in " + | " \"maxfeerate\": xxxxx, (numeric) Maximum feerate (in " + | ||||
CURRENCY_UNIT + | CURRENCY_UNIT + | ||||
" per byte)\n" | " per byte)\n" | ||||
" \"maxtxsize\": xxxxx, (numeric) Maximum transaction size\n" | " \"maxtxsize\": xxxxx, (numeric) Maximum transaction " | ||||
" \"medianfee\": x.xxx, (numeric) Truncated median fee in " | "size\n" | ||||
" \"medianfee\": x.xxx, (numeric) Truncated median fee " | |||||
"in " | |||||
"the block\n" | "the block\n" | ||||
" \"medianfeerate\": x.xxx, (numeric) Truncated median feerate " | " \"medianfeerate\": x.xxx, (numeric) Truncated median " | ||||
"feerate " | |||||
"(in " + | "(in " + | ||||
CURRENCY_UNIT + | CURRENCY_UNIT + | ||||
" per byte)\n" | " per byte)\n" | ||||
" \"mediantime\": xxxxx, (numeric) The block median time " | " \"mediantime\": xxxxx, (numeric) The block median time " | ||||
"past\n" | "past\n" | ||||
" \"mediantxsize\": xxxxx, (numeric) Truncated median " | " \"mediantxsize\": xxxxx, (numeric) Truncated median " | ||||
"transaction size\n" | "transaction size\n" | ||||
" \"minfee\": x.xxx, (numeric) Minimum fee in the block\n" | " \"minfee\": x.xxx, (numeric) Minimum fee in the " | ||||
"block\n" | |||||
" \"minfeerate\": xx.xx, (numeric) Minimum feerate (in " + | " \"minfeerate\": xx.xx, (numeric) Minimum feerate (in " + | ||||
CURRENCY_UNIT + | CURRENCY_UNIT + | ||||
" per byte)\n" | " per byte)\n" | ||||
" \"mintxsize\": xxxxx, (numeric) Minimum transaction size\n" | " \"mintxsize\": xxxxx, (numeric) Minimum transaction " | ||||
" \"outs\": xxxxx, (numeric) The number of outputs\n" | "size\n" | ||||
" \"outs\": xxxxx, (numeric) The number of " | |||||
"outputs\n" | |||||
" \"subsidy\": x.xxx, (numeric) The block subsidy\n" | " \"subsidy\": x.xxx, (numeric) The block subsidy\n" | ||||
" \"time\": xxxxx, (numeric) The block time\n" | " \"time\": xxxxx, (numeric) The block time\n" | ||||
" \"total_out\": x.xxx, (numeric) Total amount in all " | " \"total_out\": x.xxx, (numeric) Total amount in all " | ||||
"outputs (excluding coinbase and thus reward [ie subsidy + " | "outputs (excluding coinbase and thus reward [ie subsidy + " | ||||
"totalfee])\n" | "totalfee])\n" | ||||
" \"total_size\": xxxxx, (numeric) Total size of all " | " \"total_size\": xxxxx, (numeric) Total size of all " | ||||
"non-coinbase transactions\n" | "non-coinbase transactions\n" | ||||
" \"totalfee\": x.xxx, (numeric) The fee total\n" | " \"totalfee\": x.xxx, (numeric) The fee total\n" | ||||
" \"txs\": xxxxx, (numeric) The number of " | " \"txs\": xxxxx, (numeric) The number of " | ||||
"transactions (excluding coinbase)\n" | "transactions (excluding coinbase)\n" | ||||
" \"utxo_increase\": xxxxx, (numeric) The increase/decrease in " | " \"utxo_increase\": xxxxx, (numeric) The increase/decrease " | ||||
"in " | |||||
"the number of unspent outputs\n" | "the number of unspent outputs\n" | ||||
" \"utxo_size_inc\": xxxxx, (numeric) The increase/decrease in " | " \"utxo_size_inc\": xxxxx, (numeric) The increase/decrease " | ||||
"size for the utxo index (not discounting op_return and similar)\n" | "in " | ||||
"}\n" | "size for the utxo index (not discounting op_return and " | ||||
"\nExamples:\n" + | "similar)\n" | ||||
"}\n"}, | |||||
RPCExamples{ | |||||
HelpExampleCli("getblockstats", | HelpExampleCli("getblockstats", | ||||
"1000 '[\"minfeerate\",\"avgfeerate\"]'") + | "1000 '[\"minfeerate\",\"avgfeerate\"]'") + | ||||
HelpExampleRpc("getblockstats", | HelpExampleRpc("getblockstats", | ||||
"1000 '[\"minfeerate\",\"avgfeerate\"]'")); | "1000 '[\"minfeerate\",\"avgfeerate\"]'")}, | ||||
} | |||||
.ToString()); | |||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
CBlockIndex *pindex; | CBlockIndex *pindex; | ||||
if (request.params[0].isNum()) { | if (request.params[0].isNum()) { | ||||
const int height = request.params[0].get_int(); | const int height = request.params[0].get_int(); | ||||
const int current_tip = ::ChainActive().Height(); | const int current_tip = ::ChainActive().Height(); | ||||
▲ Show 20 Lines • Show All 200 Lines • ▼ Show 20 Lines | for (const std::string &stat : stats) { | ||||
ret.pushKV(stat, value); | ret.pushKV(stat, value); | ||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
static UniValue savemempool(const Config &config, | static UniValue savemempool(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 0) { | if (request.fHelp || request.params.size() != 0) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{"savemempool", | "savemempool", | ||||
"\nDumps the mempool to disk. It will fail until the " | "\nDumps the mempool to disk. It will fail until the " | ||||
"previous dump is fully loaded.\n", | "previous dump is fully loaded.\n", | ||||
{}} | {}, | ||||
.ToString() + | RPCResults{}, | ||||
"\nExamples:\n" + HelpExampleCli("savemempool", "") + | RPCExamples{HelpExampleCli("savemempool", "") + | ||||
HelpExampleRpc("savemempool", "")); | HelpExampleRpc("savemempool", "")}, | ||||
} | |||||
.ToString()); | |||||
} | } | ||||
if (!::g_mempool.IsLoaded()) { | if (!::g_mempool.IsLoaded()) { | ||||
throw JSONRPCError(RPC_MISC_ERROR, "The mempool was not loaded yet"); | throw JSONRPCError(RPC_MISC_ERROR, "The mempool was not loaded yet"); | ||||
} | } | ||||
if (!DumpMempool(::g_mempool)) { | if (!DumpMempool(::g_mempool)) { | ||||
throw JSONRPCError(RPC_MISC_ERROR, "Unable to dump mempool to disk"); | throw JSONRPCError(RPC_MISC_ERROR, "Unable to dump mempool to disk"); | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | ~CoinsViewScanReserver() { | ||||
} | } | ||||
} | } | ||||
}; | }; | ||||
static UniValue scantxoutset(const Config &config, | static UniValue scantxoutset(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() < 1 || | if (request.fHelp || request.params.size() < 1 || | ||||
request.params.size() > 2) { | request.params.size() > 2) { | ||||
throw std::runtime_error( | throw std::runtime_error(RPCHelpMan{ | ||||
RPCHelpMan{ | |||||
"scantxoutset", | "scantxoutset", | ||||
"\nEXPERIMENTAL warning: this call may be removed or changed " | "\nEXPERIMENTAL warning: this call may be removed or changed " | ||||
"in future releases.\n" | "in future releases.\n" | ||||
"\nScans the unspent transaction output set for entries that " | "\nScans the unspent transaction output set for entries that " | ||||
"match certain output descriptors.\n" | "match certain output descriptors.\n" | ||||
"Examples of output descriptors are:\n" | "Examples of output descriptors are:\n" | ||||
" addr(<address>) Outputs whose " | " addr(<address>) Outputs whose " | ||||
"scriptPubKey corresponds to the specified address does not " | "scriptPubKey corresponds to the specified address does not " | ||||
"include P2PK)\n" | "include P2PK)\n" | ||||
" raw(<hex script>) Outputs whose " | " raw(<hex script>) Outputs whose " | ||||
"scriptPubKey equals the specified hex scripts\n" | "scriptPubKey equals the specified hex scripts\n" | ||||
" combo(<pubkey>) P2PK and P2PKH " | " combo(<pubkey>) P2PK and P2PKH " | ||||
"outputs for the given pubkey\n" | "outputs for the given pubkey\n" | ||||
" pkh(<pubkey>) P2PKH outputs for " | " pkh(<pubkey>) P2PKH outputs for " | ||||
"the given pubkey\n" | "the given pubkey\n" | ||||
" sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig " | " sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig " | ||||
"outputs for the given threshold and pubkeys\n" | "outputs for the given threshold and pubkeys\n" | ||||
"\nIn the above, <pubkey> either refers to a fixed public key " | "\nIn the above, <pubkey> either refers to a fixed public key " | ||||
"in hexadecimal notation, or to an xpub/xprv optionally " | "in hexadecimal notation, or to an xpub/xprv optionally " | ||||
"followed by one\n" | "followed by one\n" | ||||
"or more path elements separated by \"/\", and optionally " | "or more path elements separated by \"/\", and optionally " | ||||
"ending in \"/*\" (unhardened), or \"/*'\" or \"/*h\" " | "ending in \"/*\" (unhardened), or \"/*'\" or \"/*h\" " | ||||
"(hardened) to specify all\n" | "(hardened) to specify all\n" | ||||
"unhardened or hardened child keys.\n" | "unhardened or hardened child keys.\n" | ||||
"In the latter case, a range needs to be specified by below if " | "In the latter case, a range needs to be specified by below if " | ||||
"different from 1000.\n" | "different from 1000.\n" | ||||
"For more information on output descriptors, see the " | "For more information on output descriptors, see the " | ||||
"documentation in the doc/descriptors.md file.\n", | "documentation in the doc/descriptors.md file.\n", | ||||
{ | { | ||||
{"action", RPCArg::Type::STR, /* opt */ false, | {"action", RPCArg::Type::STR, /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"The action to execute\n" | "The action to execute\n" | ||||
" \"start\" for " | " \"start\" for " | ||||
"starting a scan\n" | "starting a scan\n" | ||||
" \"abort\" for " | " \"abort\" for " | ||||
"aborting the current scan (returns true when abort was " | "aborting the current scan (returns true when abort was " | ||||
"successful)\n" | "successful)\n" | ||||
" \"status\" for " | " \"status\" for " | ||||
"progress report (in %) of the current scan"}, | "progress report (in %) of the current scan"}, | ||||
{"scanobjects", | {"scanobjects", | ||||
RPCArg::Type::ARR, | RPCArg::Type::ARR, | ||||
/* opt */ false, | /* opt */ false, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"Array of scan objects\n" | "Array of scan objects\n" | ||||
" Every scan object is " | " Every scan object is " | ||||
"either a string descriptor or an object:", | "either a string descriptor or an object:", | ||||
{ | { | ||||
{"descriptor", RPCArg::Type::STR, /* opt */ true, | {"descriptor", RPCArg::Type::STR, /* opt */ true, | ||||
/* default_val */ "", "An output descriptor"}, | /* default_val */ "", "An output descriptor"}, | ||||
{ | { | ||||
"", | "", | ||||
RPCArg::Type::OBJ, | RPCArg::Type::OBJ, | ||||
/* opt */ true, | /* opt */ true, | ||||
/* default_val */ "", | /* default_val */ "", | ||||
"An object with output descriptor and metadata", | "An object with output descriptor and metadata", | ||||
{ | { | ||||
{"desc", RPCArg::Type::STR, /* opt */ false, | {"desc", RPCArg::Type::STR, /* opt */ false, | ||||
/* default_val */ "", "An output descriptor"}, | /* default_val */ "", "An output descriptor"}, | ||||
{"range", RPCArg::Type::NUM, /* opt */ true, | {"range", RPCArg::Type::NUM, /* opt */ true, | ||||
/* default_val */ "1000", | /* default_val */ "1000", | ||||
"Up to what child index HD chains should be " | "Up to what child index HD chains should be " | ||||
"explored"}, | "explored"}, | ||||
}, | }, | ||||
}, | }, | ||||
}, | }, | ||||
"[scanobjects,...]"}, | "[scanobjects,...]"}, | ||||
}} | }, | ||||
.ToString() + | RPCResult{ | ||||
"\nResult:\n" | |||||
"{\n" | "{\n" | ||||
" \"unspents\": [\n" | " \"unspents\": [\n" | ||||
" {\n" | " {\n" | ||||
" \"txid\" : \"transactionid\", (string) The transaction " | " \"txid\" : \"transactionid\", (string) The " | ||||
"transaction " | |||||
"id\n" | "id\n" | ||||
" \"vout\": n, (numeric) the vout value\n" | " \"vout\": n, (numeric) the vout value\n" | ||||
" \"scriptPubKey\" : \"script\", (string) the script key\n" | " \"scriptPubKey\" : \"script\", (string) the script " | ||||
" \"amount\" : x.xxx, (numeric) The total amount " | "key\n" | ||||
" \"amount\" : x.xxx, (numeric) The total " | |||||
"amount " | |||||
"in " + | "in " + | ||||
CURRENCY_UNIT + | CURRENCY_UNIT + | ||||
" of the unspent output\n" | " of the unspent output\n" | ||||
" \"height\" : n, (numeric) Height of the " | " \"height\" : n, (numeric) Height of the " | ||||
"unspent transaction output\n" | "unspent transaction output\n" | ||||
" }\n" | " }\n" | ||||
" ,...], \n" | " ,...], \n" | ||||
" \"total_amount\" : x.xxx, (numeric) The total amount of " | " \"total_amount\" : x.xxx, (numeric) The total " | ||||
"amount of " | |||||
"all found unspent outputs in " + | "all found unspent outputs in " + | ||||
CURRENCY_UNIT + | CURRENCY_UNIT + | ||||
"\n" | "\n" | ||||
"]\n"); | "]\n"}, | ||||
RPCExamples{""}, | |||||
} | |||||
.ToString()); | |||||
} | } | ||||
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR}); | RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR}); | ||||
UniValue result(UniValue::VOBJ); | UniValue result(UniValue::VOBJ); | ||||
if (request.params[0].get_str() == "status") { | if (request.params[0].get_str() == "status") { | ||||
CoinsViewScanReserver reserver; | CoinsViewScanReserver reserver; | ||||
if (reserver.reserve()) { | if (reserver.reserve()) { | ||||
▲ Show 20 Lines • Show All 166 Lines • Show Last 20 Lines |