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
pull/764/head
MarcoFalke 4 years ago
commit d692d192cd
No known key found for this signature in database
GPG Key ID: D2EA4850E7528B25

@ -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
UniValue getblockchaininfo(const JSONRPCRequest& request);
RPCHelpMan getblockchaininfo();
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: {
JSONRPCRequest jsonRequest(context);
jsonRequest.params = UniValue(UniValue::VARR);
UniValue chainInfoObject = getblockchaininfo(jsonRequest);
UniValue chainInfoObject = getblockchaininfo().HandleRequest(jsonRequest);
std::string strJSON = chainInfoObject.write() + "\n";
req->WriteHeader("Content-Type", "application/json");
req->WriteReply(HTTP_OK, strJSON);

@ -189,9 +189,9 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIn
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"
"The genesis block has height 0.\n",
{},
@ -201,15 +201,17 @@ static UniValue getblockcount(const JSONRPCRequest& request)
HelpExampleCli("getblockcount", "")
+ HelpExampleRpc("getblockcount", "")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
LOCK(cs_main);
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",
{},
RPCResult{
@ -218,10 +220,12 @@ static UniValue getbestblockhash(const JSONRPCRequest& request)
HelpExampleCli("getbestblockhash", "")
+ HelpExampleRpc("getbestblockhash", "")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
LOCK(cs_main);
return ::ChainActive().Tip()->GetBlockHash().GetHex();
},
};
}
void RPCNotifyBlockChange(const CBlockIndex* pindex)
@ -234,9 +238,9 @@ void RPCNotifyBlockChange(const CBlockIndex* pindex)
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"
"\nReturns the current block on timeout or exit.\n",
{
@ -252,7 +256,8 @@ static UniValue waitfornewblock(const JSONRPCRequest& request)
HelpExampleCli("waitfornewblock", "1000")
+ HelpExampleRpc("waitfornewblock", "1000")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
int timeout = 0;
if (!request.params[0].isNull())
timeout = request.params[0].get_int();
@ -271,11 +276,13 @@ static UniValue waitfornewblock(const JSONRPCRequest& request)
ret.pushKV("hash", block.hash.GetHex());
ret.pushKV("height", block.height);
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"
"\nReturns the current block on timeout or exit.\n",
{
@ -292,7 +299,8 @@ static UniValue waitforblock(const JSONRPCRequest& request)
HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\" 1000")
+ HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
int timeout = 0;
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("height", block.height);
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"
"of the current tip.\n"
"\nReturns the current block on timeout or exit.\n",
@ -336,7 +346,8 @@ static UniValue waitforblockheight(const JSONRPCRequest& request)
HelpExampleCli("waitforblockheight", "100 1000")
+ HelpExampleRpc("waitforblockheight", "100, 1000")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
int timeout = 0;
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("height", block.height);
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",
{},
RPCResult{RPCResult::Type::NONE, "", ""},
@ -369,15 +382,17 @@ static UniValue syncwithvalidationinterfacequeue(const JSONRPCRequest& request)
HelpExampleCli("syncwithvalidationinterfacequeue","")
+ HelpExampleRpc("syncwithvalidationinterfacequeue","")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
SyncWithValidationInterfaceQueue();
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",
{},
RPCResult{
@ -386,10 +401,12 @@ static UniValue getdifficulty(const JSONRPCRequest& request)
HelpExampleCli("getdifficulty", "")
+ HelpExampleRpc("getdifficulty", "")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
LOCK(cs_main);
return GetDifficulty(::ChainActive().Tip());
},
};
}
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"
"\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")
+ HelpExampleRpc("getrawmempool", "true")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
bool fVerbose = false;
if (!request.params[0].isNull())
fVerbose = request.params[0].get_bool();
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",
{
{"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\"")
+ HelpExampleRpc("getmempoolancestors", "\"mytxid\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
bool fVerbose = false;
if (!request.params[1].isNull())
fVerbose = request.params[1].get_bool();
@ -603,11 +622,13 @@ static UniValue getmempoolancestors(const JSONRPCRequest& request)
}
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",
{
{"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\"")
+ HelpExampleRpc("getmempooldescendants", "\"mytxid\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
bool fVerbose = false;
if (!request.params[1].isNull())
fVerbose = request.params[1].get_bool();
@ -666,11 +687,13 @@ static UniValue getmempooldescendants(const JSONRPCRequest& request)
}
return o;
}
},
};
}
static UniValue getmempoolentry(const JSONRPCRequest& request)
static RPCHelpMan getmempoolentry()
{
RPCHelpMan{"getmempoolentry",
return RPCHelpMan{"getmempoolentry",
"\nReturns mempool data for given transaction\n",
{
{"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\"")
+ HelpExampleRpc("getmempoolentry", "\"mytxid\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
uint256 hash = ParseHashV(request.params[0], "parameter 1");
const CTxMemPool& mempool = EnsureMemPool(request.context);
@ -697,11 +720,13 @@ static UniValue getmempoolentry(const JSONRPCRequest& request)
UniValue info(UniValue::VOBJ);
entryToJSON(mempool, info, e);
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",
{
{"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The height index"},
@ -712,8 +737,8 @@ static UniValue getblockhash(const JSONRPCRequest& request)
HelpExampleCli("getblockhash", "1000")
+ HelpExampleRpc("getblockhash", "1000")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
LOCK(cs_main);
int nHeight = request.params[0].get_int();
@ -722,11 +747,13 @@ static UniValue getblockhash(const JSONRPCRequest& request)
CBlockIndex* pblockindex = ::ChainActive()[nHeight];
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"
"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\"")
+ HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
uint256 hash(ParseHashV(request.params[0], "hash"));
bool fVerbose = true;
@ -789,6 +816,8 @@ static UniValue getblockheader(const JSONRPCRequest& request)
}
return blockheaderToJSON(tip, pblockindex);
},
};
}
static CBlock GetBlockChecked(const CBlockIndex* pblockindex)
@ -822,9 +851,9 @@ static CBlockUndo GetUndoChecked(const CBlockIndex* pblockindex)
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"
"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",
@ -877,8 +906,8 @@ static UniValue getblock(const JSONRPCRequest& request)
HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
+ HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
uint256 hash(ParseHashV(request.params[0], "blockhash"));
int verbosity = 1;
@ -913,11 +942,13 @@ static UniValue getblock(const JSONRPCRequest& request)
}
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"
" 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")
+ HelpExampleRpc("pruneblockchain", "1000")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
if (!fPruneMode)
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;
}
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"
"Note this call may take some time.\n",
{
@ -994,8 +1027,8 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request)
HelpExampleCli("gettxoutsetinfo", "")
+ HelpExampleRpc("gettxoutsetinfo", "")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
UniValue ret(UniValue::VOBJ);
CCoinsStats stats;
@ -1020,11 +1053,13 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request)
throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
}
return ret;
},
};
}
UniValue gettxout(const JSONRPCRequest& request)
static RPCHelpMan gettxout()
{
RPCHelpMan{"gettxout",
return RPCHelpMan{"gettxout",
"\nReturns details about an unspent transaction output.\n",
{
{"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"
+ HelpExampleRpc("gettxout", "\"txid\", 1")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
LOCK(cs_main);
UniValue ret(UniValue::VOBJ);
@ -1099,11 +1134,13 @@ UniValue gettxout(const JSONRPCRequest& request)
ret.pushKV("coinbase", (bool)coin.fCoinBase);
return ret;
},
};
}
static UniValue verifychain(const JSONRPCRequest& request)
static RPCHelpMan verifychain()
{
RPCHelpMan{"verifychain",
return RPCHelpMan{"verifychain",
"\nVerifies blockchain database.\n",
{
{"checklevel", RPCArg::Type::NUM, /* default */ strprintf("%d, range=0-4", DEFAULT_CHECKLEVEL),
@ -1116,14 +1153,16 @@ static UniValue verifychain(const JSONRPCRequest& request)
HelpExampleCli("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_depth{request.params[1].isNull() ? DEFAULT_CHECKBLOCKS : request.params[1].get_int()};
LOCK(cs_main);
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)
@ -1192,9 +1231,9 @@ static void BIP9SoftForkDescPushBack(UniValue& softforks, const std::string &nam
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",
{},
RPCResult{
@ -1245,8 +1284,8 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
HelpExampleCli("getblockchaininfo", "")
+ HelpExampleRpc("getblockchaininfo", "")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
LOCK(cs_main);
const CBlockIndex* tip = ::ChainActive().Tip();
@ -1291,6 +1330,8 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
obj.pushKV("warnings", GetWarnings(false).original);
return obj;
},
};
}
/** 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,"
" including the main chain as well as orphaned branches.\n",
{},
@ -1333,8 +1374,8 @@ static UniValue getchaintips(const JSONRPCRequest& request)
HelpExampleCli("getchaintips", "")
+ HelpExampleRpc("getchaintips", "")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
ChainstateManager& chainman = EnsureChainman(request.context);
LOCK(cs_main);
@ -1401,6 +1442,8 @@ static UniValue getchaintips(const JSONRPCRequest& request)
}
return res;
},
};
}
UniValue MempoolInfoToJSON(const CTxMemPool& pool)
@ -1420,9 +1463,9 @@ UniValue MempoolInfoToJSON(const CTxMemPool& pool)
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",
{},
RPCResult{
@ -1441,14 +1484,16 @@ static UniValue getmempoolinfo(const JSONRPCRequest& request)
HelpExampleCli("getmempoolinfo", "")
+ HelpExampleRpc("getmempoolinfo", "")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
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"
"\nA later preciousblock call can override the effect of an earlier one.\n"
"\nThe effects of preciousblock are not retained across restarts.\n",
@ -1460,8 +1505,8 @@ static UniValue preciousblock(const JSONRPCRequest& request)
HelpExampleCli("preciousblock", "\"blockhash\"")
+ HelpExampleRpc("preciousblock", "\"blockhash\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
uint256 hash(ParseHashV(request.params[0], "blockhash"));
CBlockIndex* pblockindex;
@ -1481,11 +1526,13 @@ static UniValue preciousblock(const JSONRPCRequest& request)
}
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",
{
{"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\"")
+ HelpExampleRpc("invalidateblock", "\"blockhash\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
uint256 hash(ParseHashV(request.params[0], "blockhash"));
BlockValidationState state;
@ -1519,11 +1566,13 @@ static UniValue invalidateblock(const JSONRPCRequest& request)
}
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"
"This can be used to undo the effects of invalidateblock.\n",
{
@ -1534,8 +1583,8 @@ static UniValue reconsiderblock(const JSONRPCRequest& request)
HelpExampleCli("reconsiderblock", "\"blockhash\"")
+ HelpExampleRpc("reconsiderblock", "\"blockhash\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
uint256 hash(ParseHashV(request.params[0], "blockhash"));
{
@ -1556,11 +1605,13 @@ static UniValue reconsiderblock(const JSONRPCRequest& request)
}
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",
{
{"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", "")
+ HelpExampleRpc("getchaintxstats", "2016")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
const CBlockIndex* pindex;
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;
},
};
}
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
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"
"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"(1000, ["minfeerate","avgfeerate"])")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
LOCK(cs_main);
CBlockIndex* pindex;
@ -1948,11 +2001,13 @@ static UniValue getblockstats(const JSONRPCRequest& request)
ret.pushKV(stat, value);
}
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",
{},
RPCResult{RPCResult::Type::NONE, "", ""},
@ -1960,8 +2015,8 @@ static UniValue savemempool(const JSONRPCRequest& request)
HelpExampleCli("savemempool", "")
+ HelpExampleRpc("savemempool", "")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
const CTxMemPool& mempool = EnsureMemPool(request.context);
if (!mempool.IsLoaded()) {
@ -1973,6 +2028,8 @@ static UniValue savemempool(const JSONRPCRequest& request)
}
return NullUniValue;
},
};
}
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"
"\nScans the unspent transaction output set for entries that match certain output descriptors.\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},
}},
RPCExamples{""},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR});
UniValue result(UniValue::VOBJ);
@ -2184,11 +2241,13 @@ UniValue scantxoutset(const JSONRPCRequest& request)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid command");
}
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",
{
{"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hash of the block"},
@ -2203,9 +2262,9 @@ static UniValue getblockfilter(const JSONRPCRequest& request)
RPCExamples{
HelpExampleCli("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" \"basic\"") +
HelpExampleRpc("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\", \"basic\"")
}
}.Check(request);
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
uint256 block_hash = ParseHashV(request.params[0], "blockhash");
std::string filtertype_name = "basic";
if (!request.params[1].isNull()) {
@ -2260,6 +2319,8 @@ static UniValue getblockfilter(const JSONRPCRequest& request)
ret.pushKV("filter", HexStr(filter.GetEncodedFilter()));
ret.pushKV("header", filter_header.GetHex());
return ret;
},
};
}
/**
@ -2267,9 +2328,9 @@ static UniValue getblockfilter(const JSONRPCRequest& request)
*
* @see SnapshotMetadata
*/
UniValue dumptxoutset(const JSONRPCRequest& request)
static RPCHelpMan dumptxoutset()
{
RPCHelpMan{
return RPCHelpMan{
"dumptxoutset",
"\nWrite the serialized UTXO set to disk.\n",
{
@ -2290,9 +2351,9 @@ UniValue dumptxoutset(const JSONRPCRequest& request)
},
RPCExamples{
HelpExampleCli("dumptxoutset", "utxo.dat")
}
}.Check(request);
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
fs::path path = fs::absolute(request.params[0].get_str(), GetDataDir());
// Write to a temporary path and then move into `path` on completion
// to avoid confusion due to an interruption.
@ -2366,6 +2427,8 @@ UniValue dumptxoutset(const JSONRPCRequest& request)
result.pushKV("base_height", tip->nHeight);
result.pushKV("path", path.string());
return result;
},
};
}
void RegisterBlockchainRPCCommands(CRPCTable &t)

@ -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",
"\nReturn the raw transaction data.\n"
@ -155,8 +155,8 @@ static UniValue getrawtransaction(const JSONRPCRequest& request)
+ HelpExampleCli("getrawtransaction", "\"mytxid\" false \"myblockhash\"")
+ HelpExampleCli("getrawtransaction", "\"mytxid\" true \"myblockhash\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
const NodeContext& node = EnsureNodeContext(request.context);
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);
TxToJSON(*tx, hash_block, 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"
"\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"
@ -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."
},
RPCExamples{""},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
std::set<uint256> setTxids;
uint256 oneTxid;
UniValue txids = request.params[0].get_array();
@ -315,11 +317,13 @@ static UniValue gettxoutproof(const JSONRPCRequest& request)
ssMB << mb;
std::string strHex = HexStr(ssMB);
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"
"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{""},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
CDataStream ssMB(ParseHexV(request.params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS);
CMerkleBlock merkleBlock;
ssMB >> merkleBlock;
@ -360,11 +364,13 @@ static UniValue verifytxoutproof(const JSONRPCRequest& request)
}
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"
"Outputs can be addresses or data.\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}]\", \"[{\\\"data\\\":\\\"00010203\\\"}]\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {
UniValue::VARR,
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);
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",
{
{"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\"")
+ HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL});
CMutableTransaction mtx;
@ -515,6 +523,8 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request)
TxToUniv(CTransaction(std::move(mtx)), uint256(), result, false);
return result;
},
};
}
static std::string GetAllOutputTypes()
@ -527,9 +537,9 @@ static std::string GetAllOutputTypes()
return Join(ret, ", ");
}
static UniValue decodescript(const JSONRPCRequest& request)
static RPCHelpMan decodescript()
{
RPCHelpMan{"decodescript",
return RPCHelpMan{"decodescript",
"\nDecode a hex-encoded script.\n",
{
{"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\"")
+ HelpExampleRpc("decodescript", "\"hexstring\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR});
UniValue r(UniValue::VOBJ);
@ -616,11 +626,13 @@ static UniValue decodescript(const JSONRPCRequest& request)
}
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"
"The combined transaction may be another partially signed transaction or a \n"
"fully signed transaction.",
@ -637,8 +649,8 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request)
RPCExamples{
HelpExampleCli("combinerawtransaction", R"('["myhex1", "myhex2", "myhex3"]')")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
UniValue txs = request.params[0].get_array();
std::vector<CMutableTransaction> txVariants(txs.size());
@ -699,11 +711,13 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request)
}
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"
"The second argument is an array of base58-encoded private\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\\\"]\"")
+ 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);
CMutableTransaction mtx;
@ -795,11 +809,13 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
UniValue result(UniValue::VOBJ);
SignTransaction(mtx, &keystore, coins, request.params[3], 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"
"\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"
@ -824,8 +840,8 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request)
"\nAs a JSON-RPC call\n"
+ HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {
UniValue::VSTR,
UniValueType(), // VNUM or VSTR, checked inside AmountFromValue()
@ -853,11 +869,13 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request)
}
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"
"\nThis checks if the transaction violates the consensus or policy rules.\n"
"\nSee sendrawtransaction call.\n",
@ -897,8 +915,8 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request)
"\nAs a JSON-RPC call\n"
+ HelpExampleRpc("testmempoolaccept", "[\"signedhex\"]")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {
UniValue::VARR,
UniValueType(), // VNUM or VSTR, checked inside AmountFromValue()
@ -958,11 +976,13 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request)
result.push_back(std::move(result_0));
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",
{
{"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The PSBT base64 string"},
@ -1074,8 +1094,8 @@ UniValue decodepsbt(const JSONRPCRequest& request)
RPCExamples{
HelpExampleCli("decodepsbt", "\"psbt\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR});
// Unserialize the transactions
@ -1267,11 +1287,13 @@ UniValue decodepsbt(const JSONRPCRequest& request)
}
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"
"Implements the Combiner role.\n",
{
@ -1287,8 +1309,8 @@ UniValue combinepsbt(const JSONRPCRequest& request)
RPCExamples{
HelpExampleCli("combinepsbt", R"('["mybase64_1", "mybase64_2", "mybase64_3"]')")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VARR}, true);
// Unserialize the transactions
@ -1315,11 +1337,13 @@ UniValue combinepsbt(const JSONRPCRequest& request)
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << merged_psbt;
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"
"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"
@ -1340,8 +1364,8 @@ UniValue finalizepsbt(const JSONRPCRequest& request)
RPCExamples{
HelpExampleCli("finalizepsbt", "\"psbt\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}, true);
// Unserialize the transactions
@ -1372,11 +1396,13 @@ UniValue finalizepsbt(const JSONRPCRequest& request)
result.pushKV("complete", complete);
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"
"Implements the Creator role.\n",
{
@ -1418,8 +1444,8 @@ UniValue createpsbt(const JSONRPCRequest& request)
RPCExamples{
HelpExampleCli("createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {
UniValue::VARR,
@ -1450,11 +1476,13 @@ UniValue createpsbt(const JSONRPCRequest& request)
ssTx << psbtx;
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"
"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"
+ HelpExampleCli("converttopsbt", "\"rawtransaction\"")
},
}.Check(request);
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL, UniValue::VBOOL}, true);
// parse hex string from parameter
@ -1517,11 +1545,13 @@ UniValue converttopsbt(const JSONRPCRequest& request)
ssTx << psbtx;
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",
{
{"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"},
@ -1538,8 +1568,9 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request)
},
RPCExamples {
HelpExampleCli("utxoupdatepsbt", "\"psbt\"")
}}.Check(request);
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR}, true);
// Unserialize the transactions
@ -1605,11 +1636,13 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request)
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << psbtx;
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"
"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 {
HelpExampleCli("joinpsbts", "\"psbt\"")
}}.Check(request);
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VARR}, true);
// Unserialize the transactions
@ -1698,11 +1732,13 @@ UniValue joinpsbts(const JSONRPCRequest& request)
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << shuffled_psbt;
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",
{
{"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"}
@ -1741,8 +1777,9 @@ UniValue analyzepsbt(const JSONRPCRequest& request)
},
RPCExamples {
HelpExampleCli("analyzepsbt", "\"psbt\"")
}}.Check(request);
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR});
// Unserialize the transaction
@ -1806,6 +1843,8 @@ UniValue analyzepsbt(const JSONRPCRequest& request)
}
return result;
},
};
}
void RegisterRawTransactionRPCCommands(CRPCTable &t)

Loading…
Cancel
Save