Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/mining.cpp
Show First 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | static UniValue GetNetworkHashPS(int lookup, int height) { | ||||
arith_uint256 workDiff = pb->nChainWork - pb0->nChainWork; | arith_uint256 workDiff = pb->nChainWork - pb0->nChainWork; | ||||
int64_t timeDiff = maxTime - minTime; | int64_t timeDiff = maxTime - minTime; | ||||
return workDiff.getdouble() / timeDiff; | return workDiff.getdouble() / timeDiff; | ||||
} | } | ||||
static UniValue getnetworkhashps(const Config &config, | static UniValue getnetworkhashps(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() > 2) { | RPCHelpMan{ | ||||
throw std::runtime_error(RPCHelpMan{ | |||||
"getnetworkhashps", | "getnetworkhashps", | ||||
"\nReturns the estimated network hashes per second " | "\nReturns the estimated network hashes per second based on the last n " | ||||
"based on the last n blocks.\n" | "blocks.\n" | ||||
"Pass in [blocks] to override # of blocks, -1 specifies " | "Pass in [blocks] to override # of blocks, -1 specifies since last " | ||||
"since last difficulty change.\n" | "difficulty change.\n" | ||||
"Pass in [height] to estimate the network speed at the " | "Pass in [height] to estimate the network speed at the time when a " | ||||
"time when a certain block was found.\n", | "certain block was found.\n", | ||||
{ | { | ||||
{"nblocks", RPCArg::Type::NUM, /* default */ "120", | {"nblocks", RPCArg::Type::NUM, /* default */ "120", | ||||
"The number of blocks, or -1 for blocks since last " | "The number of blocks, or -1 for blocks since last difficulty " | ||||
"difficulty change."}, | "change."}, | ||||
{"height", RPCArg::Type::NUM, /* default */ "-1", | {"height", RPCArg::Type::NUM, /* default */ "-1", | ||||
"To estimate at the time of the given height."}, | "To estimate at the time of the given height."}, | ||||
}, | }, | ||||
RPCResult{"x (numeric) Hashes per second estimated\n"}, | RPCResult{"x (numeric) Hashes per second estimated\n"}, | ||||
RPCExamples{HelpExampleCli("getnetworkhashps", "") + | RPCExamples{HelpExampleCli("getnetworkhashps", "") + | ||||
HelpExampleRpc("getnetworkhashps", "")}, | HelpExampleRpc("getnetworkhashps", "")}, | ||||
} | } | ||||
.ToString()); | .Check(request); | ||||
} | |||||
LOCK(cs_main); | LOCK(cs_main); | ||||
return GetNetworkHashPS( | return GetNetworkHashPS( | ||||
!request.params[0].isNull() ? request.params[0].get_int() : 120, | !request.params[0].isNull() ? request.params[0].get_int() : 120, | ||||
!request.params[1].isNull() ? request.params[1].get_int() : -1); | !request.params[1].isNull() ? request.params[1].get_int() : -1); | ||||
} | } | ||||
UniValue generateBlocks(const Config &config, | UniValue generateBlocks(const Config &config, | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | while (nHeight < nHeightEnd && !ShutdownRequested()) { | ||||
} | } | ||||
} | } | ||||
return blockHashes; | return blockHashes; | ||||
} | } | ||||
static UniValue generatetoaddress(const Config &config, | static UniValue generatetoaddress(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() < 2 || | RPCHelpMan{ | ||||
request.params.size() > 3) { | |||||
throw std::runtime_error(RPCHelpMan{ | |||||
"generatetoaddress", | "generatetoaddress", | ||||
"\nMine blocks immediately to a specified address before the " | "\nMine blocks immediately to a specified address before the " | ||||
"RPC call returns)\n", | "RPC call returns)\n", | ||||
{ | { | ||||
{"nblocks", RPCArg::Type::NUM, RPCArg::Optional::NO, | {"nblocks", RPCArg::Type::NUM, RPCArg::Optional::NO, | ||||
"How many blocks are generated immediately."}, | "How many blocks are generated immediately."}, | ||||
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, | {"address", RPCArg::Type::STR, RPCArg::Optional::NO, | ||||
"The address to send the newly generated bitcoin to."}, | "The address to send the newly generated bitcoin to."}, | ||||
{"maxtries", RPCArg::Type::NUM, /* default */ "1000000", | {"maxtries", RPCArg::Type::NUM, /* default */ "1000000", | ||||
"How many iterations to try."}, | "How many iterations to try."}, | ||||
}, | }, | ||||
RPCResult{ | RPCResult{"[ blockhashes ] (array) hashes of blocks generated\n"}, | ||||
"[ blockhashes ] (array) hashes of blocks generated\n"}, | |||||
RPCExamples{ | RPCExamples{ | ||||
"\nGenerate 11 blocks to myaddress\n" + | "\nGenerate 11 blocks to myaddress\n" + | ||||
HelpExampleCli("generatetoaddress", "11 \"myaddress\"") + | HelpExampleCli("generatetoaddress", "11 \"myaddress\"") + | ||||
"If you are running the bitcoin core wallet, you can get a new " | "If you are running the bitcoin core wallet, you can get a new " | ||||
"address to send the newly generated bitcoin to with:\n" + | "address to send the newly generated bitcoin to with:\n" + | ||||
HelpExampleCli("getnewaddress", "")}, | HelpExampleCli("getnewaddress", "")}, | ||||
} | } | ||||
.ToString()); | .Check(request); | ||||
} | |||||
int nGenerate = request.params[0].get_int(); | int nGenerate = request.params[0].get_int(); | ||||
uint64_t nMaxTries = 1000000; | uint64_t nMaxTries = 1000000; | ||||
if (!request.params[2].isNull()) { | if (!request.params[2].isNull()) { | ||||
nMaxTries = request.params[2].get_int(); | nMaxTries = request.params[2].get_int(); | ||||
} | } | ||||
CTxDestination destination = | CTxDestination destination = | ||||
DecodeDestination(request.params[1].get_str(), config.GetChainParams()); | DecodeDestination(request.params[1].get_str(), config.GetChainParams()); | ||||
if (!IsValidDestination(destination)) { | if (!IsValidDestination(destination)) { | ||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | ||||
"Error: Invalid address"); | "Error: Invalid address"); | ||||
} | } | ||||
std::shared_ptr<CReserveScript> coinbaseScript = | std::shared_ptr<CReserveScript> coinbaseScript = | ||||
std::make_shared<CReserveScript>(); | std::make_shared<CReserveScript>(); | ||||
coinbaseScript->reserveScript = GetScriptForDestination(destination); | coinbaseScript->reserveScript = GetScriptForDestination(destination); | ||||
return generateBlocks(config, coinbaseScript, nGenerate, nMaxTries, false); | return generateBlocks(config, coinbaseScript, nGenerate, nMaxTries, false); | ||||
} | } | ||||
static UniValue getmininginfo(const Config &config, | static UniValue getmininginfo(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 0) { | RPCHelpMan{ | ||||
throw std::runtime_error(RPCHelpMan{ | |||||
"getmininginfo", | "getmininginfo", | ||||
"\nReturns a json object containing mining-related " | "\nReturns a json object containing mining-related " | ||||
"information.", | "information.", | ||||
{}, | {}, | ||||
RPCResult{ | RPCResult{ | ||||
"{\n" | "{\n" | ||||
" \"blocks\": nnn, (numeric) The current block\n" | " \"blocks\": nnn, (numeric) The current block\n" | ||||
" \"currentblocksize\": nnn, (numeric, optional) The block " | " \"currentblocksize\": nnn, (numeric, optional) The block size " | ||||
"size of the last assembled block (only present if a block was " | "of the last assembled block (only present if a block was ever " | ||||
"ever assembled)\n" | "assembled)\n" | ||||
" \"currentblocktx\": nnn, (numeric, optional) The number " | " \"currentblocktx\": nnn, (numeric, optional) The number of " | ||||
"of block transactions of the last assembled block (only " | "block transactions of the last assembled block (only present if a " | ||||
"present if a block was ever assembled)\n" | "block was ever assembled)\n" | ||||
" \"difficulty\": xxx.xxxxx (numeric) The current " | " \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n" | ||||
"difficulty\n" | " \"networkhashps\": nnn, (numeric) The network hashes per " | ||||
" \"networkhashps\": nnn, (numeric) The network hashes " | "second\n" | ||||
"per second\n" | " \"pooledtx\": n (numeric) The size of the mempool\n" | ||||
" \"pooledtx\": n (numeric) The size of the " | " \"chain\": \"xxxx\", (string) current network name as " | ||||
"mempool\n" | "defined in BIP70 (main, test, regtest)\n" | ||||
" \"chain\": \"xxxx\", (string) current network " | |||||
"name as defined in BIP70 (main, test, regtest)\n" | |||||
" \"warnings\": \"...\" (string) any network and " | " \"warnings\": \"...\" (string) any network and " | ||||
"blockchain warnings\n" | "blockchain warnings\n" | ||||
"}\n"}, | "}\n"}, | ||||
RPCExamples{HelpExampleCli("getmininginfo", "") + | RPCExamples{HelpExampleCli("getmininginfo", "") + | ||||
HelpExampleRpc("getmininginfo", "")}, | HelpExampleRpc("getmininginfo", "")}, | ||||
} | } | ||||
.ToString()); | .Check(request); | ||||
} | |||||
LOCK(cs_main); | LOCK(cs_main); | ||||
UniValue obj(UniValue::VOBJ); | UniValue obj(UniValue::VOBJ); | ||||
obj.pushKV("blocks", int(::ChainActive().Height())); | obj.pushKV("blocks", int(::ChainActive().Height())); | ||||
if (BlockAssembler::m_last_block_size) { | if (BlockAssembler::m_last_block_size) { | ||||
obj.pushKV("currentblocksize", *BlockAssembler::m_last_block_size); | obj.pushKV("currentblocksize", *BlockAssembler::m_last_block_size); | ||||
} | } | ||||
if (BlockAssembler::m_last_block_num_txs) { | if (BlockAssembler::m_last_block_num_txs) { | ||||
obj.pushKV("currentblocktx", *BlockAssembler::m_last_block_num_txs); | obj.pushKV("currentblocktx", *BlockAssembler::m_last_block_num_txs); | ||||
} | } | ||||
obj.pushKV("difficulty", double(GetDifficulty(::ChainActive().Tip()))); | obj.pushKV("difficulty", double(GetDifficulty(::ChainActive().Tip()))); | ||||
obj.pushKV("networkhashps", getnetworkhashps(config, request)); | obj.pushKV("networkhashps", getnetworkhashps(config, request)); | ||||
obj.pushKV("pooledtx", uint64_t(g_mempool.size())); | obj.pushKV("pooledtx", uint64_t(g_mempool.size())); | ||||
obj.pushKV("chain", config.GetChainParams().NetworkIDString()); | obj.pushKV("chain", config.GetChainParams().NetworkIDString()); | ||||
obj.pushKV("warnings", GetWarnings("statusbar")); | obj.pushKV("warnings", GetWarnings("statusbar")); | ||||
return obj; | return obj; | ||||
} | } | ||||
// NOTE: Unlike wallet RPC (which use BCH values), mining RPCs follow GBT (BIP | // NOTE: Unlike wallet RPC (which use BCH values), mining RPCs follow GBT (BIP | ||||
// 22) in using satoshi amounts | // 22) in using satoshi amounts | ||||
static UniValue prioritisetransaction(const Config &config, | static UniValue prioritisetransaction(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 3) { | RPCHelpMan{ | ||||
throw std::runtime_error(RPCHelpMan{ | |||||
"prioritisetransaction", | "prioritisetransaction", | ||||
"Accepts the transaction into mined blocks at a higher " | "Accepts the transaction into mined blocks at a higher " | ||||
"(or lower) priority\n", | "(or lower) priority\n", | ||||
{ | { | ||||
{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | ||||
"The transaction id."}, | "The transaction id."}, | ||||
{"dummy", RPCArg::Type::NUM, | {"dummy", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, | ||||
RPCArg::Optional::OMITTED_NAMED_ARG, | "API-Compatibility for previous API. Must be zero or null.\n" | ||||
"API-Compatibility for previous API. Must be zero or " | |||||
"null.\n" | |||||
" DEPRECATED. For forward compatibility " | " DEPRECATED. For forward compatibility " | ||||
"use named arguments and omit this parameter."}, | "use named arguments and omit this parameter."}, | ||||
{"fee_delta", RPCArg::Type::NUM, RPCArg::Optional::NO, | {"fee_delta", RPCArg::Type::NUM, RPCArg::Optional::NO, | ||||
"The fee value (in satoshis) to add (or subtract, if " | "The fee value (in satoshis) to add (or subtract, if negative).\n" | ||||
"negative).\n" | " The fee is not actually paid, only the " | ||||
" The fee is not actually paid, " | "algorithm for selecting transactions into a block\n" | ||||
"only the algorithm for selecting transactions into a " | |||||
"block\n" | |||||
" considers the transaction as it would " | " considers the transaction as it would " | ||||
"have paid a higher (or lower) fee."}, | "have paid a higher (or lower) fee."}, | ||||
}, | }, | ||||
RPCResult{"true (boolean) Returns true\n"}, | RPCResult{"true (boolean) Returns true\n"}, | ||||
RPCExamples{ | RPCExamples{ | ||||
HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 10000") + | HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 10000") + | ||||
HelpExampleRpc("prioritisetransaction", | HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000")}, | ||||
"\"txid\", 0.0, 10000")}, | |||||
} | |||||
.ToString()); | |||||
} | } | ||||
.Check(request); | |||||
LOCK(cs_main); | LOCK(cs_main); | ||||
TxId txid(ParseHashV(request.params[0], "txid")); | TxId txid(ParseHashV(request.params[0], "txid")); | ||||
Amount nAmount = request.params[2].get_int64() * SATOSHI; | Amount nAmount = request.params[2].get_int64() * SATOSHI; | ||||
if (!(request.params[1].isNull() || request.params[1].get_real() == 0)) { | if (!(request.params[1].isNull() || request.params[1].get_real() == 0)) { | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, | throw JSONRPCError(RPC_INVALID_PARAMETER, | ||||
Show All 26 Lines | static UniValue BIP22ValidationResult(const Config &config, | ||||
} | } | ||||
// Should be impossible. | // Should be impossible. | ||||
return "valid?"; | return "valid?"; | ||||
} | } | ||||
static UniValue getblocktemplate(const Config &config, | static UniValue getblocktemplate(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() > 1) { | RPCHelpMan{ | ||||
throw std::runtime_error(RPCHelpMan{ | |||||
"getblocktemplate", | "getblocktemplate", | ||||
"\nIf the request parameters include a 'mode' key, that is " | "\nIf the request parameters include a 'mode' key, that is used to " | ||||
"used to explicitly select between the default 'template' " | "explicitly select between the default 'template' request or a " | ||||
"request or a 'proposal'.\n" | "'proposal'.\n" | ||||
"It returns data needed to construct a block to work on.\n" | "It returns data needed to construct a block to work on.\n" | ||||
"For full specification, see BIPs 22, 23, 9, and 145:\n" | "For full specification, see BIPs 22, 23, 9, and 145:\n" | ||||
" " | " " | ||||
"https://github.com/bitcoin/bips/blob/master/" | "https://github.com/bitcoin/bips/blob/master/" | ||||
"bip-0022.mediawiki\n" | "bip-0022.mediawiki\n" | ||||
" " | " " | ||||
"https://github.com/bitcoin/bips/blob/master/" | "https://github.com/bitcoin/bips/blob/master/" | ||||
"bip-0023.mediawiki\n" | "bip-0023.mediawiki\n" | ||||
" " | " " | ||||
"https://github.com/bitcoin/bips/blob/master/" | "https://github.com/bitcoin/bips/blob/master/" | ||||
"bip-0009.mediawiki#getblocktemplate_changes\n" | "bip-0009.mediawiki#getblocktemplate_changes\n" | ||||
" ", | " ", | ||||
{ | { | ||||
{"template_request", | {"template_request", | ||||
RPCArg::Type::OBJ, | RPCArg::Type::OBJ, | ||||
"{}", | "{}", | ||||
"A json object in the following spec", | "A json object in the following spec", | ||||
{ | { | ||||
{"mode", RPCArg::Type::STR, /* treat as named arg */ | {"mode", RPCArg::Type::STR, /* treat as named arg */ | ||||
RPCArg::Optional::OMITTED_NAMED_ARG, | RPCArg::Optional::OMITTED_NAMED_ARG, | ||||
"This must be set to \"template\", \"proposal\" (see " | "This must be set to \"template\", \"proposal\" (see BIP " | ||||
"BIP 23), or omitted"}, | "23), or omitted"}, | ||||
{ | { | ||||
"capabilities", | "capabilities", | ||||
RPCArg::Type::ARR, | RPCArg::Type::ARR, | ||||
/* treat as named arg */ | /* treat as named arg */ | ||||
RPCArg::Optional::OMITTED_NAMED_ARG, | RPCArg::Optional::OMITTED_NAMED_ARG, | ||||
"A list of strings", | "A list of strings", | ||||
{ | { | ||||
{"support", RPCArg::Type::STR, | {"support", RPCArg::Type::STR, | ||||
RPCArg::Optional::OMITTED, | RPCArg::Optional::OMITTED, | ||||
"client side supported feature, 'longpoll', " | "client side supported feature, 'longpoll', " | ||||
"'coinbasetxn', 'coinbasevalue', 'proposal', " | "'coinbasetxn', 'coinbasevalue', 'proposal', " | ||||
"'serverlist', 'workid'"}, | "'serverlist', 'workid'"}, | ||||
}, | }, | ||||
}, | }, | ||||
}, | }, | ||||
"\"template_request\""}, | "\"template_request\""}, | ||||
}, | }, | ||||
RPCResult{ | RPCResult{ | ||||
"{\n" | "{\n" | ||||
" \"version\" : n, (numeric) The preferred " | " \"version\" : n, (numeric) The preferred " | ||||
"block version\n" | "block version\n" | ||||
" \"previousblockhash\" : \"xxxx\", (string) The hash of " | " \"previousblockhash\" : \"xxxx\", (string) The hash of " | ||||
"current highest block\n" | "current highest block\n" | ||||
" \"transactions\" : [ (array) contents of " | " \"transactions\" : [ (array) contents of " | ||||
"non-coinbase transactions that should be included in the next " | "non-coinbase transactions that should be included in the next " | ||||
"block\n" | "block\n" | ||||
" {\n" | " {\n" | ||||
" \"data\" : \"xxxx\", (string) " | " \"data\" : \"xxxx\", (string) transaction " | ||||
"transaction data encoded in hexadecimal (byte-for-byte)\n" | "data encoded in hexadecimal (byte-for-byte)\n" | ||||
" \"txid\" : \"xxxx\", (string) " | " \"txid\" : \"xxxx\", (string) transaction id " | ||||
"transaction id encoded in little-endian hexadecimal\n" | "encoded in little-endian hexadecimal\n" | ||||
" \"hash\" : \"xxxx\", (string) hash " | " \"hash\" : \"xxxx\", (string) hash encoded " | ||||
"encoded in little-endian hexadecimal (including witness " | "in little-endian hexadecimal\n" | ||||
"data)\n" | " \"depends\" : [ (array) array of numbers " | ||||
" \"depends\" : [ (array) array of " | "\n" | ||||
"numbers \n" | " n (numeric) transactions " | ||||
" n (numeric) " | "before this one (by 1-based index in 'transactions' list) that " | ||||
"transactions before this one (by 1-based index in " | "must be present in the final block if this one is\n" | ||||
"'transactions' list) that must be present in the final block " | |||||
"if this one is\n" | |||||
" ,...\n" | " ,...\n" | ||||
" ],\n" | " ],\n" | ||||
" \"fee\": n, (numeric) difference " | " \"fee\": n, (numeric) difference in " | ||||
"in value between transaction inputs and outputs (in " | "value between transaction inputs and outputs (in satoshis); for " | ||||
"satoshis); for coinbase transactions, this is a negative " | "coinbase transactions, this is a negative number of the total " | ||||
"Number of the total collected block fees (ie, not including " | "collected block fees (ie, not including the block subsidy); if " | ||||
"the block subsidy); if key is not present, fee is unknown and " | "key is not present, fee is unknown and clients MUST NOT assume " | ||||
"clients MUST NOT assume there isn't one\n" | "there isn't one\n" | ||||
" \"sigops\" : n, (numeric) total " | " \"sigops\" : n, (numeric) total SigOps " | ||||
"SigOps count, as counted for purposes of block limits; if key " | "count, as counted for purposes of block limits; if key is not " | ||||
"is not present, sigop count is unknown and clients MUST NOT " | "present, sigop count is unknown and clients MUST NOT assume it is " | ||||
"assume it is zero\n" | "zero\n" | ||||
" }\n" | " }\n" | ||||
" ,...\n" | " ,...\n" | ||||
" ],\n" | " ],\n" | ||||
" \"coinbaseaux\" : { (json object) data that " | " \"coinbaseaux\" : { (json object) data that " | ||||
"should be included in the coinbase's scriptSig content\n" | "should be included in the coinbase's scriptSig content\n" | ||||
" \"flags\" : \"xx\" (string) key name " | " \"flags\" : \"xx\" (string) key name is to " | ||||
"is to be ignored, and value included in scriptSig\n" | "be ignored, and value included in scriptSig\n" | ||||
" },\n" | " },\n" | ||||
" \"coinbasevalue\" : n, (numeric) maximum " | " \"coinbasevalue\" : n, (numeric) maximum allowable " | ||||
"allowable input to coinbase transaction, including the " | "input to coinbase transaction, including the generation award and " | ||||
"generation award and transaction fees (in satoshis)\n" | "transaction fees (in satoshis)\n" | ||||
" \"coinbasetxn\" : { ... }, (json object) " | " \"coinbasetxn\" : { ... }, (json object) information " | ||||
"information for coinbase transaction\n" | "for coinbase transaction\n" | ||||
" \"target\" : \"xxxx\", (string) The hash " | " \"target\" : \"xxxx\", (string) The hash target\n" | ||||
"target\n" | |||||
" \"mintime\" : xxx, (numeric) The minimum " | " \"mintime\" : xxx, (numeric) The minimum " | ||||
"timestamp appropriate for next block time in seconds since " | "timestamp appropriate for next block time in seconds since epoch " | ||||
"epoch (Jan 1 1970 GMT)\n" | "(Jan 1 1970 GMT)\n" | ||||
" \"mutable\" : [ (array of string) list " | " \"mutable\" : [ (array of string) list of " | ||||
"of ways the block template may be changed \n" | "ways the block template may be changed \n" | ||||
" \"value\" (string) A way the " | " \"value\" (string) A way the block " | ||||
"block template may be changed, e.g. 'time', 'transactions', " | "template may be changed, e.g. 'time', 'transactions', " | ||||
"'prevblock'\n" | "'prevblock'\n" | ||||
" ,...\n" | " ,...\n" | ||||
" ],\n" | " ],\n" | ||||
" \"noncerange\" : \"00000000ffffffff\",(string) A range of " | " \"noncerange\" : \"00000000ffffffff\",(string) A range of valid " | ||||
"valid nonces\n" | "nonces\n" | ||||
" \"sigoplimit\" : n, (numeric) limit of " | " \"sigoplimit\" : n, (numeric) limit of sigops " | ||||
"sigops in blocks\n" | "in blocks\n" | ||||
" \"sizelimit\" : n, (numeric) limit of " | " \"sizelimit\" : n, (numeric) limit of block " | ||||
"block size\n" | "size\n" | ||||
" \"curtime\" : ttt, (numeric) current " | " \"curtime\" : ttt, (numeric) current timestamp " | ||||
"timestamp in seconds since epoch (Jan 1 1970 GMT)\n" | "in seconds since epoch (Jan 1 1970 GMT)\n" | ||||
" \"bits\" : \"xxxxxxxx\", (string) compressed " | " \"bits\" : \"xxxxxxxx\", (string) compressed " | ||||
"target of next block\n" | "target of next block\n" | ||||
" \"height\" : n (numeric) The height of " | " \"height\" : n (numeric) The height of the " | ||||
"the next block\n" | "next block\n" | ||||
"}\n"}, | "}\n"}, | ||||
RPCExamples{HelpExampleCli("getblocktemplate", "") + | RPCExamples{HelpExampleCli("getblocktemplate", "") + | ||||
HelpExampleRpc("getblocktemplate", "")}, | HelpExampleRpc("getblocktemplate", "")}, | ||||
} | } | ||||
.ToString()); | .Check(request); | ||||
} | |||||
LOCK(cs_main); | LOCK(cs_main); | ||||
std::string strMode = "template"; | std::string strMode = "template"; | ||||
UniValue lpval = NullUniValue; | UniValue lpval = NullUniValue; | ||||
std::set<std::string> setClientRules; | std::set<std::string> setClientRules; | ||||
if (!request.params[0].isNull()) { | if (!request.params[0].isNull()) { | ||||
const UniValue &oparam = request.params[0].get_obj(); | const UniValue &oparam = request.params[0].get_obj(); | ||||
▲ Show 20 Lines • Show All 237 Lines • ▼ Show 20 Lines | void BlockChecked(const CBlock &block, | ||||
found = true; | found = true; | ||||
state = stateIn; | state = stateIn; | ||||
} | } | ||||
}; | }; | ||||
static UniValue submitblock(const Config &config, | static UniValue submitblock(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
// We allow 2 arguments for compliance with BIP22. Argument 2 is ignored. | // We allow 2 arguments for compliance with BIP22. Argument 2 is ignored. | ||||
if (request.fHelp || request.params.size() < 1 || | RPCHelpMan{ | ||||
request.params.size() > 2) { | |||||
throw std::runtime_error(RPCHelpMan{ | |||||
"submitblock", | "submitblock", | ||||
"\nAttempts to submit new block to network.\n" | "\nAttempts to submit new block to network.\n" | ||||
"See https://en.bitcoin.it/wiki/BIP_0022 for full " | "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n", | ||||
"specification.\n", | |||||
{ | { | ||||
{"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | {"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | ||||
"the hex-encoded block data to submit"}, | "the hex-encoded block data to submit"}, | ||||
{"dummy", RPCArg::Type::STR, /* default */ "ignored", | {"dummy", RPCArg::Type::STR, /* default */ "ignored", | ||||
"dummy value, for compatibility with BIP22. This value is " | "dummy value, for compatibility with BIP22. This value is " | ||||
"ignored."}, | "ignored."}, | ||||
}, | }, | ||||
RPCResults{}, | RPCResults{}, | ||||
RPCExamples{HelpExampleCli("submitblock", "\"mydata\"") + | RPCExamples{HelpExampleCli("submitblock", "\"mydata\"") + | ||||
HelpExampleRpc("submitblock", "\"mydata\"")}, | HelpExampleRpc("submitblock", "\"mydata\"")}, | ||||
} | } | ||||
.ToString()); | .Check(request); | ||||
} | |||||
std::shared_ptr<CBlock> blockptr = std::make_shared<CBlock>(); | std::shared_ptr<CBlock> blockptr = std::make_shared<CBlock>(); | ||||
CBlock &block = *blockptr; | CBlock &block = *blockptr; | ||||
if (!DecodeHexBlk(block, request.params[0].get_str())) { | if (!DecodeHexBlk(block, request.params[0].get_str())) { | ||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); | ||||
} | } | ||||
if (block.vtx.empty() || !block.vtx[0]->IsCoinBase()) { | if (block.vtx.empty() || !block.vtx[0]->IsCoinBase()) { | ||||
Show All 35 Lines | if (!sc.found) { | ||||
return "inconclusive"; | return "inconclusive"; | ||||
} | } | ||||
return BIP22ValidationResult(config, sc.state); | return BIP22ValidationResult(config, sc.state); | ||||
} | } | ||||
static UniValue submitheader(const Config &config, | static UniValue submitheader(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() != 1) { | RPCHelpMan{ | ||||
throw std::runtime_error(RPCHelpMan{ | |||||
"submitheader", | "submitheader", | ||||
"\nDecode the given hexdata as a header and submit it as a " | "\nDecode the given hexdata as a header and submit it as a candidate " | ||||
"candidate chain tip if valid." | "chain tip if valid." | ||||
"\nThrows when the header is invalid.\n", | "\nThrows when the header is invalid.\n", | ||||
{ | { | ||||
{"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | {"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | ||||
"the hex-encoded block header data"}, | "the hex-encoded block header data"}, | ||||
}, | }, | ||||
RPCResult{"None"}, | RPCResult{"None"}, | ||||
RPCExamples{HelpExampleCli("submitheader", "\"aabbcc\"") + | RPCExamples{HelpExampleCli("submitheader", "\"aabbcc\"") + | ||||
HelpExampleRpc("submitheader", "\"aabbcc\"")}, | HelpExampleRpc("submitheader", "\"aabbcc\"")}, | ||||
} | } | ||||
.ToString()); | .Check(request); | ||||
} | |||||
CBlockHeader h; | CBlockHeader h; | ||||
if (!DecodeHexBlockHeader(h, request.params[0].get_str())) { | if (!DecodeHexBlockHeader(h, request.params[0].get_str())) { | ||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, | ||||
"Block header decode failed"); | "Block header decode failed"); | ||||
} | } | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
Show All 13 Lines | static UniValue submitheader(const Config &config, | ||||
if (state.IsError()) { | if (state.IsError()) { | ||||
throw JSONRPCError(RPC_VERIFY_ERROR, FormatStateMessage(state)); | throw JSONRPCError(RPC_VERIFY_ERROR, FormatStateMessage(state)); | ||||
} | } | ||||
throw JSONRPCError(RPC_VERIFY_ERROR, state.GetRejectReason()); | throw JSONRPCError(RPC_VERIFY_ERROR, state.GetRejectReason()); | ||||
} | } | ||||
static UniValue estimatefee(const Config &config, | static UniValue estimatefee(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
if (request.fHelp || request.params.size() > 0) { | RPCHelpMan{ | ||||
throw std::runtime_error(RPCHelpMan{ | |||||
"estimatefee", | "estimatefee", | ||||
"\nEstimates the approximate fee per kilobyte needed " | "\nEstimates the approximate fee per kilobyte needed for a " | ||||
"for a transaction\n", | "transaction\n", | ||||
{}, | {}, | ||||
RPCResult{"n (numeric) estimated fee-per-kilobyte\n"}, | RPCResult{"n (numeric) estimated fee-per-kilobyte\n"}, | ||||
RPCExamples{HelpExampleCli("estimatefee", "")}, | RPCExamples{HelpExampleCli("estimatefee", "")}, | ||||
} | } | ||||
.ToString()); | .Check(request); | ||||
} | |||||
return ValueFromAmount(g_mempool.estimateFee().GetFeePerK()); | return ValueFromAmount(g_mempool.estimateFee().GetFeePerK()); | ||||
} | } | ||||
// clang-format off | // clang-format off | ||||
static const CRPCCommand commands[] = { | static const CRPCCommand commands[] = { | ||||
// category name actor (function) argNames | // category name actor (function) argNames | ||||
// ---------- ------------------------ ---------------------- ---------- | // ---------- ------------------------ ---------------------- ---------- | ||||
Show All 18 Lines |