diff options
author | MarcoFalke <falke.marco@gmail.com> | 2020-09-23 20:10:35 +0200 |
---|---|---|
committer | MarcoFalke <falke.marco@gmail.com> | 2020-09-23 20:11:08 +0200 |
commit | 5e14fafb316ebd718370847aeb74b63ed5c17a59 (patch) | |
tree | 6028735a57eead4411f6b1af8df4e0390c3c8958 | |
parent | 8235dca6210dab8e9657c0b592ab928554155082 (diff) | |
parent | fa14f57fbc3c1fa2b9eea5df687f0fb36d452bd5 (diff) |
Merge #19994: Assert that RPCArg names are equal to CRPCCommand ones (net, rpcwallet)
fa14f57fbc3c1fa2b9eea5df687f0fb36d452bd5 Assert that RPCArg names are equal to CRPCCommand ones (net, rpcwallet) (MarcoFalke)
Pull request description:
This is the last part 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:
tACK fa14f57fbc3c1fa2b9eea5df687f0fb36d452bd5
ryanofsky:
Code review ACK fa14f57fbc3c1fa2b9eea5df687f0fb36d452bd5. Just straightforward replacements except code moved in `addnode`, and displatching updated in `bumpfee_helper`
Tree-SHA512: e07af150f1d95a88e558256ce197a6b7dc6cd722a6d6c13c75d944c49c2e2441f8b8237e9f94b03db69fa18f9bda627b0781d5e1da70bf5415e09b38728a8cb1
-rw-r--r-- | src/rpc/net.cpp | 148 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 483 | ||||
-rw-r--r-- | src/wallet/rpcwallet.h | 4 |
3 files changed, 381 insertions, 254 deletions
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 5af4389857..11a2d23d85 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -29,9 +29,9 @@ #include <univalue.h> -static UniValue getconnectioncount(const JSONRPCRequest& request) +static RPCHelpMan getconnectioncount() { - RPCHelpMan{"getconnectioncount", + return RPCHelpMan{"getconnectioncount", "\nReturns the number of connections to other nodes.\n", {}, RPCResult{ @@ -41,18 +41,20 @@ static UniValue getconnectioncount(const JSONRPCRequest& request) HelpExampleCli("getconnectioncount", "") + HelpExampleRpc("getconnectioncount", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ NodeContext& node = EnsureNodeContext(request.context); if(!node.connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); return (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_ALL); +}, + }; } -static UniValue ping(const JSONRPCRequest& request) +static RPCHelpMan ping() { - RPCHelpMan{"ping", + return RPCHelpMan{"ping", "\nRequests that a ping be sent to all other nodes, to measure ping time.\n" "Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds.\n" "Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping.\n", @@ -62,8 +64,8 @@ static UniValue ping(const JSONRPCRequest& request) HelpExampleCli("ping", "") + HelpExampleRpc("ping", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ NodeContext& node = EnsureNodeContext(request.context); if(!node.connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); @@ -73,11 +75,13 @@ static UniValue ping(const JSONRPCRequest& request) pnode->fPingQueued = true; }); return NullUniValue; +}, + }; } -static UniValue getpeerinfo(const JSONRPCRequest& request) +static RPCHelpMan getpeerinfo() { - RPCHelpMan{"getpeerinfo", + return RPCHelpMan{"getpeerinfo", "\nReturns data about each connected network node as a json array of objects.\n", {}, RPCResult{ @@ -142,8 +146,8 @@ static UniValue getpeerinfo(const JSONRPCRequest& request) HelpExampleCli("getpeerinfo", "") + HelpExampleRpc("getpeerinfo", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ NodeContext& node = EnsureNodeContext(request.context); if(!node.connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); @@ -233,17 +237,13 @@ static UniValue getpeerinfo(const JSONRPCRequest& request) } return ret; +}, + }; } -static UniValue addnode(const JSONRPCRequest& request) +static RPCHelpMan addnode() { - std::string strCommand; - if (!request.params[1].isNull()) - strCommand = request.params[1].get_str(); - if (request.fHelp || request.params.size() != 2 || - (strCommand != "onetry" && strCommand != "add" && strCommand != "remove")) - throw std::runtime_error( - RPCHelpMan{"addnode", + return RPCHelpMan{"addnode", "\nAttempts to add or remove a node from the addnode list.\n" "Or try a connection to a node once.\n" "Nodes added using addnode (or -connect) are protected from DoS disconnection and are not required to be\n" @@ -257,7 +257,15 @@ static UniValue addnode(const JSONRPCRequest& request) HelpExampleCli("addnode", "\"192.168.0.6:8333\" \"onetry\"") + HelpExampleRpc("addnode", "\"192.168.0.6:8333\", \"onetry\"") }, - }.ToString()); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ + std::string strCommand; + if (!request.params[1].isNull()) + strCommand = request.params[1].get_str(); + if (request.fHelp || request.params.size() != 2 || + (strCommand != "onetry" && strCommand != "add" && strCommand != "remove")) + throw std::runtime_error( + self.ToString()); NodeContext& node = EnsureNodeContext(request.context); if(!node.connman) @@ -284,11 +292,13 @@ static UniValue addnode(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -static UniValue disconnectnode(const JSONRPCRequest& request) +static RPCHelpMan disconnectnode() { - RPCHelpMan{"disconnectnode", + return RPCHelpMan{"disconnectnode", "\nImmediately disconnects from the specified peer node.\n" "\nStrictly one out of 'address' and 'nodeid' can be provided to identify the node.\n" "\nTo disconnect by nodeid, either set 'address' to the empty string, or call using the named 'nodeid' argument only.\n", @@ -303,8 +313,8 @@ static UniValue disconnectnode(const JSONRPCRequest& request) + HelpExampleRpc("disconnectnode", "\"192.168.0.6:8333\"") + HelpExampleRpc("disconnectnode", "\"\", 1") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ NodeContext& node = EnsureNodeContext(request.context); if(!node.connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); @@ -329,11 +339,13 @@ static UniValue disconnectnode(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -static UniValue getaddednodeinfo(const JSONRPCRequest& request) +static RPCHelpMan getaddednodeinfo() { - RPCHelpMan{"getaddednodeinfo", + return RPCHelpMan{"getaddednodeinfo", "\nReturns information about the given added node, or all added nodes\n" "(note that onetry addnodes are not listed here)\n", { @@ -361,8 +373,8 @@ static UniValue getaddednodeinfo(const JSONRPCRequest& request) HelpExampleCli("getaddednodeinfo", "\"192.168.0.201\"") + HelpExampleRpc("getaddednodeinfo", "\"192.168.0.201\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ NodeContext& node = EnsureNodeContext(request.context); if(!node.connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); @@ -401,11 +413,13 @@ static UniValue getaddednodeinfo(const JSONRPCRequest& request) } return ret; +}, + }; } -static UniValue getnettotals(const JSONRPCRequest& request) +static RPCHelpMan getnettotals() { - RPCHelpMan{"getnettotals", + return RPCHelpMan{"getnettotals", "\nReturns information about network traffic, including bytes in, bytes out,\n" "and current time.\n", {}, @@ -430,7 +444,8 @@ static UniValue getnettotals(const JSONRPCRequest& request) HelpExampleCli("getnettotals", "") + HelpExampleRpc("getnettotals", "") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ NodeContext& node = EnsureNodeContext(request.context); if(!node.connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); @@ -449,6 +464,8 @@ static UniValue getnettotals(const JSONRPCRequest& request) outboundLimit.pushKV("time_left_in_cycle", node.connman->GetMaxOutboundTimeLeftInCycle()); obj.pushKV("uploadtarget", outboundLimit); return obj; +}, + }; } static UniValue GetNetworksInfo() @@ -472,9 +489,9 @@ static UniValue GetNetworksInfo() return networks; } -static UniValue getnetworkinfo(const JSONRPCRequest& request) +static RPCHelpMan getnetworkinfo() { - RPCHelpMan{"getnetworkinfo", + return RPCHelpMan{"getnetworkinfo", "Returns an object containing various state info regarding P2P networking.\n", {}, RPCResult{ @@ -523,8 +540,8 @@ static UniValue getnetworkinfo(const JSONRPCRequest& request) HelpExampleCli("getnetworkinfo", "") + HelpExampleRpc("getnetworkinfo", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ LOCK(cs_main); UniValue obj(UniValue::VOBJ); obj.pushKV("version", CLIENT_VERSION); @@ -562,11 +579,13 @@ static UniValue getnetworkinfo(const JSONRPCRequest& request) obj.pushKV("localaddresses", localAddresses); obj.pushKV("warnings", GetWarnings(false).original); return obj; +}, + }; } -static UniValue setban(const JSONRPCRequest& request) +static RPCHelpMan setban() { - const RPCHelpMan help{"setban", + return RPCHelpMan{"setban", "\nAttempts to add or remove an IP/Subnet from the banned list.\n", { {"subnet", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP/Subnet (see getpeerinfo for nodes IP) with an optional netmask (default is /32 = single IP)"}, @@ -580,7 +599,8 @@ static UniValue setban(const JSONRPCRequest& request) + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"") + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\", 86400") }, - }; + [&](const RPCHelpMan& help, const JSONRPCRequest& request) -> UniValue +{ std::string strCommand; if (!request.params[1].isNull()) strCommand = request.params[1].get_str(); @@ -643,11 +663,13 @@ static UniValue setban(const JSONRPCRequest& request) } } return NullUniValue; +}, + }; } -static UniValue listbanned(const JSONRPCRequest& request) +static RPCHelpMan listbanned() { - RPCHelpMan{"listbanned", + return RPCHelpMan{"listbanned", "\nList all manually banned IPs/Subnets.\n", {}, RPCResult{RPCResult::Type::ARR, "", "", @@ -663,8 +685,8 @@ static UniValue listbanned(const JSONRPCRequest& request) HelpExampleCli("listbanned", "") + HelpExampleRpc("listbanned", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ NodeContext& node = EnsureNodeContext(request.context); if(!node.banman) { throw JSONRPCError(RPC_DATABASE_ERROR, "Error: Ban database not loaded"); @@ -686,11 +708,13 @@ static UniValue listbanned(const JSONRPCRequest& request) } return bannedAddresses; +}, + }; } -static UniValue clearbanned(const JSONRPCRequest& request) +static RPCHelpMan clearbanned() { - RPCHelpMan{"clearbanned", + return RPCHelpMan{"clearbanned", "\nClear all banned IPs.\n", {}, RPCResult{RPCResult::Type::NONE, "", ""}, @@ -698,7 +722,8 @@ static UniValue clearbanned(const JSONRPCRequest& request) HelpExampleCli("clearbanned", "") + HelpExampleRpc("clearbanned", "") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ NodeContext& node = EnsureNodeContext(request.context); if (!node.banman) { throw JSONRPCError(RPC_DATABASE_ERROR, "Error: Ban database not loaded"); @@ -707,19 +732,21 @@ static UniValue clearbanned(const JSONRPCRequest& request) node.banman->ClearBanned(); return NullUniValue; +}, + }; } -static UniValue setnetworkactive(const JSONRPCRequest& request) +static RPCHelpMan setnetworkactive() { - RPCHelpMan{"setnetworkactive", + return RPCHelpMan{"setnetworkactive", "\nDisable/enable all p2p network activity.\n", { {"state", RPCArg::Type::BOOL, RPCArg::Optional::NO, "true to enable networking, false to disable"}, }, RPCResult{RPCResult::Type::BOOL, "", "The value that was passed in"}, RPCExamples{""}, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ NodeContext& node = EnsureNodeContext(request.context); if (!node.connman) { throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); @@ -728,11 +755,13 @@ static UniValue setnetworkactive(const JSONRPCRequest& request) node.connman->SetNetworkActive(request.params[0].get_bool()); return node.connman->GetNetworkActive(); +}, + }; } -static UniValue getnodeaddresses(const JSONRPCRequest& request) +static RPCHelpMan getnodeaddresses() { - RPCHelpMan{"getnodeaddresses", + return RPCHelpMan{"getnodeaddresses", "\nReturn known addresses which can potentially be used to find new nodes in the network\n", { {"count", RPCArg::Type::NUM, /* default */ "1", "The maximum number of addresses to return. Specify 0 to return all known addresses."}, @@ -753,7 +782,8 @@ static UniValue getnodeaddresses(const JSONRPCRequest& request) HelpExampleCli("getnodeaddresses", "8") + HelpExampleRpc("getnodeaddresses", "8") }, - }.Check(request); + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ NodeContext& node = EnsureNodeContext(request.context); if (!node.connman) { throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); @@ -779,11 +809,13 @@ static UniValue getnodeaddresses(const JSONRPCRequest& request) ret.push_back(obj); } return ret; +}, + }; } -static UniValue addpeeraddress(const JSONRPCRequest& request) +static RPCHelpMan addpeeraddress() { - RPCHelpMan{"addpeeraddress", + return RPCHelpMan{"addpeeraddress", "\nAdd the address of a potential peer to the address manager. This RPC is for testing only.\n", { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP address of the peer"}, @@ -799,8 +831,8 @@ static UniValue addpeeraddress(const JSONRPCRequest& request) HelpExampleCli("addpeeraddress", "\"1.2.3.4\" 8333") + HelpExampleRpc("addpeeraddress", "\"1.2.3.4\", 8333") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ NodeContext& node = EnsureNodeContext(request.context); if (!node.connman) { throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); @@ -827,6 +859,8 @@ static UniValue addpeeraddress(const JSONRPCRequest& request) obj.pushKV("success", true); return obj; +}, + }; } void RegisterNetRPCCommands(CRPCTable &t) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 62a3206802..2217bc2875 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -231,9 +231,9 @@ static void SetFeeEstimateMode(const CWallet* pwallet, CCoinControl& cc, const U } } -static UniValue getnewaddress(const JSONRPCRequest& request) +static RPCHelpMan getnewaddress() { - RPCHelpMan{"getnewaddress", + return RPCHelpMan{"getnewaddress", "\nReturns a new Bitcoin address for receiving payments.\n" "If 'label' is specified, it is added to the address book \n" "so payments received with the address will be associated with 'label'.\n", @@ -248,8 +248,8 @@ static UniValue getnewaddress(const JSONRPCRequest& request) HelpExampleCli("getnewaddress", "") + HelpExampleRpc("getnewaddress", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -279,11 +279,13 @@ static UniValue getnewaddress(const JSONRPCRequest& request) } return EncodeDestination(dest); +}, + }; } -static UniValue getrawchangeaddress(const JSONRPCRequest& request) +static RPCHelpMan getrawchangeaddress() { - RPCHelpMan{"getrawchangeaddress", + return RPCHelpMan{"getrawchangeaddress", "\nReturns a new Bitcoin address, for receiving change.\n" "This is for use with raw transactions, NOT normal use.\n", { @@ -296,8 +298,8 @@ static UniValue getrawchangeaddress(const JSONRPCRequest& request) HelpExampleCli("getrawchangeaddress", "") + HelpExampleRpc("getrawchangeaddress", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -321,12 +323,14 @@ static UniValue getrawchangeaddress(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, error); } return EncodeDestination(dest); +}, + }; } -static UniValue setlabel(const JSONRPCRequest& request) +static RPCHelpMan setlabel() { - RPCHelpMan{"setlabel", + return RPCHelpMan{"setlabel", "\nSets the label associated with the given address.\n", { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to be associated with a label."}, @@ -337,8 +341,8 @@ static UniValue setlabel(const JSONRPCRequest& request) HelpExampleCli("setlabel", "\"" + EXAMPLE_ADDRESS[0] + "\" \"tabby\"") + HelpExampleRpc("setlabel", "\"" + EXAMPLE_ADDRESS[0] + "\", \"tabby\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -359,6 +363,8 @@ static UniValue setlabel(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } void ParseRecipients(const UniValue& address_amounts, const UniValue& subtract_fee_outputs, std::vector<CRecipient> &recipients) { @@ -411,9 +417,9 @@ UniValue SendMoney(CWallet* const pwallet, const CCoinControl &coin_control, std return tx->GetHash().GetHex(); } -static UniValue sendtoaddress(const JSONRPCRequest& request) +static RPCHelpMan sendtoaddress() { - RPCHelpMan{"sendtoaddress", + return RPCHelpMan{"sendtoaddress", "\nSend an amount to a given address." + HELP_REQUIRING_PASSPHRASE, { @@ -444,8 +450,8 @@ static UniValue sendtoaddress(const JSONRPCRequest& request) + HelpExampleCli("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0.1 \"\" \"\" false true 2 " + (CURRENCY_ATOM + "/B")) + HelpExampleRpc("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\", 0.1, \"donation\", \"seans outpost\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -493,11 +499,13 @@ static UniValue sendtoaddress(const JSONRPCRequest& request) ParseRecipients(address_amounts, subtractFeeFromAmount, recipients); return SendMoney(pwallet, coin_control, recipients, mapValue); +}, + }; } -static UniValue listaddressgroupings(const JSONRPCRequest& request) +static RPCHelpMan listaddressgroupings() { - RPCHelpMan{"listaddressgroupings", + return RPCHelpMan{"listaddressgroupings", "\nLists groups of addresses which have had their common ownership\n" "made public by common use as inputs or as the resulting change\n" "in past transactions\n", @@ -520,8 +528,8 @@ static UniValue listaddressgroupings(const JSONRPCRequest& request) HelpExampleCli("listaddressgroupings", "") + HelpExampleRpc("listaddressgroupings", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -552,11 +560,13 @@ static UniValue listaddressgroupings(const JSONRPCRequest& request) jsonGroupings.push_back(jsonGrouping); } return jsonGroupings; +}, + }; } -static UniValue signmessage(const JSONRPCRequest& request) +static RPCHelpMan signmessage() { - RPCHelpMan{"signmessage", + return RPCHelpMan{"signmessage", "\nSign a message with the private key of an address" + HELP_REQUIRING_PASSPHRASE, { @@ -576,8 +586,8 @@ static UniValue signmessage(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -608,6 +618,8 @@ static UniValue signmessage(const JSONRPCRequest& request) } return signature; +}, + }; } static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet) @@ -656,9 +668,9 @@ static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool b } -static UniValue getreceivedbyaddress(const JSONRPCRequest& request) +static RPCHelpMan getreceivedbyaddress() { - RPCHelpMan{"getreceivedbyaddress", + return RPCHelpMan{"getreceivedbyaddress", "\nReturns the total amount received by the given address in transactions with at least minconf confirmations.\n", { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address for transactions."}, @@ -677,8 +689,8 @@ static UniValue getreceivedbyaddress(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\", 6") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -690,12 +702,14 @@ static UniValue getreceivedbyaddress(const JSONRPCRequest& request) LOCK(pwallet->cs_wallet); return ValueFromAmount(GetReceived(*pwallet, request.params, /* by_label */ false)); +}, + }; } -static UniValue getreceivedbylabel(const JSONRPCRequest& request) +static RPCHelpMan getreceivedbylabel() { - RPCHelpMan{"getreceivedbylabel", + return RPCHelpMan{"getreceivedbylabel", "\nReturns the total amount received by addresses with <label> in transactions with at least [minconf] confirmations.\n", { {"label", RPCArg::Type::STR, RPCArg::Optional::NO, "The selected label, may be the default label using \"\"."}, @@ -714,8 +728,8 @@ static UniValue getreceivedbylabel(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("getreceivedbylabel", "\"tabby\", 6") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -727,12 +741,14 @@ static UniValue getreceivedbylabel(const JSONRPCRequest& request) LOCK(pwallet->cs_wallet); return ValueFromAmount(GetReceived(*pwallet, request.params, /* by_label */ true)); +}, + }; } -static UniValue getbalance(const JSONRPCRequest& request) +static RPCHelpMan getbalance() { - RPCHelpMan{"getbalance", + return RPCHelpMan{"getbalance", "\nReturns the total available balance.\n" "The available balance is what the wallet considers currently spendable, and is\n" "thus affected by options which limit spendability such as -spendzeroconfchange.\n", @@ -753,8 +769,8 @@ static UniValue getbalance(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("getbalance", "\"*\", 6") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -782,17 +798,19 @@ static UniValue getbalance(const JSONRPCRequest& request) const auto bal = pwallet->GetBalance(min_depth, avoid_reuse); return ValueFromAmount(bal.m_mine_trusted + (include_watchonly ? bal.m_watchonly_trusted : 0)); +}, + }; } -static UniValue getunconfirmedbalance(const JSONRPCRequest &request) +static RPCHelpMan getunconfirmedbalance() { - RPCHelpMan{"getunconfirmedbalance", + return RPCHelpMan{"getunconfirmedbalance", "DEPRECATED\nIdentical to getbalances().mine.untrusted_pending\n", {}, RPCResult{RPCResult::Type::NUM, "", "The balance"}, RPCExamples{""}, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -804,12 +822,14 @@ static UniValue getunconfirmedbalance(const JSONRPCRequest &request) LOCK(pwallet->cs_wallet); return ValueFromAmount(pwallet->GetBalance().m_mine_untrusted_pending); +}, + }; } -static UniValue sendmany(const JSONRPCRequest& request) +static RPCHelpMan sendmany() { - RPCHelpMan{"sendmany", + return RPCHelpMan{"sendmany", "\nSend multiple times. Amounts are double-precision floating point numbers." + HELP_REQUIRING_PASSPHRASE, { @@ -848,8 +868,8 @@ static UniValue sendmany(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("sendmany", "\"\", {\"" + EXAMPLE_ADDRESS[0] + "\":0.01,\"" + EXAMPLE_ADDRESS[1] + "\":0.02}, 6, \"testing\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -884,11 +904,13 @@ static UniValue sendmany(const JSONRPCRequest& request) ParseRecipients(sendTo, subtractFeeFromAmount, recipients); return SendMoney(pwallet, coin_control, recipients, std::move(mapValue)); +}, + }; } -static UniValue addmultisigaddress(const JSONRPCRequest& request) +static RPCHelpMan addmultisigaddress() { - RPCHelpMan{"addmultisigaddress", + return RPCHelpMan{"addmultisigaddress", "\nAdd an nrequired-to-sign multisignature address to the wallet. Requires a new wallet backup.\n" "Each key is a Bitcoin address or hex-encoded public key.\n" "This functionality is only intended for use with non-watchonly addresses.\n" @@ -918,8 +940,8 @@ static UniValue addmultisigaddress(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"" + EXAMPLE_ADDRESS[0] + "\\\",\\\"" + EXAMPLE_ADDRESS[1] + "\\\"]\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -965,6 +987,8 @@ static UniValue addmultisigaddress(const JSONRPCRequest& request) result.pushKV("redeemScript", HexStr(inner)); result.pushKV("descriptor", descriptor->ToString()); return result; +}, + }; } struct tallyitem @@ -1125,9 +1149,9 @@ static UniValue ListReceived(const CWallet* const pwallet, const UniValue& param return ret; } -static UniValue listreceivedbyaddress(const JSONRPCRequest& request) +static RPCHelpMan listreceivedbyaddress() { - RPCHelpMan{"listreceivedbyaddress", + return RPCHelpMan{"listreceivedbyaddress", "\nList balances by receiving address.\n", { {"minconf", RPCArg::Type::NUM, /* default */ "1", "The minimum number of confirmations before payments are included."}, @@ -1158,8 +1182,8 @@ static UniValue listreceivedbyaddress(const JSONRPCRequest& request) + HelpExampleRpc("listreceivedbyaddress", "6, true, true") + HelpExampleRpc("listreceivedbyaddress", "6, true, true, \"" + EXAMPLE_ADDRESS[0] + "\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -1171,11 +1195,13 @@ static UniValue listreceivedbyaddress(const JSONRPCRequest& request) LOCK(pwallet->cs_wallet); return ListReceived(pwallet, request.params, false); +}, + }; } -static UniValue listreceivedbylabel(const JSONRPCRequest& request) +static RPCHelpMan listreceivedbylabel() { - RPCHelpMan{"listreceivedbylabel", + return RPCHelpMan{"listreceivedbylabel", "\nList received transactions by label.\n", { {"minconf", RPCArg::Type::NUM, /* default */ "1", "The minimum number of confirmations before payments are included."}, @@ -1199,8 +1225,8 @@ static UniValue listreceivedbylabel(const JSONRPCRequest& request) + HelpExampleCli("listreceivedbylabel", "6 true") + HelpExampleRpc("listreceivedbylabel", "6, true, true") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -1212,6 +1238,8 @@ static UniValue listreceivedbylabel(const JSONRPCRequest& request) LOCK(pwallet->cs_wallet); return ListReceived(pwallet, request.params, true); +}, + }; } static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) @@ -1331,9 +1359,9 @@ static const std::vector<RPCResult> TransactionDescriptionString() "may be unknown for unconfirmed transactions not in the mempool"}}; } -UniValue listtransactions(const JSONRPCRequest& request) +static RPCHelpMan listtransactions() { - RPCHelpMan{"listtransactions", + return RPCHelpMan{"listtransactions", "\nIf a label name is provided, this will return only incoming transactions paying to addresses with the specified label.\n" "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions.\n", { @@ -1378,8 +1406,8 @@ UniValue listtransactions(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("listtransactions", "\"*\", 20, 100") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -1439,11 +1467,13 @@ UniValue listtransactions(const JSONRPCRequest& request) UniValue result{UniValue::VARR}; result.push_backV({ txs.rend() - nFrom - nCount, txs.rend() - nFrom }); // Return oldest to newest return result; +}, + }; } -static UniValue listsinceblock(const JSONRPCRequest& request) +static RPCHelpMan listsinceblock() { - RPCHelpMan{"listsinceblock", + return RPCHelpMan{"listsinceblock", "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted.\n" "If \"blockhash\" is no longer a part of the main chain, transactions from the fork point onward are included.\n" "Additionally, if include_removed is set, transactions affecting the wallet which were removed are returned in the \"removed\" array.\n", @@ -1494,8 +1524,8 @@ static UniValue listsinceblock(const JSONRPCRequest& request) + HelpExampleCli("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\" 6") + HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request); if (!pwallet) return NullUniValue; @@ -1578,11 +1608,13 @@ static UniValue listsinceblock(const JSONRPCRequest& request) ret.pushKV("lastblock", lastblock.GetHex()); return ret; +}, + }; } -static UniValue gettransaction(const JSONRPCRequest& request) +static RPCHelpMan gettransaction() { - RPCHelpMan{"gettransaction", + return RPCHelpMan{"gettransaction", "\nGet detailed information about in-wallet transaction <txid>\n", { {"txid", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction id"}, @@ -1634,8 +1666,8 @@ static UniValue gettransaction(const JSONRPCRequest& request) + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" false true") + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -1688,11 +1720,13 @@ static UniValue gettransaction(const JSONRPCRequest& request) } return entry; +}, + }; } -static UniValue abandontransaction(const JSONRPCRequest& request) +static RPCHelpMan abandontransaction() { - RPCHelpMan{"abandontransaction", + return RPCHelpMan{"abandontransaction", "\nMark in-wallet transaction <txid> as abandoned\n" "This will mark this transaction and all its in-wallet descendants as abandoned which will allow\n" "for their inputs to be respent. It can be used to replace \"stuck\" or evicted transactions.\n" @@ -1706,8 +1740,8 @@ static UniValue abandontransaction(const JSONRPCRequest& request) HelpExampleCli("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -1728,12 +1762,14 @@ static UniValue abandontransaction(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -static UniValue backupwallet(const JSONRPCRequest& request) +static RPCHelpMan backupwallet() { - RPCHelpMan{"backupwallet", + return RPCHelpMan{"backupwallet", "\nSafely copies current wallet file to destination, which can be a directory or a path with filename.\n", { {"destination", RPCArg::Type::STR, RPCArg::Optional::NO, "The destination directory or file"}, @@ -1743,8 +1779,8 @@ static UniValue backupwallet(const JSONRPCRequest& request) HelpExampleCli("backupwallet", "\"backup.dat\"") + HelpExampleRpc("backupwallet", "\"backup.dat\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -1761,12 +1797,14 @@ static UniValue backupwallet(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -static UniValue keypoolrefill(const JSONRPCRequest& request) +static RPCHelpMan keypoolrefill() { - RPCHelpMan{"keypoolrefill", + return RPCHelpMan{"keypoolrefill", "\nFills the keypool."+ HELP_REQUIRING_PASSPHRASE, { @@ -1777,8 +1815,8 @@ static UniValue keypoolrefill(const JSONRPCRequest& request) HelpExampleCli("keypoolrefill", "") + HelpExampleRpc("keypoolrefill", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -1805,12 +1843,14 @@ static UniValue keypoolrefill(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -static UniValue walletpassphrase(const JSONRPCRequest& request) +static RPCHelpMan walletpassphrase() { - RPCHelpMan{"walletpassphrase", + return RPCHelpMan{"walletpassphrase", "\nStores the wallet decryption key in memory for 'timeout' seconds.\n" "This is needed prior to performing transactions related to private keys such as sending bitcoins\n" "\nNote:\n" @@ -1829,8 +1869,8 @@ static UniValue walletpassphrase(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -1899,12 +1939,14 @@ static UniValue walletpassphrase(const JSONRPCRequest& request) }, nSleepTime); return NullUniValue; +}, + }; } -static UniValue walletpassphrasechange(const JSONRPCRequest& request) +static RPCHelpMan walletpassphrasechange() { - RPCHelpMan{"walletpassphrasechange", + return RPCHelpMan{"walletpassphrasechange", "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n", { {"oldpassphrase", RPCArg::Type::STR, RPCArg::Optional::NO, "The current passphrase"}, @@ -1915,8 +1957,8 @@ static UniValue walletpassphrasechange(const JSONRPCRequest& request) HelpExampleCli("walletpassphrasechange", "\"old one\" \"new one\"") + HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -1946,12 +1988,14 @@ static UniValue walletpassphrasechange(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } -static UniValue walletlock(const JSONRPCRequest& request) +static RPCHelpMan walletlock() { - RPCHelpMan{"walletlock", + return RPCHelpMan{"walletlock", "\nRemoves the wallet encryption key from memory, locking the wallet.\n" "After calling this method, you will need to call walletpassphrase again\n" "before being able to call any methods which require the wallet to be unlocked.\n", @@ -1967,8 +2011,8 @@ static UniValue walletlock(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("walletlock", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -1983,12 +2027,14 @@ static UniValue walletlock(const JSONRPCRequest& request) pwallet->nRelockTime = 0; return NullUniValue; +}, + }; } -static UniValue encryptwallet(const JSONRPCRequest& request) +static RPCHelpMan encryptwallet() { - RPCHelpMan{"encryptwallet", + return RPCHelpMan{"encryptwallet", "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n" "After this, any calls that interact with private keys such as sending or signing \n" "will require the passphrase to be set prior the making these calls.\n" @@ -2010,8 +2056,8 @@ static UniValue encryptwallet(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("encryptwallet", "\"my pass phrase\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -2041,11 +2087,13 @@ static UniValue encryptwallet(const JSONRPCRequest& request) } return "wallet encrypted; The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup."; +}, + }; } -static UniValue lockunspent(const JSONRPCRequest& request) +static RPCHelpMan lockunspent() { - RPCHelpMan{"lockunspent", + return RPCHelpMan{"lockunspent", "\nUpdates list of temporarily unspendable outputs.\n" "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n" "If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n" @@ -2082,8 +2130,8 @@ static UniValue lockunspent(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -2165,11 +2213,13 @@ static UniValue lockunspent(const JSONRPCRequest& request) } return true; +}, + }; } -static UniValue listlockunspent(const JSONRPCRequest& request) +static RPCHelpMan listlockunspent() { - RPCHelpMan{"listlockunspent", + return RPCHelpMan{"listlockunspent", "\nReturns list of temporarily unspendable outputs.\n" "See the lockunspent call to lock and unlock transactions for spending.\n", {}, @@ -2195,8 +2245,8 @@ static UniValue listlockunspent(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("listlockunspent", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -2217,11 +2267,13 @@ static UniValue listlockunspent(const JSONRPCRequest& request) } return ret; +}, + }; } -static UniValue settxfee(const JSONRPCRequest& request) +static RPCHelpMan settxfee() { - RPCHelpMan{"settxfee", + return RPCHelpMan{"settxfee", "\nSet the transaction fee per kB for this wallet. Overrides the global -paytxfee command line parameter.\n" "Can be deactivated by passing 0 as the fee. In that case automatic fee selection will be used by default.\n", { @@ -2234,8 +2286,8 @@ static UniValue settxfee(const JSONRPCRequest& request) HelpExampleCli("settxfee", "0.00001") + HelpExampleRpc("settxfee", "0.00001") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -2257,11 +2309,13 @@ static UniValue settxfee(const JSONRPCRequest& request) pwallet->m_pay_tx_fee = tx_fee_rate; return true; +}, + }; } -static UniValue getbalances(const JSONRPCRequest& request) +static RPCHelpMan getbalances() { - RPCHelpMan{ + return RPCHelpMan{ "getbalances", "Returns an object with all balances in " + CURRENCY_UNIT + ".\n", {}, @@ -2286,8 +2340,8 @@ static UniValue getbalances(const JSONRPCRequest& request) RPCExamples{ HelpExampleCli("getbalances", "") + HelpExampleRpc("getbalances", "")}, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const rpc_wallet = GetWalletForJSONRPCRequest(request); if (!rpc_wallet) return NullUniValue; CWallet& wallet = *rpc_wallet; @@ -2322,11 +2376,13 @@ static UniValue getbalances(const JSONRPCRequest& request) balances.pushKV("watchonly", balances_watchonly); } return balances; +}, + }; } -static UniValue getwalletinfo(const JSONRPCRequest& request) +static RPCHelpMan getwalletinfo() { - RPCHelpMan{"getwalletinfo", + return RPCHelpMan{"getwalletinfo", "Returns an object containing various wallet state info.\n", {}, RPCResult{ @@ -2359,8 +2415,8 @@ static UniValue getwalletinfo(const JSONRPCRequest& request) HelpExampleCli("getwalletinfo", "") + HelpExampleRpc("getwalletinfo", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -2414,11 +2470,13 @@ static UniValue getwalletinfo(const JSONRPCRequest& request) } obj.pushKV("descriptors", pwallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)); return obj; +}, + }; } -static UniValue listwalletdir(const JSONRPCRequest& request) +static RPCHelpMan listwalletdir() { - RPCHelpMan{"listwalletdir", + return RPCHelpMan{"listwalletdir", "Returns a list of wallets in the wallet directory.\n", {}, RPCResult{ @@ -2437,8 +2495,8 @@ static UniValue listwalletdir(const JSONRPCRequest& request) HelpExampleCli("listwalletdir", "") + HelpExampleRpc("listwalletdir", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ UniValue wallets(UniValue::VARR); for (const auto& path : ListWalletDir()) { UniValue wallet(UniValue::VOBJ); @@ -2449,11 +2507,13 @@ static UniValue listwalletdir(const JSONRPCRequest& request) UniValue result(UniValue::VOBJ); result.pushKV("wallets", wallets); return result; +}, + }; } -static UniValue listwallets(const JSONRPCRequest& request) +static RPCHelpMan listwallets() { - RPCHelpMan{"listwallets", + return RPCHelpMan{"listwallets", "Returns a list of currently loaded wallets.\n" "For full information on the wallet, use \"getwalletinfo\"\n", {}, @@ -2467,8 +2527,8 @@ static UniValue listwallets(const JSONRPCRequest& request) HelpExampleCli("listwallets", "") + HelpExampleRpc("listwallets", "") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ UniValue obj(UniValue::VARR); for (const std::shared_ptr<CWallet>& wallet : GetWallets()) { @@ -2477,11 +2537,13 @@ static UniValue listwallets(const JSONRPCRequest& request) } return obj; +}, + }; } -static UniValue loadwallet(const JSONRPCRequest& request) +static RPCHelpMan loadwallet() { - RPCHelpMan{"loadwallet", + return RPCHelpMan{"loadwallet", "\nLoads a wallet from a wallet file or directory." "\nNote that all wallet command-line options used when starting bitcoind will be" "\napplied to the new wallet (eg -rescan, etc).\n", @@ -2500,8 +2562,8 @@ static UniValue loadwallet(const JSONRPCRequest& request) HelpExampleCli("loadwallet", "\"test.dat\"") + HelpExampleRpc("loadwallet", "\"test.dat\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ WalletContext& context = EnsureWalletContext(request.context); const std::string name(request.params[0].get_str()); @@ -2524,15 +2586,18 @@ static UniValue loadwallet(const JSONRPCRequest& request) obj.pushKV("warning", Join(warnings, Untranslated("\n")).original); return obj; +}, + }; } -static UniValue setwalletflag(const JSONRPCRequest& request) +static RPCHelpMan setwalletflag() { std::string flags = ""; for (auto& it : WALLET_FLAG_MAP) if (it.second & MUTABLE_WALLET_FLAGS) flags += (flags == "" ? "" : ", ") + it.first; - RPCHelpMan{"setwalletflag", + + return RPCHelpMan{"setwalletflag", "\nChange the state of the given wallet flag for a wallet.\n", { {"flag", RPCArg::Type::STR, RPCArg::Optional::NO, "The name of the flag to change. Current available flags: " + flags}, @@ -2550,8 +2615,8 @@ static UniValue setwalletflag(const JSONRPCRequest& request) HelpExampleCli("setwalletflag", "avoid_reuse") + HelpExampleRpc("setwalletflag", "\"avoid_reuse\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -2589,11 +2654,13 @@ static UniValue setwalletflag(const JSONRPCRequest& request) } return res; +}, + }; } -static UniValue createwallet(const JSONRPCRequest& request) +static RPCHelpMan createwallet() { - RPCHelpMan{ + return RPCHelpMan{ "createwallet", "\nCreates and loads a new wallet.\n", { @@ -2616,8 +2683,8 @@ static UniValue createwallet(const JSONRPCRequest& request) HelpExampleCli("createwallet", "\"testwallet\"") + HelpExampleRpc("createwallet", "\"testwallet\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ WalletContext& context = EnsureWalletContext(request.context); uint64_t flags = 0; if (!request.params[1].isNull() && request.params[1].get_bool()) { @@ -2664,11 +2731,13 @@ static UniValue createwallet(const JSONRPCRequest& request) obj.pushKV("warning", Join(warnings, Untranslated("\n")).original); return obj; +}, + }; } -static UniValue unloadwallet(const JSONRPCRequest& request) +static RPCHelpMan unloadwallet() { - RPCHelpMan{"unloadwallet", + return RPCHelpMan{"unloadwallet", "Unloads the wallet referenced by the request endpoint otherwise unloads the wallet specified in the argument.\n" "Specifying the wallet name on a wallet endpoint is invalid.", { @@ -2682,8 +2751,8 @@ static UniValue unloadwallet(const JSONRPCRequest& request) HelpExampleCli("unloadwallet", "wallet_name") + HelpExampleRpc("unloadwallet", "wallet_name") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::string wallet_name; if (GetWalletNameFromJSONRPCRequest(request, wallet_name)) { if (!request.params[0].isNull()) { @@ -2712,11 +2781,13 @@ static UniValue unloadwallet(const JSONRPCRequest& request) UniValue result(UniValue::VOBJ); result.pushKV("warning", Join(warnings, Untranslated("\n")).original); return result; +}, + }; } -static UniValue listunspent(const JSONRPCRequest& request) +static RPCHelpMan listunspent() { - RPCHelpMan{ + return RPCHelpMan{ "listunspent", "\nReturns array of unspent transaction outputs\n" "with between minconf and maxconf (inclusive) confirmations.\n" @@ -2771,8 +2842,8 @@ static UniValue listunspent(const JSONRPCRequest& request) + HelpExampleCli("listunspent", "6 9999999 '[]' true '{ \"minimumAmount\": 0.005 }'") + HelpExampleRpc("listunspent", "6, 9999999, [] , true, { \"minimumAmount\": 0.005 } ") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -2933,6 +3004,8 @@ static UniValue listunspent(const JSONRPCRequest& request) } return results; +}, + }; } void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& fee_out, int& change_position, UniValue options, CCoinControl& coinControl) @@ -3064,9 +3137,9 @@ void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& f } } -static UniValue fundrawtransaction(const JSONRPCRequest& request) +static RPCHelpMan fundrawtransaction() { - RPCHelpMan{"fundrawtransaction", + return RPCHelpMan{"fundrawtransaction", "\nIf the transaction has no inputs, they will be automatically selected to meet its out value.\n" "It will add at most one change output to the outputs.\n" "No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n" @@ -3132,8 +3205,8 @@ static UniValue fundrawtransaction(const JSONRPCRequest& request) "\nSend the transaction\n" + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -3161,11 +3234,13 @@ static UniValue fundrawtransaction(const JSONRPCRequest& request) result.pushKV("changepos", change_position); return result; +}, + }; } -UniValue signrawtransactionwithwallet(const JSONRPCRequest& request) +RPCHelpMan signrawtransactionwithwallet() { - RPCHelpMan{"signrawtransactionwithwallet", + return RPCHelpMan{"signrawtransactionwithwallet", "\nSign inputs for raw transaction (serialized, hex-encoded).\n" "The second optional argument (may be null) is an array of previous transaction outputs that\n" "this transaction depends on but may not yet be in the block chain." + @@ -3216,8 +3291,8 @@ UniValue signrawtransactionwithwallet(const JSONRPCRequest& request) HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"") + HelpExampleRpc("signrawtransactionwithwallet", "\"myhex\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -3252,13 +3327,15 @@ UniValue signrawtransactionwithwallet(const JSONRPCRequest& request) UniValue result(UniValue::VOBJ); SignTransactionResultToJSON(mtx, complete, coins, input_errors, result); return result; +}, + }; } -static UniValue bumpfee(const JSONRPCRequest& request) +static RPCHelpMan bumpfee_helper(std::string method_name) { - bool want_psbt = request.strMethod == "psbtbumpfee"; + bool want_psbt = method_name == "psbtbumpfee"; - RPCHelpMan{request.strMethod, + return RPCHelpMan{method_name, "\nBumps the fee of an opt-in-RBF transaction T, replacing it with a new transaction B.\n" + std::string(want_psbt ? "Returns a PSBT instead of creating and signing a new transaction.\n" : "") + "An opt-in RBF transaction with the given txid must be in the wallet.\n" @@ -3308,10 +3385,10 @@ static UniValue bumpfee(const JSONRPCRequest& request) }, RPCExamples{ "\nBump the fee, get the new transaction\'s" + std::string(want_psbt ? "psbt" : "txid") + "\n" + - HelpExampleCli(request.strMethod, "<txid>") + HelpExampleCli(method_name, "<txid>") }, - }.Check(request); - + [want_psbt](const RPCHelpMan& self, const JSONRPCRequest& request) mutable -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -3438,16 +3515,16 @@ static UniValue bumpfee(const JSONRPCRequest& request) result.pushKV("errors", result_errors); return result; +}, + }; } -static UniValue psbtbumpfee(const JSONRPCRequest& request) -{ - return bumpfee(request); -} +static RPCHelpMan bumpfee() { return bumpfee_helper("bumpfee"); } +static RPCHelpMan psbtbumpfee() { return bumpfee_helper("psbtbumpfee"); } -UniValue rescanblockchain(const JSONRPCRequest& request) +static RPCHelpMan rescanblockchain() { - RPCHelpMan{"rescanblockchain", + return RPCHelpMan{"rescanblockchain", "\nRescan the local blockchain for wallet related transactions.\n" "Note: Use \"getwalletinfo\" to query the scanning progress.\n", { @@ -3465,8 +3542,8 @@ UniValue rescanblockchain(const JSONRPCRequest& request) HelpExampleCli("rescanblockchain", "100000 120000") + HelpExampleRpc("rescanblockchain", "100000, 120000") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -3522,6 +3599,8 @@ UniValue rescanblockchain(const JSONRPCRequest& request) response.pushKV("start_height", start_height); response.pushKV("stop_height", result.last_scanned_height ? *result.last_scanned_height : UniValue()); return response; +}, + }; } class DescribeWalletAddressVisitor : public boost::static_visitor<UniValue> @@ -3641,9 +3720,9 @@ static UniValue AddressBookDataToJSON(const CAddressBookData& data, const bool v return ret; } -UniValue getaddressinfo(const JSONRPCRequest& request) +RPCHelpMan getaddressinfo() { - RPCHelpMan{"getaddressinfo", + return RPCHelpMan{"getaddressinfo", "\nReturn information about the given bitcoin address.\n" "Some of the information will only be present if the address is in the active wallet.\n", { @@ -3694,8 +3773,8 @@ UniValue getaddressinfo(const JSONRPCRequest& request) HelpExampleCli("getaddressinfo", "\"" + EXAMPLE_ADDRESS[0] + "\"") + HelpExampleRpc("getaddressinfo", "\"" + EXAMPLE_ADDRESS[0] + "\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -3759,11 +3838,13 @@ UniValue getaddressinfo(const JSONRPCRequest& request) ret.pushKV("labels", std::move(labels)); return ret; +}, + }; } -static UniValue getaddressesbylabel(const JSONRPCRequest& request) +static RPCHelpMan getaddressesbylabel() { - RPCHelpMan{"getaddressesbylabel", + return RPCHelpMan{"getaddressesbylabel", "\nReturns the list of addresses assigned the specified label.\n", { {"label", RPCArg::Type::STR, RPCArg::Optional::NO, "The label."}, @@ -3781,8 +3862,8 @@ static UniValue getaddressesbylabel(const JSONRPCRequest& request) HelpExampleCli("getaddressesbylabel", "\"tabby\"") + HelpExampleRpc("getaddressesbylabel", "\"tabby\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -3816,11 +3897,13 @@ static UniValue getaddressesbylabel(const JSONRPCRequest& request) } return ret; +}, + }; } -static UniValue listlabels(const JSONRPCRequest& request) +static RPCHelpMan listlabels() { - RPCHelpMan{"listlabels", + return RPCHelpMan{"listlabels", "\nReturns the list of all labels, or labels that are assigned to addresses with a specific purpose.\n", { {"purpose", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "Address purpose to list labels for ('send','receive'). An empty string is the same as not providing this argument."}, @@ -3841,8 +3924,8 @@ static UniValue listlabels(const JSONRPCRequest& request) "\nAs a JSON-RPC call\n" + HelpExampleRpc("listlabels", "receive") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -3869,6 +3952,8 @@ static UniValue listlabels(const JSONRPCRequest& request) } return ret; +}, + }; } static RPCHelpMan send() @@ -4050,9 +4135,9 @@ static RPCHelpMan send() }; } -UniValue sethdseed(const JSONRPCRequest& request) +static RPCHelpMan sethdseed() { - RPCHelpMan{"sethdseed", + return RPCHelpMan{"sethdseed", "\nSet or generate a new HD wallet seed. Non-HD wallets will not be upgraded to being a HD wallet. Wallets that are already\n" "HD will have a new HD seed set so that new keys added to the keypool will be derived from this new seed.\n" "\nNote that you will need to MAKE A NEW BACKUP of your wallet after setting the HD wallet seed." + @@ -4072,8 +4157,8 @@ UniValue sethdseed(const JSONRPCRequest& request) + HelpExampleCli("sethdseed", "true \"wifkey\"") + HelpExampleRpc("sethdseed", "true, \"wifkey\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -4118,11 +4203,13 @@ UniValue sethdseed(const JSONRPCRequest& request) if (flush_key_pool) spk_man.NewKeyPool(); return NullUniValue; +}, + }; } -UniValue walletprocesspsbt(const JSONRPCRequest& request) +static RPCHelpMan walletprocesspsbt() { - RPCHelpMan{"walletprocesspsbt", + return RPCHelpMan{"walletprocesspsbt", "\nUpdate a PSBT with input information from our wallet and then sign inputs\n" "that we can sign for." + HELP_REQUIRING_PASSPHRASE, @@ -4148,8 +4235,8 @@ UniValue walletprocesspsbt(const JSONRPCRequest& request) RPCExamples{ HelpExampleCli("walletprocesspsbt", "\"psbt\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; const CWallet* const pwallet = wallet.get(); @@ -4182,11 +4269,13 @@ UniValue walletprocesspsbt(const JSONRPCRequest& request) result.pushKV("complete", complete); return result; +}, + }; } -UniValue walletcreatefundedpsbt(const JSONRPCRequest& request) +static RPCHelpMan walletcreatefundedpsbt() { - RPCHelpMan{"walletcreatefundedpsbt", + return RPCHelpMan{"walletcreatefundedpsbt", "\nCreates and funds a transaction in the Partially Signed Transaction format.\n" "Implements the Creator and Updater roles.\n", { @@ -4257,8 +4346,8 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request) "\nCreate a transaction with no inputs\n" + HelpExampleCli("walletcreatefundedpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") }, - }.Check(request); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -4307,11 +4396,13 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request) result.pushKV("fee", ValueFromAmount(fee)); result.pushKV("changepos", change_position); return result; +}, + }; } -static UniValue upgradewallet(const JSONRPCRequest& request) +static RPCHelpMan upgradewallet() { - RPCHelpMan{"upgradewallet", + return RPCHelpMan{"upgradewallet", "\nUpgrade the wallet. Upgrades to the latest version if no version number is specified\n" "New keys may be generated and a new wallet backup will need to be made.", { @@ -4321,9 +4412,9 @@ static UniValue upgradewallet(const JSONRPCRequest& request) RPCExamples{ HelpExampleCli("upgradewallet", "169900") + HelpExampleRpc("upgradewallet", "169900") - } - }.Check(request); - + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); if (!wallet) return NullUniValue; CWallet* const pwallet = wallet.get(); @@ -4343,6 +4434,8 @@ static UniValue upgradewallet(const JSONRPCRequest& request) throw JSONRPCError(RPC_WALLET_ERROR, error.original); } return error.original; +}, + }; } RPCHelpMan abortrescan(); diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h index fb1e91282b..184a16e91d 100644 --- a/src/wallet/rpcwallet.h +++ b/src/wallet/rpcwallet.h @@ -34,6 +34,6 @@ void EnsureWalletIsUnlocked(const CWallet*); WalletContext& EnsureWalletContext(const util::Ref& context); LegacyScriptPubKeyMan& EnsureLegacyScriptPubKeyMan(CWallet& wallet, bool also_create = false); -UniValue getaddressinfo(const JSONRPCRequest& request); -UniValue signrawtransactionwithwallet(const JSONRPCRequest& request); +RPCHelpMan getaddressinfo(); +RPCHelpMan signrawtransactionwithwallet(); #endif //BITCOIN_WALLET_RPCWALLET_H |