Skip to content

Commit 5e14faf

Browse files
author
MarcoFalke
committed
Merge bitcoin#19994: Assert that RPCArg names are equal to CRPCCommand ones (net, rpcwallet)
fa14f57 Assert that RPCArg names are equal to CRPCCommand ones (net, rpcwallet) (MarcoFalke) Pull request description: This is the last part split out from bitcoin#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 bitcoin#18607 * The changes itself fixed bug bitcoin#19250 ACKs for top commit: fjahr: tACK fa14f57 ryanofsky: Code review ACK fa14f57. Just straightforward replacements except code moved in `addnode`, and displatching updated in `bumpfee_helper` Tree-SHA512: e07af150f1d95a88e558256ce197a6b7dc6cd722a6d6c13c75d944c49c2e2441f8b8237e9f94b03db69fa18f9bda627b0781d5e1da70bf5415e09b38728a8cb1
2 parents 8235dca + fa14f57 commit 5e14faf

File tree

3 files changed

+381
-254
lines changed

3 files changed

+381
-254
lines changed

src/rpc/net.cpp

+91-57
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@
2929

3030
#include <univalue.h>
3131

32-
static UniValue getconnectioncount(const JSONRPCRequest& request)
32+
static RPCHelpMan getconnectioncount()
3333
{
34-
RPCHelpMan{"getconnectioncount",
34+
return RPCHelpMan{"getconnectioncount",
3535
"\nReturns the number of connections to other nodes.\n",
3636
{},
3737
RPCResult{
@@ -41,18 +41,20 @@ static UniValue getconnectioncount(const JSONRPCRequest& request)
4141
HelpExampleCli("getconnectioncount", "")
4242
+ HelpExampleRpc("getconnectioncount", "")
4343
},
44-
}.Check(request);
45-
44+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
45+
{
4646
NodeContext& node = EnsureNodeContext(request.context);
4747
if(!node.connman)
4848
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
4949

5050
return (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_ALL);
51+
},
52+
};
5153
}
5254

53-
static UniValue ping(const JSONRPCRequest& request)
55+
static RPCHelpMan ping()
5456
{
55-
RPCHelpMan{"ping",
57+
return RPCHelpMan{"ping",
5658
"\nRequests that a ping be sent to all other nodes, to measure ping time.\n"
5759
"Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds.\n"
5860
"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)
6264
HelpExampleCli("ping", "")
6365
+ HelpExampleRpc("ping", "")
6466
},
65-
}.Check(request);
66-
67+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
68+
{
6769
NodeContext& node = EnsureNodeContext(request.context);
6870
if(!node.connman)
6971
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
@@ -73,11 +75,13 @@ static UniValue ping(const JSONRPCRequest& request)
7375
pnode->fPingQueued = true;
7476
});
7577
return NullUniValue;
78+
},
79+
};
7680
}
7781

78-
static UniValue getpeerinfo(const JSONRPCRequest& request)
82+
static RPCHelpMan getpeerinfo()
7983
{
80-
RPCHelpMan{"getpeerinfo",
84+
return RPCHelpMan{"getpeerinfo",
8185
"\nReturns data about each connected network node as a json array of objects.\n",
8286
{},
8387
RPCResult{
@@ -142,8 +146,8 @@ static UniValue getpeerinfo(const JSONRPCRequest& request)
142146
HelpExampleCli("getpeerinfo", "")
143147
+ HelpExampleRpc("getpeerinfo", "")
144148
},
145-
}.Check(request);
146-
149+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
150+
{
147151
NodeContext& node = EnsureNodeContext(request.context);
148152
if(!node.connman)
149153
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
@@ -233,17 +237,13 @@ static UniValue getpeerinfo(const JSONRPCRequest& request)
233237
}
234238

235239
return ret;
240+
},
241+
};
236242
}
237243

238-
static UniValue addnode(const JSONRPCRequest& request)
244+
static RPCHelpMan addnode()
239245
{
240-
std::string strCommand;
241-
if (!request.params[1].isNull())
242-
strCommand = request.params[1].get_str();
243-
if (request.fHelp || request.params.size() != 2 ||
244-
(strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
245-
throw std::runtime_error(
246-
RPCHelpMan{"addnode",
246+
return RPCHelpMan{"addnode",
247247
"\nAttempts to add or remove a node from the addnode list.\n"
248248
"Or try a connection to a node once.\n"
249249
"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)
257257
HelpExampleCli("addnode", "\"192.168.0.6:8333\" \"onetry\"")
258258
+ HelpExampleRpc("addnode", "\"192.168.0.6:8333\", \"onetry\"")
259259
},
260-
}.ToString());
260+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
261+
{
262+
std::string strCommand;
263+
if (!request.params[1].isNull())
264+
strCommand = request.params[1].get_str();
265+
if (request.fHelp || request.params.size() != 2 ||
266+
(strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
267+
throw std::runtime_error(
268+
self.ToString());
261269

262270
NodeContext& node = EnsureNodeContext(request.context);
263271
if(!node.connman)
@@ -284,11 +292,13 @@ static UniValue addnode(const JSONRPCRequest& request)
284292
}
285293

286294
return NullUniValue;
295+
},
296+
};
287297
}
288298

289-
static UniValue disconnectnode(const JSONRPCRequest& request)
299+
static RPCHelpMan disconnectnode()
290300
{
291-
RPCHelpMan{"disconnectnode",
301+
return RPCHelpMan{"disconnectnode",
292302
"\nImmediately disconnects from the specified peer node.\n"
293303
"\nStrictly one out of 'address' and 'nodeid' can be provided to identify the node.\n"
294304
"\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)
303313
+ HelpExampleRpc("disconnectnode", "\"192.168.0.6:8333\"")
304314
+ HelpExampleRpc("disconnectnode", "\"\", 1")
305315
},
306-
}.Check(request);
307-
316+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
317+
{
308318
NodeContext& node = EnsureNodeContext(request.context);
309319
if(!node.connman)
310320
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
@@ -329,11 +339,13 @@ static UniValue disconnectnode(const JSONRPCRequest& request)
329339
}
330340

331341
return NullUniValue;
342+
},
343+
};
332344
}
333345

334-
static UniValue getaddednodeinfo(const JSONRPCRequest& request)
346+
static RPCHelpMan getaddednodeinfo()
335347
{
336-
RPCHelpMan{"getaddednodeinfo",
348+
return RPCHelpMan{"getaddednodeinfo",
337349
"\nReturns information about the given added node, or all added nodes\n"
338350
"(note that onetry addnodes are not listed here)\n",
339351
{
@@ -361,8 +373,8 @@ static UniValue getaddednodeinfo(const JSONRPCRequest& request)
361373
HelpExampleCli("getaddednodeinfo", "\"192.168.0.201\"")
362374
+ HelpExampleRpc("getaddednodeinfo", "\"192.168.0.201\"")
363375
},
364-
}.Check(request);
365-
376+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
377+
{
366378
NodeContext& node = EnsureNodeContext(request.context);
367379
if(!node.connman)
368380
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
@@ -401,11 +413,13 @@ static UniValue getaddednodeinfo(const JSONRPCRequest& request)
401413
}
402414

403415
return ret;
416+
},
417+
};
404418
}
405419

406-
static UniValue getnettotals(const JSONRPCRequest& request)
420+
static RPCHelpMan getnettotals()
407421
{
408-
RPCHelpMan{"getnettotals",
422+
return RPCHelpMan{"getnettotals",
409423
"\nReturns information about network traffic, including bytes in, bytes out,\n"
410424
"and current time.\n",
411425
{},
@@ -430,7 +444,8 @@ static UniValue getnettotals(const JSONRPCRequest& request)
430444
HelpExampleCli("getnettotals", "")
431445
+ HelpExampleRpc("getnettotals", "")
432446
},
433-
}.Check(request);
447+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
448+
{
434449
NodeContext& node = EnsureNodeContext(request.context);
435450
if(!node.connman)
436451
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
@@ -449,6 +464,8 @@ static UniValue getnettotals(const JSONRPCRequest& request)
449464
outboundLimit.pushKV("time_left_in_cycle", node.connman->GetMaxOutboundTimeLeftInCycle());
450465
obj.pushKV("uploadtarget", outboundLimit);
451466
return obj;
467+
},
468+
};
452469
}
453470

454471
static UniValue GetNetworksInfo()
@@ -472,9 +489,9 @@ static UniValue GetNetworksInfo()
472489
return networks;
473490
}
474491

475-
static UniValue getnetworkinfo(const JSONRPCRequest& request)
492+
static RPCHelpMan getnetworkinfo()
476493
{
477-
RPCHelpMan{"getnetworkinfo",
494+
return RPCHelpMan{"getnetworkinfo",
478495
"Returns an object containing various state info regarding P2P networking.\n",
479496
{},
480497
RPCResult{
@@ -523,8 +540,8 @@ static UniValue getnetworkinfo(const JSONRPCRequest& request)
523540
HelpExampleCli("getnetworkinfo", "")
524541
+ HelpExampleRpc("getnetworkinfo", "")
525542
},
526-
}.Check(request);
527-
543+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
544+
{
528545
LOCK(cs_main);
529546
UniValue obj(UniValue::VOBJ);
530547
obj.pushKV("version", CLIENT_VERSION);
@@ -562,11 +579,13 @@ static UniValue getnetworkinfo(const JSONRPCRequest& request)
562579
obj.pushKV("localaddresses", localAddresses);
563580
obj.pushKV("warnings", GetWarnings(false).original);
564581
return obj;
582+
},
583+
};
565584
}
566585

567-
static UniValue setban(const JSONRPCRequest& request)
586+
static RPCHelpMan setban()
568587
{
569-
const RPCHelpMan help{"setban",
588+
return RPCHelpMan{"setban",
570589
"\nAttempts to add or remove an IP/Subnet from the banned list.\n",
571590
{
572591
{"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)
580599
+ HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"")
581600
+ HelpExampleRpc("setban", "\"192.168.0.6\", \"add\", 86400")
582601
},
583-
};
602+
[&](const RPCHelpMan& help, const JSONRPCRequest& request) -> UniValue
603+
{
584604
std::string strCommand;
585605
if (!request.params[1].isNull())
586606
strCommand = request.params[1].get_str();
@@ -643,11 +663,13 @@ static UniValue setban(const JSONRPCRequest& request)
643663
}
644664
}
645665
return NullUniValue;
666+
},
667+
};
646668
}
647669

648-
static UniValue listbanned(const JSONRPCRequest& request)
670+
static RPCHelpMan listbanned()
649671
{
650-
RPCHelpMan{"listbanned",
672+
return RPCHelpMan{"listbanned",
651673
"\nList all manually banned IPs/Subnets.\n",
652674
{},
653675
RPCResult{RPCResult::Type::ARR, "", "",
@@ -663,8 +685,8 @@ static UniValue listbanned(const JSONRPCRequest& request)
663685
HelpExampleCli("listbanned", "")
664686
+ HelpExampleRpc("listbanned", "")
665687
},
666-
}.Check(request);
667-
688+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
689+
{
668690
NodeContext& node = EnsureNodeContext(request.context);
669691
if(!node.banman) {
670692
throw JSONRPCError(RPC_DATABASE_ERROR, "Error: Ban database not loaded");
@@ -686,19 +708,22 @@ static UniValue listbanned(const JSONRPCRequest& request)
686708
}
687709

688710
return bannedAddresses;
711+
},
712+
};
689713
}
690714

691-
static UniValue clearbanned(const JSONRPCRequest& request)
715+
static RPCHelpMan clearbanned()
692716
{
693-
RPCHelpMan{"clearbanned",
717+
return RPCHelpMan{"clearbanned",
694718
"\nClear all banned IPs.\n",
695719
{},
696720
RPCResult{RPCResult::Type::NONE, "", ""},
697721
RPCExamples{
698722
HelpExampleCli("clearbanned", "")
699723
+ HelpExampleRpc("clearbanned", "")
700724
},
701-
}.Check(request);
725+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
726+
{
702727
NodeContext& node = EnsureNodeContext(request.context);
703728
if (!node.banman) {
704729
throw JSONRPCError(RPC_DATABASE_ERROR, "Error: Ban database not loaded");
@@ -707,19 +732,21 @@ static UniValue clearbanned(const JSONRPCRequest& request)
707732
node.banman->ClearBanned();
708733

709734
return NullUniValue;
735+
},
736+
};
710737
}
711738

712-
static UniValue setnetworkactive(const JSONRPCRequest& request)
739+
static RPCHelpMan setnetworkactive()
713740
{
714-
RPCHelpMan{"setnetworkactive",
741+
return RPCHelpMan{"setnetworkactive",
715742
"\nDisable/enable all p2p network activity.\n",
716743
{
717744
{"state", RPCArg::Type::BOOL, RPCArg::Optional::NO, "true to enable networking, false to disable"},
718745
},
719746
RPCResult{RPCResult::Type::BOOL, "", "The value that was passed in"},
720747
RPCExamples{""},
721-
}.Check(request);
722-
748+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
749+
{
723750
NodeContext& node = EnsureNodeContext(request.context);
724751
if (!node.connman) {
725752
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
@@ -728,11 +755,13 @@ static UniValue setnetworkactive(const JSONRPCRequest& request)
728755
node.connman->SetNetworkActive(request.params[0].get_bool());
729756

730757
return node.connman->GetNetworkActive();
758+
},
759+
};
731760
}
732761

733-
static UniValue getnodeaddresses(const JSONRPCRequest& request)
762+
static RPCHelpMan getnodeaddresses()
734763
{
735-
RPCHelpMan{"getnodeaddresses",
764+
return RPCHelpMan{"getnodeaddresses",
736765
"\nReturn known addresses which can potentially be used to find new nodes in the network\n",
737766
{
738767
{"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)
753782
HelpExampleCli("getnodeaddresses", "8")
754783
+ HelpExampleRpc("getnodeaddresses", "8")
755784
},
756-
}.Check(request);
785+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
786+
{
757787
NodeContext& node = EnsureNodeContext(request.context);
758788
if (!node.connman) {
759789
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
@@ -779,11 +809,13 @@ static UniValue getnodeaddresses(const JSONRPCRequest& request)
779809
ret.push_back(obj);
780810
}
781811
return ret;
812+
},
813+
};
782814
}
783815

784-
static UniValue addpeeraddress(const JSONRPCRequest& request)
816+
static RPCHelpMan addpeeraddress()
785817
{
786-
RPCHelpMan{"addpeeraddress",
818+
return RPCHelpMan{"addpeeraddress",
787819
"\nAdd the address of a potential peer to the address manager. This RPC is for testing only.\n",
788820
{
789821
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP address of the peer"},
@@ -799,8 +831,8 @@ static UniValue addpeeraddress(const JSONRPCRequest& request)
799831
HelpExampleCli("addpeeraddress", "\"1.2.3.4\" 8333")
800832
+ HelpExampleRpc("addpeeraddress", "\"1.2.3.4\", 8333")
801833
},
802-
}.Check(request);
803-
834+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
835+
{
804836
NodeContext& node = EnsureNodeContext(request.context);
805837
if (!node.connman) {
806838
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
@@ -827,6 +859,8 @@ static UniValue addpeeraddress(const JSONRPCRequest& request)
827859

828860
obj.pushKV("success", true);
829861
return obj;
862+
},
863+
};
830864
}
831865

832866
void RegisterNetRPCCommands(CRPCTable &t)

0 commit comments

Comments
 (0)