-
Notifications
You must be signed in to change notification settings - Fork 35.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rpc: Assert that RPCArg names are equal to CRPCCommand ones (server) #19386
Conversation
fa2b206
to
fac2edb
Compare
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
Concept ACK.
FWIW I dislike the idea of doing this at run-time. We don't want RPC to suddenly crash because an argument doesn't match its specified type in the help.
This is somewhat difficult. It was considered in the past but
|
Good idea. This could be hidden behind
Makes sense. I think I will keep the linter/test around, but make it less fragile by removing the regex parsing, which has been broken in the past at least once. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code review ACK fac2edb. This is a great way of getting rid of redundant RPC metadata without requiring invasive changes. Also thanks from splitting this out from the more overwhelmingly sized #18531.
re: #19386 (comment)
FWIW I dislike the idea of doing this at run-time
I think it's important to distinguish three types of checking
- Build time checking
- Run time checking in unit tests or at startup
- Run time checking at every method call
I think 1 & 2 are both perfectly good places to catch wrongly declared RPC methods. Only 3 is a bad place.
src/rpc/util.h
Outdated
@@ -329,6 +329,11 @@ class RPCHelpMan | |||
public: | |||
RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples); | |||
using RPCMethod = std::function<UniValue(const RPCHelpMan&, const JSONRPCRequest&)>; | |||
struct HiddenArg { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In commit " rpc: Assert that passed arg names are equal to hardcoded ones (server)" (fac2edb)
It seems like it might be cleaner if instead of adding a new HiddenArg struct, and new RPCHelpMan constructor and special case code for m_hidden_arg in GetArgNames, this just added a new RPCArg::Type::HIDDEN
type. This would also support multiple hidden args, or hidden args after non-hidden args.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hidden args should not be a thing, because I can't imagine a use case for them.
If they are needed for testing, a new (hidden) RPC method with un-hidden RPC arguments should be added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re: #19386 (comment)
Hidden args should not be a thing, because I can't imagine a use case for them.
If they are needed for testing, a new (hidden) RPC method with un-hidden RPC arguments should be added.
Beyond testing, undocumented hidden args also seem useful as a way of removing options we no longer want to support like wallet account and min_conf arguments in some places, and still maintaining compatibility when arguments are set to specific values (e.g. min_conf=1, account="*").
But regardless of whether hidden args will be used in the future, adding a Type::HIDDEN
enum value seems like a simpler way to implement hidden args now than adding a HiddenArg
struct and alternate code path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Beyond testing, undocumented hidden args also seem useful as a way of removing options
I disagree. The RPC interface seems the wrong place to hide options in the documentation but then still accept them. For deprecation we use -rpcdeprecated
and proper updates to the documentation to say an argument has been deprecated or is discouraged. (Edit: Making an option hidden will only hide the documentation that says the argument has been deprecated and thus will have the opposite effect of what was intended, no?)
I plan to remove HiddenArg
before the next release, so the implementation shouldn't matter as long as it is minimal and correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK.
fac2edb
to
fabb011
Compare
This allows the constructor to ask the rpc manager for the name of the rpc method or the rpc argument names instead of having it manually passed in.
fa7276a
to
fa87adf
Compare
Addressed feedback. Sorry for the intermediate force-pushes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code review ACK fa87adf. Changes since previous review: removing redundant throw, renaming some things, adding RPCHelpMan::HandleRequest
method to replace macro, changing commit order.
So suggestion from #19386 (comment) doesn't get lost, I think HandleRequest(request)
method could call Check(request)
, so every individual method doesn't have to check its own arguments.
src/rpc/util.h
Outdated
@@ -329,6 +329,11 @@ class RPCHelpMan | |||
public: | |||
RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples); | |||
using RPCMethod = std::function<UniValue(const RPCHelpMan&, const JSONRPCRequest&)>; | |||
struct HiddenArg { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re: #19386 (comment)
Hidden args should not be a thing, because I can't imagine a use case for them.
If they are needed for testing, a new (hidden) RPC method with un-hidden RPC arguments should be added.
Beyond testing, undocumented hidden args also seem useful as a way of removing options we no longer want to support like wallet account and min_conf arguments in some places, and still maintaining compatibility when arguments are set to specific values (e.g. min_conf=1, account="*").
But regardless of whether hidden args will be used in the future, adding a Type::HIDDEN
enum value seems like a simpler way to implement hidden args now than adding a HiddenArg
struct and alternate code path.
fa87adf
to
faccf86
Compare
Also, update switch statments to our style guide
Also, move Check to inside HandleRequest
faccf86
to
fa7592b
Compare
Thanks. Fixed and force pushed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code review ACK fa7592b. Looks great! Just some hidden arg and Check() and comment cleanups since last review
ACK fa7592b
I agree. The regexs were a quick hack. More robust parsing would definitely make sense. It's too bad that there's no portable/low-dependency way to get the C++ syntax tree and extract information from a program without some monstriosity hand-rolled thing. |
…ommand ones (server) fa7592b rpc: Update server to use new RPCHelpMan (MarcoFalke) aaaaad5 rpc: Add option to hide RPCArg (MarcoFalke) fa9708f rpc: Assert that passed arg names are equal to hardcoded ones (MarcoFalke) faaeb2b rpc: Add CRPCCommand constructor which takes RPCHelpMan (MarcoFalke) fa8ec00 rpc: Check that left section is not multiline (MarcoFalke) Pull request description: This is split out from bitcoin#18531 to just touch the RPC methods in server. 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: laanwj: ACK fa7592b ryanofsky: Code review ACK fa7592b. Looks great! Just some hidden arg and Check() and comment cleanups since last review Tree-SHA512: e64b6a212f4a3aeedeee47557559bde104d5fd40cdc1746b27eb2f3d4c8885d5e6e4dd287595ea11cdbc6a939654fe103cae765fd505875444d851f0abb11308
…ommand ones (server) fa7592b rpc: Update server to use new RPCHelpMan (MarcoFalke) aaaaad5 rpc: Add option to hide RPCArg (MarcoFalke) fa9708f rpc: Assert that passed arg names are equal to hardcoded ones (MarcoFalke) faaeb2b rpc: Add CRPCCommand constructor which takes RPCHelpMan (MarcoFalke) fa8ec00 rpc: Check that left section is not multiline (MarcoFalke) Pull request description: This is split out from bitcoin#18531 to just touch the RPC methods in server. 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: laanwj: ACK fa7592b ryanofsky: Code review ACK fa7592b. Looks great! Just some hidden arg and Check() and comment cleanups since last review Tree-SHA512: e64b6a212f4a3aeedeee47557559bde104d5fd40cdc1746b27eb2f3d4c8885d5e6e4dd287595ea11cdbc6a939654fe103cae765fd505875444d851f0abb11308
Summary: PR description: > 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 CRPCCommands 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). > > Changes > > The changes here add an assert in the CRPCCommand constructor that the RPCArg names are identical to the ones in the CRPCCommand. This is a backport of [[bitcoin/bitcoin#19386 | core#19386]] [1/5] bitcoin/bitcoin@fa8ec00 Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, majcosta Reviewed By: #bitcoin_abc, majcosta Differential Revision: https://reviews.bitcoinabc.org/D10006
Summary: This allows the constructor to ask the rpc manager for the name of the rpc method or the rpc argument names instead of having it manually passed in. Note: added underscores to some constructors' arguments to prevent shadowing fields, like previously done in D5906 This is a backport of [[bitcoin/bitcoin#19386 | core#19386]] [2/5] bitcoin/bitcoin@faaeb2b Depends on D10006 Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, majcosta Reviewed By: #bitcoin_abc, majcosta Differential Revision: https://reviews.bitcoinabc.org/D10007
Summary: This is a backport of [[bitcoin/bitcoin#19386 | core#19386]] [3/5] bitcoin/bitcoin@fa9708f Depends on D10007 Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, majcosta Reviewed By: #bitcoin_abc, majcosta Differential Revision: https://reviews.bitcoinabc.org/D10008
Summary: Also, update switch statments to our style guide This is a backport of [[bitcoin/bitcoin#19386 | core#19386]] [4/5] bitcoin/bitcoin@aaaaad5 Depends on D10008 Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, majcosta Reviewed By: #bitcoin_abc, majcosta Differential Revision: https://reviews.bitcoinabc.org/D10009
Summary: Also, move Check to inside HandleRequest This is a backport of [[bitcoin/bitcoin#19386 | core#19386]] bitcoin/bitcoin@fa7592b Depends on D10009 Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, majcosta, Fabien Reviewed By: #bitcoin_abc, majcosta, Fabien Subscribers: Fabien, majcosta Differential Revision: https://reviews.bitcoinabc.org/D10010
This is split out from #18531 to just touch the RPC methods in server. 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 theCRPCCommand
.Future work
Sure, but let's not get ahead of ourselves. I am going to submit any further works as follow-ups, including:
Bugs found