Merge #19849: Assert that RPCArg names are equal to CRPCCommand ones (blockchain,rawtransaction)

fa6bb0ce5d Assert that RPCArg names are equal to CRPCCommand ones (rawtransaction) (MarcoFalke)
fa80c81487 Assert that RPCArg names are equal to CRPCCommand ones (blockchain) (MarcoFalke)

Pull request description:

  This is split out from #18531 to just touch some RPC methods. Description from the main pr:

  ### Motivation

  RPCArg names in the rpc help are currently only used for documentation. However, in the future they could be used to teach the server the named arguments. Named arguments are currently registered by the `CRPCCommand`s and duplicate the RPCArg names from the documentation. This redundancy is fragile, and has lead to errors in the past (despite having linters to catch those kind of errors). See section "bugs found" for a list of bugs that have been found as a result of the changes here.

  ### Changes

  The changes here add an assert in the `CRPCCommand` constructor that the RPCArg names are identical to the ones in the `CRPCCommand`.

  ### Future work

  > Here or follow up, makes sense to also assert type of returned UniValue?

  Sure, but let's not get ahead of ourselves. I am going to submit any further works as follow-ups, including:

  * Removing the CRPCCommand arguments, now that they are asserted to be equal and thus redundant
  * Removing all python regex linters on the args, now that RPCMan can be used to generate any output, including the cli.cpp table
  * Auto-formatting and sanity checking the RPCExamples with RPCMan
  * Checking passed-in json in self-check. Removing redundant checks
  * Checking returned json against documentation to avoid regressions or false documentation
  * Compile the RPC documentation at compile-time to ensure it doesn't change at runtime and is completely static

  ### Bugs found

  * The assert identified issue #18607
  * The changes itself fixed bug #19250

ACKs for top commit:
  fjahr:
    utACK fa6bb0ce5d
  tryphe:
    utACK fa6bb0ce5d. Reducing data duplication is nice. Code changes are minimal and concise.

Tree-SHA512: deb0edc3f999baf055526eaa199b98c500635e12502dece7aa3cad5319db330eb5ee7459a5c8f040a83671a7f20c560c19a2026fb76c8416f138aa332727cbce
This commit is contained in:
MarcoFalke 2020-09-22 17:08:00 +02:00
commit d692d192cd
No known key found for this signature in database
GPG key ID: D2EA4850E7528B25
3 changed files with 295 additions and 193 deletions

View file

@ -303,7 +303,7 @@ static bool rest_block_notxdetails(const util::Ref& context, HTTPRequest* req, c
} }
// A bit of a hack - dependency on a function defined in rpc/blockchain.cpp // A bit of a hack - dependency on a function defined in rpc/blockchain.cpp
UniValue getblockchaininfo(const JSONRPCRequest& request); RPCHelpMan getblockchaininfo();
static bool rest_chaininfo(const util::Ref& context, HTTPRequest* req, const std::string& strURIPart) static bool rest_chaininfo(const util::Ref& context, HTTPRequest* req, const std::string& strURIPart)
{ {
@ -316,7 +316,7 @@ static bool rest_chaininfo(const util::Ref& context, HTTPRequest* req, const std
case RetFormat::JSON: { case RetFormat::JSON: {
JSONRPCRequest jsonRequest(context); JSONRPCRequest jsonRequest(context);
jsonRequest.params = UniValue(UniValue::VARR); jsonRequest.params = UniValue(UniValue::VARR);
UniValue chainInfoObject = getblockchaininfo(jsonRequest); UniValue chainInfoObject = getblockchaininfo().HandleRequest(jsonRequest);
std::string strJSON = chainInfoObject.write() + "\n"; std::string strJSON = chainInfoObject.write() + "\n";
req->WriteHeader("Content-Type", "application/json"); req->WriteHeader("Content-Type", "application/json");
req->WriteReply(HTTP_OK, strJSON); req->WriteReply(HTTP_OK, strJSON);

View file

@ -189,9 +189,9 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIn
return result; return result;
} }
static UniValue getblockcount(const JSONRPCRequest& request) static RPCHelpMan getblockcount()
{ {
RPCHelpMan{"getblockcount", return RPCHelpMan{"getblockcount",
"\nReturns the height of the most-work fully-validated chain.\n" "\nReturns the height of the most-work fully-validated chain.\n"
"The genesis block has height 0.\n", "The genesis block has height 0.\n",
{}, {},
@ -201,15 +201,17 @@ static UniValue getblockcount(const JSONRPCRequest& request)
HelpExampleCli("getblockcount", "") HelpExampleCli("getblockcount", "")
+ HelpExampleRpc("getblockcount", "") + HelpExampleRpc("getblockcount", "")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
LOCK(cs_main); LOCK(cs_main);
return ::ChainActive().Height(); return ::ChainActive().Height();
},
};
} }
static UniValue getbestblockhash(const JSONRPCRequest& request) static RPCHelpMan getbestblockhash()
{ {
RPCHelpMan{"getbestblockhash", return RPCHelpMan{"getbestblockhash",
"\nReturns the hash of the best (tip) block in the most-work fully-validated chain.\n", "\nReturns the hash of the best (tip) block in the most-work fully-validated chain.\n",
{}, {},
RPCResult{ RPCResult{
@ -218,10 +220,12 @@ static UniValue getbestblockhash(const JSONRPCRequest& request)
HelpExampleCli("getbestblockhash", "") HelpExampleCli("getbestblockhash", "")
+ HelpExampleRpc("getbestblockhash", "") + HelpExampleRpc("getbestblockhash", "")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
LOCK(cs_main); LOCK(cs_main);
return ::ChainActive().Tip()->GetBlockHash().GetHex(); return ::ChainActive().Tip()->GetBlockHash().GetHex();
},
};
} }
void RPCNotifyBlockChange(const CBlockIndex* pindex) void RPCNotifyBlockChange(const CBlockIndex* pindex)
@ -234,9 +238,9 @@ void RPCNotifyBlockChange(const CBlockIndex* pindex)
cond_blockchange.notify_all(); cond_blockchange.notify_all();
} }
static UniValue waitfornewblock(const JSONRPCRequest& request) static RPCHelpMan waitfornewblock()
{ {
RPCHelpMan{"waitfornewblock", return RPCHelpMan{"waitfornewblock",
"\nWaits for a specific new block and returns useful info about it.\n" "\nWaits for a specific new block and returns useful info about it.\n"
"\nReturns the current block on timeout or exit.\n", "\nReturns the current block on timeout or exit.\n",
{ {
@ -252,7 +256,8 @@ static UniValue waitfornewblock(const JSONRPCRequest& request)
HelpExampleCli("waitfornewblock", "1000") HelpExampleCli("waitfornewblock", "1000")
+ HelpExampleRpc("waitfornewblock", "1000") + HelpExampleRpc("waitfornewblock", "1000")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
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();
@ -271,11 +276,13 @@ static UniValue waitfornewblock(const JSONRPCRequest& request)
ret.pushKV("hash", block.hash.GetHex()); ret.pushKV("hash", block.hash.GetHex());
ret.pushKV("height", block.height); ret.pushKV("height", block.height);
return ret; return ret;
},
};
} }
static UniValue waitforblock(const JSONRPCRequest& request) static RPCHelpMan waitforblock()
{ {
RPCHelpMan{"waitforblock", return RPCHelpMan{"waitforblock",
"\nWaits for a specific new block and returns useful info about it.\n" "\nWaits for a specific new block and returns useful info about it.\n"
"\nReturns the current block on timeout or exit.\n", "\nReturns the current block on timeout or exit.\n",
{ {
@ -292,7 +299,8 @@ static UniValue waitforblock(const JSONRPCRequest& request)
HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\" 1000") HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\" 1000")
+ HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000") + HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
int timeout = 0; int timeout = 0;
uint256 hash(ParseHashV(request.params[0], "blockhash")); uint256 hash(ParseHashV(request.params[0], "blockhash"));
@ -314,11 +322,13 @@ static UniValue waitforblock(const JSONRPCRequest& request)
ret.pushKV("hash", block.hash.GetHex()); ret.pushKV("hash", block.hash.GetHex());
ret.pushKV("height", block.height); ret.pushKV("height", block.height);
return ret; return ret;
},
};
} }
static UniValue waitforblockheight(const JSONRPCRequest& request) static RPCHelpMan waitforblockheight()
{ {
RPCHelpMan{"waitforblockheight", return RPCHelpMan{"waitforblockheight",
"\nWaits for (at least) block height and returns the height and hash\n" "\nWaits for (at least) block height and returns the height and hash\n"
"of the current tip.\n" "of the current tip.\n"
"\nReturns the current block on timeout or exit.\n", "\nReturns the current block on timeout or exit.\n",
@ -336,7 +346,8 @@ static UniValue waitforblockheight(const JSONRPCRequest& request)
HelpExampleCli("waitforblockheight", "100 1000") HelpExampleCli("waitforblockheight", "100 1000")
+ HelpExampleRpc("waitforblockheight", "100, 1000") + HelpExampleRpc("waitforblockheight", "100, 1000")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
int timeout = 0; int timeout = 0;
int height = request.params[0].get_int(); int height = request.params[0].get_int();
@ -357,11 +368,13 @@ static UniValue waitforblockheight(const JSONRPCRequest& request)
ret.pushKV("hash", block.hash.GetHex()); ret.pushKV("hash", block.hash.GetHex());
ret.pushKV("height", block.height); ret.pushKV("height", block.height);
return ret; return ret;
},
};
} }
static UniValue syncwithvalidationinterfacequeue(const JSONRPCRequest& request) static RPCHelpMan syncwithvalidationinterfacequeue()
{ {
RPCHelpMan{"syncwithvalidationinterfacequeue", return RPCHelpMan{"syncwithvalidationinterfacequeue",
"\nWaits for the validation interface queue to catch up on everything that was there when we entered this function.\n", "\nWaits for the validation interface queue to catch up on everything that was there when we entered this function.\n",
{}, {},
RPCResult{RPCResult::Type::NONE, "", ""}, RPCResult{RPCResult::Type::NONE, "", ""},
@ -369,15 +382,17 @@ static UniValue syncwithvalidationinterfacequeue(const JSONRPCRequest& request)
HelpExampleCli("syncwithvalidationinterfacequeue","") HelpExampleCli("syncwithvalidationinterfacequeue","")
+ HelpExampleRpc("syncwithvalidationinterfacequeue","") + HelpExampleRpc("syncwithvalidationinterfacequeue","")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
SyncWithValidationInterfaceQueue(); SyncWithValidationInterfaceQueue();
return NullUniValue; return NullUniValue;
},
};
} }
static UniValue getdifficulty(const JSONRPCRequest& request) static RPCHelpMan getdifficulty()
{ {
RPCHelpMan{"getdifficulty", return RPCHelpMan{"getdifficulty",
"\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n", "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n",
{}, {},
RPCResult{ RPCResult{
@ -386,10 +401,12 @@ static UniValue getdifficulty(const JSONRPCRequest& request)
HelpExampleCli("getdifficulty", "") HelpExampleCli("getdifficulty", "")
+ HelpExampleRpc("getdifficulty", "") + HelpExampleRpc("getdifficulty", "")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
LOCK(cs_main); LOCK(cs_main);
return GetDifficulty(::ChainActive().Tip()); return GetDifficulty(::ChainActive().Tip());
},
};
} }
static std::vector<RPCResult> MempoolEntryDescription() { return { static std::vector<RPCResult> MempoolEntryDescription() { return {
@ -510,9 +527,9 @@ UniValue MempoolToJSON(const CTxMemPool& pool, bool verbose)
} }
} }
static UniValue getrawmempool(const JSONRPCRequest& request) static RPCHelpMan getrawmempool()
{ {
RPCHelpMan{"getrawmempool", return RPCHelpMan{"getrawmempool",
"\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n" "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
"\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n", "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n",
{ {
@ -534,18 +551,20 @@ static UniValue getrawmempool(const JSONRPCRequest& request)
HelpExampleCli("getrawmempool", "true") HelpExampleCli("getrawmempool", "true")
+ HelpExampleRpc("getrawmempool", "true") + HelpExampleRpc("getrawmempool", "true")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
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(EnsureMemPool(request.context), fVerbose); return MempoolToJSON(EnsureMemPool(request.context), fVerbose);
},
};
} }
static UniValue getmempoolancestors(const JSONRPCRequest& request) static RPCHelpMan getmempoolancestors()
{ {
RPCHelpMan{"getmempoolancestors", return RPCHelpMan{"getmempoolancestors",
"\nIf txid is in the mempool, returns all in-mempool ancestors.\n", "\nIf txid is in the mempool, returns all in-mempool ancestors.\n",
{ {
{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"}, {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"},
@ -565,8 +584,8 @@ static UniValue getmempoolancestors(const JSONRPCRequest& request)
HelpExampleCli("getmempoolancestors", "\"mytxid\"") HelpExampleCli("getmempoolancestors", "\"mytxid\"")
+ HelpExampleRpc("getmempoolancestors", "\"mytxid\"") + HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
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();
@ -603,11 +622,13 @@ static UniValue getmempoolancestors(const JSONRPCRequest& request)
} }
return o; return o;
} }
},
};
} }
static UniValue getmempooldescendants(const JSONRPCRequest& request) static RPCHelpMan getmempooldescendants()
{ {
RPCHelpMan{"getmempooldescendants", return RPCHelpMan{"getmempooldescendants",
"\nIf txid is in the mempool, returns all in-mempool descendants.\n", "\nIf txid is in the mempool, returns all in-mempool descendants.\n",
{ {
{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"}, {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"},
@ -627,8 +648,8 @@ static UniValue getmempooldescendants(const JSONRPCRequest& request)
HelpExampleCli("getmempooldescendants", "\"mytxid\"") HelpExampleCli("getmempooldescendants", "\"mytxid\"")
+ HelpExampleRpc("getmempooldescendants", "\"mytxid\"") + HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
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();
@ -666,11 +687,13 @@ static UniValue getmempooldescendants(const JSONRPCRequest& request)
} }
return o; return o;
} }
},
};
} }
static UniValue getmempoolentry(const JSONRPCRequest& request) static RPCHelpMan getmempoolentry()
{ {
RPCHelpMan{"getmempoolentry", return RPCHelpMan{"getmempoolentry",
"\nReturns mempool data for given transaction\n", "\nReturns mempool data for given transaction\n",
{ {
{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"}, {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"},
@ -681,8 +704,8 @@ static UniValue getmempoolentry(const JSONRPCRequest& request)
HelpExampleCli("getmempoolentry", "\"mytxid\"") HelpExampleCli("getmempoolentry", "\"mytxid\"")
+ HelpExampleRpc("getmempoolentry", "\"mytxid\"") + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
uint256 hash = ParseHashV(request.params[0], "parameter 1"); uint256 hash = ParseHashV(request.params[0], "parameter 1");
const CTxMemPool& mempool = EnsureMemPool(request.context); const CTxMemPool& mempool = EnsureMemPool(request.context);
@ -697,11 +720,13 @@ static UniValue getmempoolentry(const JSONRPCRequest& request)
UniValue info(UniValue::VOBJ); UniValue info(UniValue::VOBJ);
entryToJSON(mempool, info, e); entryToJSON(mempool, info, e);
return info; return info;
},
};
} }
static UniValue getblockhash(const JSONRPCRequest& request) static RPCHelpMan getblockhash()
{ {
RPCHelpMan{"getblockhash", return RPCHelpMan{"getblockhash",
"\nReturns hash of block in best-block-chain at height provided.\n", "\nReturns hash of block in best-block-chain at height provided.\n",
{ {
{"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The height index"}, {"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The height index"},
@ -712,8 +737,8 @@ static UniValue getblockhash(const JSONRPCRequest& request)
HelpExampleCli("getblockhash", "1000") HelpExampleCli("getblockhash", "1000")
+ HelpExampleRpc("getblockhash", "1000") + HelpExampleRpc("getblockhash", "1000")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
LOCK(cs_main); LOCK(cs_main);
int nHeight = request.params[0].get_int(); int nHeight = request.params[0].get_int();
@ -722,11 +747,13 @@ static UniValue getblockhash(const JSONRPCRequest& request)
CBlockIndex* pblockindex = ::ChainActive()[nHeight]; CBlockIndex* pblockindex = ::ChainActive()[nHeight];
return pblockindex->GetBlockHash().GetHex(); return pblockindex->GetBlockHash().GetHex();
},
};
} }
static UniValue getblockheader(const JSONRPCRequest& request) static RPCHelpMan getblockheader()
{ {
RPCHelpMan{"getblockheader", return RPCHelpMan{"getblockheader",
"\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n" "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
"If verbose is true, returns an Object with information about blockheader <hash>.\n", "If verbose is true, returns an Object with information about blockheader <hash>.\n",
{ {
@ -760,8 +787,8 @@ static UniValue getblockheader(const JSONRPCRequest& request)
HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
+ HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
uint256 hash(ParseHashV(request.params[0], "hash")); uint256 hash(ParseHashV(request.params[0], "hash"));
bool fVerbose = true; bool fVerbose = true;
@ -789,6 +816,8 @@ static UniValue getblockheader(const JSONRPCRequest& request)
} }
return blockheaderToJSON(tip, pblockindex); return blockheaderToJSON(tip, pblockindex);
},
};
} }
static CBlock GetBlockChecked(const CBlockIndex* pblockindex) static CBlock GetBlockChecked(const CBlockIndex* pblockindex)
@ -822,9 +851,9 @@ static CBlockUndo GetUndoChecked(const CBlockIndex* pblockindex)
return blockUndo; return blockUndo;
} }
static UniValue getblock(const JSONRPCRequest& request) static RPCHelpMan getblock()
{ {
RPCHelpMan{"getblock", return RPCHelpMan{"getblock",
"\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n" "\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
"If verbosity is 1, returns an Object with information about block <hash>.\n" "If verbosity is 1, returns an Object with information about block <hash>.\n"
"If verbosity is 2, returns an Object with information about block <hash> and information about each transaction. \n", "If verbosity is 2, returns an Object with information about block <hash> and information about each transaction. \n",
@ -877,8 +906,8 @@ static UniValue getblock(const JSONRPCRequest& request)
HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
+ HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
uint256 hash(ParseHashV(request.params[0], "blockhash")); uint256 hash(ParseHashV(request.params[0], "blockhash"));
int verbosity = 1; int verbosity = 1;
@ -913,11 +942,13 @@ static UniValue getblock(const JSONRPCRequest& request)
} }
return blockToJSON(block, tip, pblockindex, verbosity >= 2); return blockToJSON(block, tip, pblockindex, verbosity >= 2);
},
};
} }
static UniValue pruneblockchain(const JSONRPCRequest& request) static RPCHelpMan pruneblockchain()
{ {
RPCHelpMan{"pruneblockchain", "", return RPCHelpMan{"pruneblockchain", "",
{ {
{"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The block height to prune up to. May be set to a discrete height, or to a " + UNIX_EPOCH_TIME + "\n" {"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The block height to prune up to. May be set to a discrete height, or to a " + UNIX_EPOCH_TIME + "\n"
" to prune blocks whose block time is at least 2 hours older than the provided timestamp."}, " to prune blocks whose block time is at least 2 hours older than the provided timestamp."},
@ -928,8 +959,8 @@ static UniValue pruneblockchain(const JSONRPCRequest& request)
HelpExampleCli("pruneblockchain", "1000") HelpExampleCli("pruneblockchain", "1000")
+ HelpExampleRpc("pruneblockchain", "1000") + HelpExampleRpc("pruneblockchain", "1000")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
if (!fPruneMode) if (!fPruneMode)
throw JSONRPCError(RPC_MISC_ERROR, "Cannot prune blocks because node is not in prune mode."); throw JSONRPCError(RPC_MISC_ERROR, "Cannot prune blocks because node is not in prune mode.");
@ -968,11 +999,13 @@ static UniValue pruneblockchain(const JSONRPCRequest& request)
block = block->pprev; block = block->pprev;
} }
return uint64_t(block->nHeight); return uint64_t(block->nHeight);
},
};
} }
static UniValue gettxoutsetinfo(const JSONRPCRequest& request) static RPCHelpMan gettxoutsetinfo()
{ {
RPCHelpMan{"gettxoutsetinfo", return RPCHelpMan{"gettxoutsetinfo",
"\nReturns statistics about the unspent transaction output set.\n" "\nReturns statistics about the unspent transaction output set.\n"
"Note this call may take some time.\n", "Note this call may take some time.\n",
{ {
@ -994,8 +1027,8 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request)
HelpExampleCli("gettxoutsetinfo", "") HelpExampleCli("gettxoutsetinfo", "")
+ HelpExampleRpc("gettxoutsetinfo", "") + HelpExampleRpc("gettxoutsetinfo", "")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
UniValue ret(UniValue::VOBJ); UniValue ret(UniValue::VOBJ);
CCoinsStats stats; CCoinsStats stats;
@ -1020,11 +1053,13 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request)
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 JSONRPCRequest& request) static RPCHelpMan gettxout()
{ {
RPCHelpMan{"gettxout", return RPCHelpMan{"gettxout",
"\nReturns details about an unspent transaction output.\n", "\nReturns details about an unspent transaction output.\n",
{ {
{"txid", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction id"}, {"txid", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction id"},
@ -1056,8 +1091,8 @@ UniValue gettxout(const JSONRPCRequest& request)
"\nAs a JSON-RPC call\n" "\nAs a JSON-RPC call\n"
+ HelpExampleRpc("gettxout", "\"txid\", 1") + HelpExampleRpc("gettxout", "\"txid\", 1")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
LOCK(cs_main); LOCK(cs_main);
UniValue ret(UniValue::VOBJ); UniValue ret(UniValue::VOBJ);
@ -1099,11 +1134,13 @@ UniValue gettxout(const JSONRPCRequest& request)
ret.pushKV("coinbase", (bool)coin.fCoinBase); ret.pushKV("coinbase", (bool)coin.fCoinBase);
return ret; return ret;
},
};
} }
static UniValue verifychain(const JSONRPCRequest& request) static RPCHelpMan verifychain()
{ {
RPCHelpMan{"verifychain", return RPCHelpMan{"verifychain",
"\nVerifies blockchain database.\n", "\nVerifies blockchain database.\n",
{ {
{"checklevel", RPCArg::Type::NUM, /* default */ strprintf("%d, range=0-4", DEFAULT_CHECKLEVEL), {"checklevel", RPCArg::Type::NUM, /* default */ strprintf("%d, range=0-4", DEFAULT_CHECKLEVEL),
@ -1116,14 +1153,16 @@ static UniValue verifychain(const JSONRPCRequest& request)
HelpExampleCli("verifychain", "") HelpExampleCli("verifychain", "")
+ HelpExampleRpc("verifychain", "") + HelpExampleRpc("verifychain", "")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
const int check_level(request.params[0].isNull() ? DEFAULT_CHECKLEVEL : request.params[0].get_int()); const int check_level(request.params[0].isNull() ? DEFAULT_CHECKLEVEL : request.params[0].get_int());
const int check_depth{request.params[1].isNull() ? DEFAULT_CHECKBLOCKS : request.params[1].get_int()}; const int check_depth{request.params[1].isNull() ? DEFAULT_CHECKBLOCKS : request.params[1].get_int()};
LOCK(cs_main); LOCK(cs_main);
return CVerifyDB().VerifyDB(Params(), &::ChainstateActive().CoinsTip(), check_level, check_depth); return CVerifyDB().VerifyDB(Params(), &::ChainstateActive().CoinsTip(), check_level, check_depth);
},
};
} }
static void BuriedForkDescPushBack(UniValue& softforks, const std::string &name, int height) EXCLUSIVE_LOCKS_REQUIRED(cs_main) static void BuriedForkDescPushBack(UniValue& softforks, const std::string &name, int height) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
@ -1192,9 +1231,9 @@ static void BIP9SoftForkDescPushBack(UniValue& softforks, const std::string &nam
softforks.pushKV(name, rv); softforks.pushKV(name, rv);
} }
UniValue getblockchaininfo(const JSONRPCRequest& request) RPCHelpMan getblockchaininfo()
{ {
RPCHelpMan{"getblockchaininfo", return RPCHelpMan{"getblockchaininfo",
"Returns an object containing various state info regarding blockchain processing.\n", "Returns an object containing various state info regarding blockchain processing.\n",
{}, {},
RPCResult{ RPCResult{
@ -1245,8 +1284,8 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
HelpExampleCli("getblockchaininfo", "") HelpExampleCli("getblockchaininfo", "")
+ HelpExampleRpc("getblockchaininfo", "") + HelpExampleRpc("getblockchaininfo", "")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
LOCK(cs_main); LOCK(cs_main);
const CBlockIndex* tip = ::ChainActive().Tip(); const CBlockIndex* tip = ::ChainActive().Tip();
@ -1291,6 +1330,8 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
obj.pushKV("warnings", GetWarnings(false).original); obj.pushKV("warnings", GetWarnings(false).original);
return obj; return obj;
},
};
} }
/** Comparison function for sorting the getchaintips heads. */ /** Comparison function for sorting the getchaintips heads. */
@ -1308,9 +1349,9 @@ struct CompareBlocksByHeight
} }
}; };
static UniValue getchaintips(const JSONRPCRequest& request) static RPCHelpMan getchaintips()
{ {
RPCHelpMan{"getchaintips", return RPCHelpMan{"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",
{}, {},
@ -1333,8 +1374,8 @@ static UniValue getchaintips(const JSONRPCRequest& request)
HelpExampleCli("getchaintips", "") HelpExampleCli("getchaintips", "")
+ HelpExampleRpc("getchaintips", "") + HelpExampleRpc("getchaintips", "")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
ChainstateManager& chainman = EnsureChainman(request.context); ChainstateManager& chainman = EnsureChainman(request.context);
LOCK(cs_main); LOCK(cs_main);
@ -1401,6 +1442,8 @@ static UniValue getchaintips(const JSONRPCRequest& request)
} }
return res; return res;
},
};
} }
UniValue MempoolInfoToJSON(const CTxMemPool& pool) UniValue MempoolInfoToJSON(const CTxMemPool& pool)
@ -1420,9 +1463,9 @@ UniValue MempoolInfoToJSON(const CTxMemPool& pool)
return ret; return ret;
} }
static UniValue getmempoolinfo(const JSONRPCRequest& request) static RPCHelpMan getmempoolinfo()
{ {
RPCHelpMan{"getmempoolinfo", return RPCHelpMan{"getmempoolinfo",
"\nReturns details on the active state of the TX memory pool.\n", "\nReturns details on the active state of the TX memory pool.\n",
{}, {},
RPCResult{ RPCResult{
@ -1441,14 +1484,16 @@ static UniValue getmempoolinfo(const JSONRPCRequest& request)
HelpExampleCli("getmempoolinfo", "") HelpExampleCli("getmempoolinfo", "")
+ HelpExampleRpc("getmempoolinfo", "") + HelpExampleRpc("getmempoolinfo", "")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
return MempoolInfoToJSON(EnsureMemPool(request.context)); return MempoolInfoToJSON(EnsureMemPool(request.context));
},
};
} }
static UniValue preciousblock(const JSONRPCRequest& request) static RPCHelpMan preciousblock()
{ {
RPCHelpMan{"preciousblock", return RPCHelpMan{"preciousblock",
"\nTreats a block as if it were received before others with the same work.\n" "\nTreats a block as if it were received before others with the same work.\n"
"\nA later preciousblock call can override the effect of an earlier one.\n" "\nA later preciousblock call can override the effect of an earlier one.\n"
"\nThe effects of preciousblock are not retained across restarts.\n", "\nThe effects of preciousblock are not retained across restarts.\n",
@ -1460,8 +1505,8 @@ static UniValue preciousblock(const JSONRPCRequest& request)
HelpExampleCli("preciousblock", "\"blockhash\"") HelpExampleCli("preciousblock", "\"blockhash\"")
+ HelpExampleRpc("preciousblock", "\"blockhash\"") + HelpExampleRpc("preciousblock", "\"blockhash\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
uint256 hash(ParseHashV(request.params[0], "blockhash")); uint256 hash(ParseHashV(request.params[0], "blockhash"));
CBlockIndex* pblockindex; CBlockIndex* pblockindex;
@ -1481,11 +1526,13 @@ static UniValue preciousblock(const JSONRPCRequest& request)
} }
return NullUniValue; return NullUniValue;
},
};
} }
static UniValue invalidateblock(const JSONRPCRequest& request) static RPCHelpMan invalidateblock()
{ {
RPCHelpMan{"invalidateblock", return RPCHelpMan{"invalidateblock",
"\nPermanently marks a block as invalid, as if it violated a consensus rule.\n", "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n",
{ {
{"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hash of the block to mark as invalid"}, {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hash of the block to mark as invalid"},
@ -1495,8 +1542,8 @@ static UniValue invalidateblock(const JSONRPCRequest& request)
HelpExampleCli("invalidateblock", "\"blockhash\"") HelpExampleCli("invalidateblock", "\"blockhash\"")
+ HelpExampleRpc("invalidateblock", "\"blockhash\"") + HelpExampleRpc("invalidateblock", "\"blockhash\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
uint256 hash(ParseHashV(request.params[0], "blockhash")); uint256 hash(ParseHashV(request.params[0], "blockhash"));
BlockValidationState state; BlockValidationState state;
@ -1519,11 +1566,13 @@ static UniValue invalidateblock(const JSONRPCRequest& request)
} }
return NullUniValue; return NullUniValue;
},
};
} }
static UniValue reconsiderblock(const JSONRPCRequest& request) static RPCHelpMan reconsiderblock()
{ {
RPCHelpMan{"reconsiderblock", return RPCHelpMan{"reconsiderblock",
"\nRemoves invalidity status of a block, its ancestors and its descendants, reconsider them for activation.\n" "\nRemoves invalidity status of a block, its ancestors and its descendants, 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",
{ {
@ -1534,8 +1583,8 @@ static UniValue reconsiderblock(const JSONRPCRequest& request)
HelpExampleCli("reconsiderblock", "\"blockhash\"") HelpExampleCli("reconsiderblock", "\"blockhash\"")
+ HelpExampleRpc("reconsiderblock", "\"blockhash\"") + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
uint256 hash(ParseHashV(request.params[0], "blockhash")); uint256 hash(ParseHashV(request.params[0], "blockhash"));
{ {
@ -1556,11 +1605,13 @@ static UniValue reconsiderblock(const JSONRPCRequest& request)
} }
return NullUniValue; return NullUniValue;
},
};
} }
static UniValue getchaintxstats(const JSONRPCRequest& request) static RPCHelpMan getchaintxstats()
{ {
RPCHelpMan{"getchaintxstats", return RPCHelpMan{"getchaintxstats",
"\nCompute statistics about the total number and rate of transactions in the chain.\n", "\nCompute statistics about the total number and rate of transactions in the chain.\n",
{ {
{"nblocks", RPCArg::Type::NUM, /* default */ "one month", "Size of the window in number of blocks"}, {"nblocks", RPCArg::Type::NUM, /* default */ "one month", "Size of the window in number of blocks"},
@ -1582,8 +1633,8 @@ static UniValue getchaintxstats(const JSONRPCRequest& request)
HelpExampleCli("getchaintxstats", "") HelpExampleCli("getchaintxstats", "")
+ HelpExampleRpc("getchaintxstats", "2016") + HelpExampleRpc("getchaintxstats", "2016")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
const CBlockIndex* pindex; const CBlockIndex* pindex;
int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month
@ -1633,6 +1684,8 @@ static UniValue getchaintxstats(const JSONRPCRequest& request)
} }
return ret; return ret;
},
};
} }
template<typename T> template<typename T>
@ -1691,9 +1744,9 @@ static inline bool SetHasKeys(const std::set<T>& set, const Tk& key, const Args&
// outpoint (needed for the utxo index) + nHeight + fCoinBase // outpoint (needed for the utxo index) + nHeight + fCoinBase
static constexpr size_t PER_UTXO_OVERHEAD = sizeof(COutPoint) + sizeof(uint32_t) + sizeof(bool); static constexpr size_t PER_UTXO_OVERHEAD = sizeof(COutPoint) + sizeof(uint32_t) + sizeof(bool);
static UniValue getblockstats(const JSONRPCRequest& request) static RPCHelpMan getblockstats()
{ {
RPCHelpMan{"getblockstats", return RPCHelpMan{"getblockstats",
"\nCompute per block statistics for a given window. All amounts are in satoshis.\n" "\nCompute per block statistics for a given window. All amounts are in satoshis.\n"
"It won't work for some heights with pruning.\n", "It won't work for some heights with pruning.\n",
{ {
@ -1751,8 +1804,8 @@ static UniValue getblockstats(const JSONRPCRequest& request)
HelpExampleRpc("getblockstats", R"("00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09", ["minfeerate","avgfeerate"])") + HelpExampleRpc("getblockstats", R"("00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09", ["minfeerate","avgfeerate"])") +
HelpExampleRpc("getblockstats", R"(1000, ["minfeerate","avgfeerate"])") HelpExampleRpc("getblockstats", R"(1000, ["minfeerate","avgfeerate"])")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
LOCK(cs_main); LOCK(cs_main);
CBlockIndex* pindex; CBlockIndex* pindex;
@ -1948,11 +2001,13 @@ static UniValue getblockstats(const JSONRPCRequest& request)
ret.pushKV(stat, value); ret.pushKV(stat, value);
} }
return ret; return ret;
},
};
} }
static UniValue savemempool(const JSONRPCRequest& request) static RPCHelpMan savemempool()
{ {
RPCHelpMan{"savemempool", return RPCHelpMan{"savemempool",
"\nDumps the mempool to disk. It will fail until the previous dump is fully loaded.\n", "\nDumps the mempool to disk. It will fail until the previous dump is fully loaded.\n",
{}, {},
RPCResult{RPCResult::Type::NONE, "", ""}, RPCResult{RPCResult::Type::NONE, "", ""},
@ -1960,8 +2015,8 @@ static UniValue savemempool(const JSONRPCRequest& request)
HelpExampleCli("savemempool", "") HelpExampleCli("savemempool", "")
+ HelpExampleRpc("savemempool", "") + HelpExampleRpc("savemempool", "")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
const CTxMemPool& mempool = EnsureMemPool(request.context); const CTxMemPool& mempool = EnsureMemPool(request.context);
if (!mempool.IsLoaded()) { if (!mempool.IsLoaded()) {
@ -1973,6 +2028,8 @@ static UniValue savemempool(const JSONRPCRequest& request)
} }
return NullUniValue; return NullUniValue;
},
};
} }
namespace { namespace {
@ -2034,9 +2091,9 @@ public:
} }
}; };
UniValue scantxoutset(const JSONRPCRequest& request) static RPCHelpMan scantxoutset()
{ {
RPCHelpMan{"scantxoutset", return RPCHelpMan{"scantxoutset",
"\nEXPERIMENTAL warning: this call may be removed or changed in future releases.\n" "\nEXPERIMENTAL warning: this call may be removed or changed in future releases.\n"
"\nScans the unspent transaction output set for entries that match certain output descriptors.\n" "\nScans the unspent transaction output set for entries that match certain output descriptors.\n"
"Examples of output descriptors are:\n" "Examples of output descriptors are:\n"
@ -2090,8 +2147,8 @@ UniValue scantxoutset(const JSONRPCRequest& request)
{RPCResult::Type::STR_AMOUNT, "total_amount", "The total amount of all found unspent outputs in " + CURRENCY_UNIT}, {RPCResult::Type::STR_AMOUNT, "total_amount", "The total amount of all found unspent outputs in " + CURRENCY_UNIT},
}}, }},
RPCExamples{""}, RPCExamples{""},
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR}); RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR});
UniValue result(UniValue::VOBJ); UniValue result(UniValue::VOBJ);
@ -2184,11 +2241,13 @@ UniValue scantxoutset(const JSONRPCRequest& request)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid command"); throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid command");
} }
return result; return result;
},
};
} }
static UniValue getblockfilter(const JSONRPCRequest& request) static RPCHelpMan getblockfilter()
{ {
RPCHelpMan{"getblockfilter", return RPCHelpMan{"getblockfilter",
"\nRetrieve a BIP 157 content filter for a particular block.\n", "\nRetrieve a BIP 157 content filter for a particular block.\n",
{ {
{"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hash of the block"}, {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hash of the block"},
@ -2203,9 +2262,9 @@ static UniValue getblockfilter(const JSONRPCRequest& request)
RPCExamples{ RPCExamples{
HelpExampleCli("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" \"basic\"") + HelpExampleCli("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" \"basic\"") +
HelpExampleRpc("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\", \"basic\"") HelpExampleRpc("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\", \"basic\"")
} },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
uint256 block_hash = ParseHashV(request.params[0], "blockhash"); uint256 block_hash = ParseHashV(request.params[0], "blockhash");
std::string filtertype_name = "basic"; std::string filtertype_name = "basic";
if (!request.params[1].isNull()) { if (!request.params[1].isNull()) {
@ -2260,6 +2319,8 @@ static UniValue getblockfilter(const JSONRPCRequest& request)
ret.pushKV("filter", HexStr(filter.GetEncodedFilter())); ret.pushKV("filter", HexStr(filter.GetEncodedFilter()));
ret.pushKV("header", filter_header.GetHex()); ret.pushKV("header", filter_header.GetHex());
return ret; return ret;
},
};
} }
/** /**
@ -2267,9 +2328,9 @@ static UniValue getblockfilter(const JSONRPCRequest& request)
* *
* @see SnapshotMetadata * @see SnapshotMetadata
*/ */
UniValue dumptxoutset(const JSONRPCRequest& request) static RPCHelpMan dumptxoutset()
{ {
RPCHelpMan{ return RPCHelpMan{
"dumptxoutset", "dumptxoutset",
"\nWrite the serialized UTXO set to disk.\n", "\nWrite the serialized UTXO set to disk.\n",
{ {
@ -2290,9 +2351,9 @@ UniValue dumptxoutset(const JSONRPCRequest& request)
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("dumptxoutset", "utxo.dat") HelpExampleCli("dumptxoutset", "utxo.dat")
} },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
fs::path path = fs::absolute(request.params[0].get_str(), GetDataDir()); fs::path path = fs::absolute(request.params[0].get_str(), GetDataDir());
// Write to a temporary path and then move into `path` on completion // Write to a temporary path and then move into `path` on completion
// to avoid confusion due to an interruption. // to avoid confusion due to an interruption.
@ -2366,6 +2427,8 @@ UniValue dumptxoutset(const JSONRPCRequest& request)
result.pushKV("base_height", tip->nHeight); result.pushKV("base_height", tip->nHeight);
result.pushKV("path", path.string()); result.pushKV("path", path.string());
return result; return result;
},
};
} }
void RegisterBlockchainRPCCommands(CRPCTable &t) void RegisterBlockchainRPCCommands(CRPCTable &t)

View file

@ -67,9 +67,9 @@ static void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue&
} }
} }
static UniValue getrawtransaction(const JSONRPCRequest& request) static RPCHelpMan getrawtransaction()
{ {
RPCHelpMan{ return RPCHelpMan{
"getrawtransaction", "getrawtransaction",
"\nReturn the raw transaction data.\n" "\nReturn the raw transaction data.\n"
@ -155,8 +155,8 @@ static UniValue getrawtransaction(const JSONRPCRequest& request)
+ HelpExampleCli("getrawtransaction", "\"mytxid\" false \"myblockhash\"") + HelpExampleCli("getrawtransaction", "\"mytxid\" false \"myblockhash\"")
+ HelpExampleCli("getrawtransaction", "\"mytxid\" true \"myblockhash\"") + HelpExampleCli("getrawtransaction", "\"mytxid\" true \"myblockhash\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
const NodeContext& node = EnsureNodeContext(request.context); const NodeContext& node = EnsureNodeContext(request.context);
bool in_active_chain = true; bool in_active_chain = true;
@ -217,11 +217,13 @@ static UniValue getrawtransaction(const JSONRPCRequest& request)
if (blockindex) result.pushKV("in_active_chain", in_active_chain); if (blockindex) result.pushKV("in_active_chain", in_active_chain);
TxToJSON(*tx, hash_block, result); TxToJSON(*tx, hash_block, result);
return result; return result;
},
};
} }
static UniValue gettxoutproof(const JSONRPCRequest& request) static RPCHelpMan gettxoutproof()
{ {
RPCHelpMan{"gettxoutproof", return RPCHelpMan{"gettxoutproof",
"\nReturns a hex-encoded proof that \"txid\" was included in a block.\n" "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
"\nNOTE: By default this function only works sometimes. This is when there is an\n" "\nNOTE: By default this function only works sometimes. This is when there is an\n"
"unspent output in the utxo for this transaction. To make it always work,\n" "unspent output in the utxo for this transaction. To make it always work,\n"
@ -239,8 +241,8 @@ static UniValue gettxoutproof(const JSONRPCRequest& request)
RPCResult::Type::STR, "data", "A string that is a serialized, hex-encoded data for the proof." RPCResult::Type::STR, "data", "A string that is a serialized, hex-encoded data for the proof."
}, },
RPCExamples{""}, RPCExamples{""},
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
std::set<uint256> setTxids; std::set<uint256> setTxids;
uint256 oneTxid; uint256 oneTxid;
UniValue txids = request.params[0].get_array(); UniValue txids = request.params[0].get_array();
@ -315,11 +317,13 @@ static UniValue gettxoutproof(const JSONRPCRequest& request)
ssMB << mb; ssMB << mb;
std::string strHex = HexStr(ssMB); std::string strHex = HexStr(ssMB);
return strHex; return strHex;
},
};
} }
static UniValue verifytxoutproof(const JSONRPCRequest& request) static RPCHelpMan verifytxoutproof()
{ {
RPCHelpMan{"verifytxoutproof", return RPCHelpMan{"verifytxoutproof",
"\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n" "\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n"
"and throwing an RPC error if the block is not in our best chain\n", "and throwing an RPC error if the block is not in our best chain\n",
{ {
@ -332,8 +336,8 @@ static UniValue verifytxoutproof(const JSONRPCRequest& request)
} }
}, },
RPCExamples{""}, RPCExamples{""},
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
CDataStream ssMB(ParseHexV(request.params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS); CDataStream ssMB(ParseHexV(request.params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
CMerkleBlock merkleBlock; CMerkleBlock merkleBlock;
ssMB >> merkleBlock; ssMB >> merkleBlock;
@ -360,11 +364,13 @@ static UniValue verifytxoutproof(const JSONRPCRequest& request)
} }
return res; return res;
},
};
} }
static UniValue createrawtransaction(const JSONRPCRequest& request) static RPCHelpMan createrawtransaction()
{ {
RPCHelpMan{"createrawtransaction", return RPCHelpMan{"createrawtransaction",
"\nCreate a transaction spending the given inputs and creating new outputs.\n" "\nCreate a transaction spending the given inputs and creating new outputs.\n"
"Outputs can be addresses or data.\n" "Outputs can be addresses or data.\n"
"Returns hex-encoded raw transaction.\n" "Returns hex-encoded raw transaction.\n"
@ -412,8 +418,8 @@ static UniValue createrawtransaction(const JSONRPCRequest& request)
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"address\\\":0.01}]\"") + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"address\\\":0.01}]\"")
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"data\\\":\\\"00010203\\\"}]\"") + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"data\\\":\\\"00010203\\\"}]\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, { RPCTypeCheck(request.params, {
UniValue::VARR, UniValue::VARR,
UniValueType(), // ARR or OBJ, checked later UniValueType(), // ARR or OBJ, checked later
@ -429,11 +435,13 @@ static UniValue createrawtransaction(const JSONRPCRequest& request)
CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf); CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf);
return EncodeHexTx(CTransaction(rawTx)); return EncodeHexTx(CTransaction(rawTx));
},
};
} }
static UniValue decoderawtransaction(const JSONRPCRequest& request) static RPCHelpMan decoderawtransaction()
{ {
RPCHelpMan{"decoderawtransaction", return RPCHelpMan{"decoderawtransaction",
"\nReturn a JSON object representing the serialized, hex-encoded transaction.\n", "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n",
{ {
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction hex string"}, {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction hex string"},
@ -498,8 +506,8 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request)
HelpExampleCli("decoderawtransaction", "\"hexstring\"") HelpExampleCli("decoderawtransaction", "\"hexstring\"")
+ HelpExampleRpc("decoderawtransaction", "\"hexstring\"") + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}); RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL});
CMutableTransaction mtx; CMutableTransaction mtx;
@ -515,6 +523,8 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request)
TxToUniv(CTransaction(std::move(mtx)), uint256(), result, false); TxToUniv(CTransaction(std::move(mtx)), uint256(), result, false);
return result; return result;
},
};
} }
static std::string GetAllOutputTypes() static std::string GetAllOutputTypes()
@ -527,9 +537,9 @@ static std::string GetAllOutputTypes()
return Join(ret, ", "); return Join(ret, ", ");
} }
static UniValue decodescript(const JSONRPCRequest& request) static RPCHelpMan decodescript()
{ {
RPCHelpMan{"decodescript", return RPCHelpMan{"decodescript",
"\nDecode a hex-encoded script.\n", "\nDecode a hex-encoded script.\n",
{ {
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded script"}, {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded script"},
@ -563,8 +573,8 @@ static UniValue decodescript(const JSONRPCRequest& request)
HelpExampleCli("decodescript", "\"hexstring\"") HelpExampleCli("decodescript", "\"hexstring\"")
+ HelpExampleRpc("decodescript", "\"hexstring\"") + HelpExampleRpc("decodescript", "\"hexstring\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR}); RPCTypeCheck(request.params, {UniValue::VSTR});
UniValue r(UniValue::VOBJ); UniValue r(UniValue::VOBJ);
@ -616,11 +626,13 @@ static UniValue decodescript(const JSONRPCRequest& request)
} }
return r; return r;
},
};
} }
static UniValue combinerawtransaction(const JSONRPCRequest& request) static RPCHelpMan combinerawtransaction()
{ {
RPCHelpMan{"combinerawtransaction", return RPCHelpMan{"combinerawtransaction",
"\nCombine multiple partially signed transactions into one transaction.\n" "\nCombine multiple partially signed transactions into one transaction.\n"
"The combined transaction may be another partially signed transaction or a \n" "The combined transaction may be another partially signed transaction or a \n"
"fully signed transaction.", "fully signed transaction.",
@ -637,8 +649,8 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request)
RPCExamples{ RPCExamples{
HelpExampleCli("combinerawtransaction", R"('["myhex1", "myhex2", "myhex3"]')") HelpExampleCli("combinerawtransaction", R"('["myhex1", "myhex2", "myhex3"]')")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
UniValue txs = request.params[0].get_array(); UniValue txs = request.params[0].get_array();
std::vector<CMutableTransaction> txVariants(txs.size()); std::vector<CMutableTransaction> txVariants(txs.size());
@ -699,11 +711,13 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request)
} }
return EncodeHexTx(CTransaction(mergedTx)); return EncodeHexTx(CTransaction(mergedTx));
},
};
} }
static UniValue signrawtransactionwithkey(const JSONRPCRequest& request) static RPCHelpMan signrawtransactionwithkey()
{ {
RPCHelpMan{"signrawtransactionwithkey", return RPCHelpMan{"signrawtransactionwithkey",
"\nSign inputs for raw transaction (serialized, hex-encoded).\n" "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
"The second argument is an array of base58-encoded private\n" "The second argument is an array of base58-encoded private\n"
"keys that will be the only keys used to sign the transaction.\n" "keys that will be the only keys used to sign the transaction.\n"
@ -761,8 +775,8 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
HelpExampleCli("signrawtransactionwithkey", "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"") HelpExampleCli("signrawtransactionwithkey", "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"")
+ HelpExampleRpc("signrawtransactionwithkey", "\"myhex\", \"[\\\"key1\\\",\\\"key2\\\"]\"") + HelpExampleRpc("signrawtransactionwithkey", "\"myhex\", \"[\\\"key1\\\",\\\"key2\\\"]\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true); RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true);
CMutableTransaction mtx; CMutableTransaction mtx;
@ -795,11 +809,13 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
UniValue result(UniValue::VOBJ); UniValue result(UniValue::VOBJ);
SignTransaction(mtx, &keystore, coins, request.params[3], result); SignTransaction(mtx, &keystore, coins, request.params[3], result);
return result; return result;
},
};
} }
static UniValue sendrawtransaction(const JSONRPCRequest& request) static RPCHelpMan sendrawtransaction()
{ {
RPCHelpMan{"sendrawtransaction", return RPCHelpMan{"sendrawtransaction",
"\nSubmit a raw transaction (serialized, hex-encoded) to local node and network.\n" "\nSubmit a raw transaction (serialized, hex-encoded) to local node and network.\n"
"\nNote that the transaction will be sent unconditionally to all peers, so using this\n" "\nNote that the transaction will be sent unconditionally to all peers, so using this\n"
"for manual rebroadcast may degrade privacy by leaking the transaction's origin, as\n" "for manual rebroadcast may degrade privacy by leaking the transaction's origin, as\n"
@ -824,8 +840,8 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request)
"\nAs a JSON-RPC call\n" "\nAs a JSON-RPC call\n"
+ HelpExampleRpc("sendrawtransaction", "\"signedhex\"") + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, { RPCTypeCheck(request.params, {
UniValue::VSTR, UniValue::VSTR,
UniValueType(), // VNUM or VSTR, checked inside AmountFromValue() UniValueType(), // VNUM or VSTR, checked inside AmountFromValue()
@ -853,11 +869,13 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request)
} }
return tx->GetHash().GetHex(); return tx->GetHash().GetHex();
},
};
} }
static UniValue testmempoolaccept(const JSONRPCRequest& request) static RPCHelpMan testmempoolaccept()
{ {
RPCHelpMan{"testmempoolaccept", return RPCHelpMan{"testmempoolaccept",
"\nReturns result of mempool acceptance tests indicating if raw transaction (serialized, hex-encoded) would be accepted by mempool.\n" "\nReturns result of mempool acceptance tests indicating if raw transaction (serialized, hex-encoded) would be accepted by mempool.\n"
"\nThis checks if the transaction violates the consensus or policy rules.\n" "\nThis checks if the transaction violates the consensus or policy rules.\n"
"\nSee sendrawtransaction call.\n", "\nSee sendrawtransaction call.\n",
@ -897,8 +915,8 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request)
"\nAs a JSON-RPC call\n" "\nAs a JSON-RPC call\n"
+ HelpExampleRpc("testmempoolaccept", "[\"signedhex\"]") + HelpExampleRpc("testmempoolaccept", "[\"signedhex\"]")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, { RPCTypeCheck(request.params, {
UniValue::VARR, UniValue::VARR,
UniValueType(), // VNUM or VSTR, checked inside AmountFromValue() UniValueType(), // VNUM or VSTR, checked inside AmountFromValue()
@ -958,11 +976,13 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request)
result.push_back(std::move(result_0)); result.push_back(std::move(result_0));
return result; return result;
},
};
} }
UniValue decodepsbt(const JSONRPCRequest& request) static RPCHelpMan decodepsbt()
{ {
RPCHelpMan{"decodepsbt", return RPCHelpMan{"decodepsbt",
"\nReturn a JSON object representing the serialized, base64-encoded partially signed Bitcoin transaction.\n", "\nReturn a JSON object representing the serialized, base64-encoded partially signed Bitcoin transaction.\n",
{ {
{"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The PSBT base64 string"}, {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The PSBT base64 string"},
@ -1074,8 +1094,8 @@ UniValue decodepsbt(const JSONRPCRequest& request)
RPCExamples{ RPCExamples{
HelpExampleCli("decodepsbt", "\"psbt\"") HelpExampleCli("decodepsbt", "\"psbt\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR}); RPCTypeCheck(request.params, {UniValue::VSTR});
// Unserialize the transactions // Unserialize the transactions
@ -1267,11 +1287,13 @@ UniValue decodepsbt(const JSONRPCRequest& request)
} }
return result; return result;
},
};
} }
UniValue combinepsbt(const JSONRPCRequest& request) static RPCHelpMan combinepsbt()
{ {
RPCHelpMan{"combinepsbt", return RPCHelpMan{"combinepsbt",
"\nCombine multiple partially signed Bitcoin transactions into one transaction.\n" "\nCombine multiple partially signed Bitcoin transactions into one transaction.\n"
"Implements the Combiner role.\n", "Implements the Combiner role.\n",
{ {
@ -1287,8 +1309,8 @@ UniValue combinepsbt(const JSONRPCRequest& request)
RPCExamples{ RPCExamples{
HelpExampleCli("combinepsbt", R"('["mybase64_1", "mybase64_2", "mybase64_3"]')") HelpExampleCli("combinepsbt", R"('["mybase64_1", "mybase64_2", "mybase64_3"]')")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VARR}, true); RPCTypeCheck(request.params, {UniValue::VARR}, true);
// Unserialize the transactions // Unserialize the transactions
@ -1315,11 +1337,13 @@ UniValue combinepsbt(const JSONRPCRequest& request)
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << merged_psbt; ssTx << merged_psbt;
return EncodeBase64(MakeUCharSpan(ssTx)); return EncodeBase64(MakeUCharSpan(ssTx));
},
};
} }
UniValue finalizepsbt(const JSONRPCRequest& request) static RPCHelpMan finalizepsbt()
{ {
RPCHelpMan{"finalizepsbt", return RPCHelpMan{"finalizepsbt",
"Finalize the inputs of a PSBT. If the transaction is fully signed, it will produce a\n" "Finalize the inputs of a PSBT. If the transaction is fully signed, it will produce a\n"
"network serialized transaction which can be broadcast with sendrawtransaction. Otherwise a PSBT will be\n" "network serialized transaction which can be broadcast with sendrawtransaction. Otherwise a PSBT will be\n"
"created which has the final_scriptSig and final_scriptWitness fields filled for inputs that are complete.\n" "created which has the final_scriptSig and final_scriptWitness fields filled for inputs that are complete.\n"
@ -1340,8 +1364,8 @@ UniValue finalizepsbt(const JSONRPCRequest& request)
RPCExamples{ RPCExamples{
HelpExampleCli("finalizepsbt", "\"psbt\"") HelpExampleCli("finalizepsbt", "\"psbt\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}, true); RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}, true);
// Unserialize the transactions // Unserialize the transactions
@ -1372,11 +1396,13 @@ UniValue finalizepsbt(const JSONRPCRequest& request)
result.pushKV("complete", complete); result.pushKV("complete", complete);
return result; return result;
},
};
} }
UniValue createpsbt(const JSONRPCRequest& request) static RPCHelpMan createpsbt()
{ {
RPCHelpMan{"createpsbt", return RPCHelpMan{"createpsbt",
"\nCreates a transaction in the Partially Signed Transaction format.\n" "\nCreates a transaction in the Partially Signed Transaction format.\n"
"Implements the Creator role.\n", "Implements the Creator role.\n",
{ {
@ -1418,8 +1444,8 @@ UniValue createpsbt(const JSONRPCRequest& request)
RPCExamples{ RPCExamples{
HelpExampleCli("createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") HelpExampleCli("createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, { RPCTypeCheck(request.params, {
UniValue::VARR, UniValue::VARR,
@ -1450,11 +1476,13 @@ UniValue createpsbt(const JSONRPCRequest& request)
ssTx << psbtx; ssTx << psbtx;
return EncodeBase64(MakeUCharSpan(ssTx)); return EncodeBase64(MakeUCharSpan(ssTx));
},
};
} }
UniValue converttopsbt(const JSONRPCRequest& request) static RPCHelpMan converttopsbt()
{ {
RPCHelpMan{"converttopsbt", return RPCHelpMan{"converttopsbt",
"\nConverts a network serialized transaction to a PSBT. This should be used only with createrawtransaction and fundrawtransaction\n" "\nConverts a network serialized transaction to a PSBT. This should be used only with createrawtransaction and fundrawtransaction\n"
"createpsbt and walletcreatefundedpsbt should be used for new applications.\n", "createpsbt and walletcreatefundedpsbt should be used for new applications.\n",
{ {
@ -1478,8 +1506,8 @@ UniValue converttopsbt(const JSONRPCRequest& request)
"\nConvert the transaction to a PSBT\n" "\nConvert the transaction to a PSBT\n"
+ HelpExampleCli("converttopsbt", "\"rawtransaction\"") + HelpExampleCli("converttopsbt", "\"rawtransaction\"")
}, },
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL, UniValue::VBOOL}, true); RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL, UniValue::VBOOL}, true);
// parse hex string from parameter // parse hex string from parameter
@ -1517,11 +1545,13 @@ UniValue converttopsbt(const JSONRPCRequest& request)
ssTx << psbtx; ssTx << psbtx;
return EncodeBase64(MakeUCharSpan(ssTx)); return EncodeBase64(MakeUCharSpan(ssTx));
},
};
} }
UniValue utxoupdatepsbt(const JSONRPCRequest& request) static RPCHelpMan utxoupdatepsbt()
{ {
RPCHelpMan{"utxoupdatepsbt", return RPCHelpMan{"utxoupdatepsbt",
"\nUpdates all segwit inputs and outputs in a PSBT with data from output descriptors, the UTXO set or the mempool.\n", "\nUpdates all segwit inputs and outputs in a PSBT with data from output descriptors, the UTXO set or the mempool.\n",
{ {
{"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"}, {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"},
@ -1538,8 +1568,9 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request)
}, },
RPCExamples { RPCExamples {
HelpExampleCli("utxoupdatepsbt", "\"psbt\"") HelpExampleCli("utxoupdatepsbt", "\"psbt\"")
}}.Check(request); },
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR}, true); RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR}, true);
// Unserialize the transactions // Unserialize the transactions
@ -1605,11 +1636,13 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request)
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << psbtx; ssTx << psbtx;
return EncodeBase64(MakeUCharSpan(ssTx)); return EncodeBase64(MakeUCharSpan(ssTx));
},
};
} }
UniValue joinpsbts(const JSONRPCRequest& request) static RPCHelpMan joinpsbts()
{ {
RPCHelpMan{"joinpsbts", return RPCHelpMan{"joinpsbts",
"\nJoins multiple distinct PSBTs with different inputs and outputs into one PSBT with inputs and outputs from all of the PSBTs\n" "\nJoins multiple distinct PSBTs with different inputs and outputs into one PSBT with inputs and outputs from all of the PSBTs\n"
"No input in any of the PSBTs can be in more than one of the PSBTs.\n", "No input in any of the PSBTs can be in more than one of the PSBTs.\n",
{ {
@ -1623,8 +1656,9 @@ UniValue joinpsbts(const JSONRPCRequest& request)
}, },
RPCExamples { RPCExamples {
HelpExampleCli("joinpsbts", "\"psbt\"") HelpExampleCli("joinpsbts", "\"psbt\"")
}}.Check(request); },
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VARR}, true); RPCTypeCheck(request.params, {UniValue::VARR}, true);
// Unserialize the transactions // Unserialize the transactions
@ -1698,11 +1732,13 @@ UniValue joinpsbts(const JSONRPCRequest& request)
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << shuffled_psbt; ssTx << shuffled_psbt;
return EncodeBase64(MakeUCharSpan(ssTx)); return EncodeBase64(MakeUCharSpan(ssTx));
},
};
} }
UniValue analyzepsbt(const JSONRPCRequest& request) static RPCHelpMan analyzepsbt()
{ {
RPCHelpMan{"analyzepsbt", return RPCHelpMan{"analyzepsbt",
"\nAnalyzes and provides information about the current status of a PSBT and its inputs\n", "\nAnalyzes and provides information about the current status of a PSBT and its inputs\n",
{ {
{"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"} {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"}
@ -1741,8 +1777,9 @@ UniValue analyzepsbt(const JSONRPCRequest& request)
}, },
RPCExamples { RPCExamples {
HelpExampleCli("analyzepsbt", "\"psbt\"") HelpExampleCli("analyzepsbt", "\"psbt\"")
}}.Check(request); },
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR}); RPCTypeCheck(request.params, {UniValue::VSTR});
// Unserialize the transaction // Unserialize the transaction
@ -1806,6 +1843,8 @@ UniValue analyzepsbt(const JSONRPCRequest& request)
} }
return result; return result;
},
};
} }
void RegisterRawTransactionRPCCommands(CRPCTable &t) void RegisterRawTransactionRPCCommands(CRPCTable &t)