Skip to content

Conversation

@stickies-v
Copy link
Contributor

Adds string overloads for the RPCHelpMan::Arg and RPCHelpMan::MaybeArg helpers to be able to access RPC arguments by name instead of index number. Especially in RPCs with a large number of parameters, this can be quite helpful.

Example usage:

const auto action{self.Arg<std::string>("action")};

Most of the LoC is adding test coverage and documentation updates. No behaviour change.

An alternative approach to #27788 with significantly less overhaul.

@DrahtBot
Copy link
Contributor

DrahtBot commented Jan 18, 2024

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage

For detailed information about the code coverage, see the test coverage report.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK fjahr, maflcko, ryanofsky
Concept ACK ismaelsadeeq, tdb3

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

@ismaelsadeeq
Copy link
Member

Concept ACK

@DrahtBot
Copy link
Contributor

🚧 At least one of the CI tasks failed. Make sure to run all tests locally, according to the
documentation.

Possibly this is due to a silent merge conflict (the changes in this pull request being
incompatible with the current code in the target branch). If so, make sure to rebase on the latest
commit of the target branch.

Leave a comment here, if you need help tracking down a confusing failure.

Debug: https://github.com/bitcoin/bitcoin/runs/20633278087

@stickies-v stickies-v force-pushed the 2023-10/named-args-on-arg-helper branch from 2c222ea to d2369cb Compare January 18, 2024 22:41
@stickies-v
Copy link
Contributor Author

stickies-v commented Jan 19, 2024

Force pushed to make CI happy:

  • removed doxygen @params since it didn't pick up the overloads (and it's already documented in plain-text anyway)
  • added a null return type to the testing RPCHelpMan

Copy link
Contributor

@fjahr fjahr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK, certainly makes the RPC code more readable.

@stickies-v have you considered preparing a map once when an RPC is called rather than doing the search for the index every time an arg is accessed?

@maflcko
Copy link
Member

maflcko commented Feb 19, 2024

@stickies-v have you considered preparing a map once when an RPC is called rather than doing the search for the index every time an arg is accessed?

I doubt this will have any impact. It could even perform worse, and require more code? Also, maps aren't constexpr, so if this is moved toward constexpr/consteval, it will have to be re-written again.

@stickies-v stickies-v force-pushed the 2023-10/named-args-on-arg-helper branch from d2369cb to 3918736 Compare February 21, 2024 12:49
@stickies-v
Copy link
Contributor Author

Force pushed to address indentation issue (and removed the unintuitive "developer mistake" comment in docstring)

@stickies-v have you considered preparing a map once when an RPC is called rather than doing the search for the index every time an arg is accessed?

I agree with @maflcko's reasoning, so going to leave this as is.

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 3918736 🍔

Show signature

Signature:

untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
trusted comment: ACK 391873694137f241dfe1f57ed9058a438e147218 🍔
0mHHsiB/JX9sv6SH8E4hfbfpMPUipMUdvJ7diZjq+LEVBYg0u48Usa9OFR7sl0OdlDEJ3c64WImMfBoc80W4Bg==

@fjahr
Copy link
Contributor

fjahr commented Feb 21, 2024

I doubt this will have any impact. It could even perform worse, and require more code?

Same amount of code and I don't see how this would perform worse: fjahr@cbda2cf I also find this easier to reason about.

Also, maps aren't constexpr, so if this is moved toward constexpr/consteval, it will have to be re-written again.

I guess I don't have enough insight into future development plans of the RPC to judge that if is. But either way it seems weird to me that the best solution should be a find_if each time any argument is accessed (which comes out to O(n^2)), especially when we are already iterating over that information once before in the RPCHelperMan constructor. So it feels to me like this could be rewritten in the future just as likely.

@maflcko
Copy link
Member

maflcko commented Feb 21, 2024

Same amount of code and I don't see how this would perform worse: fjahr@cbda2cf I also find this easier to reason about.

You removed the CHECK_NONFATAL to mark the bug as an internal bug.

which comes out to O(n^2)

The O notation only makes sense for large n. Is there more than one RPC with more than n=3? Again, if you measure it, I wouldn't be surprised if the runtime is slower for a map. Though, you likely won't be able to find an end-to-end performance difference, regardless of what is used.

In any case, it shouldn't matter much, since apparently it can easily be reverted if the switch to constexpr is done.

Copy link
Contributor

@tdb3 tdb3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice addition. Increases readability.
Concept ACK.

Inline comment provided.

Built and exercised unit tests and rpc* functional tests. All passed.

Compare the results of self.Arg with the request.params accessors
to ensure they behave the same way.
Overload the Arg and MaybeArg helpers to allow accessing arguments
by name as well.

Also update the docs to document Arg and MaybeArg separately
Use the new key-based Arg helper in a few locations to show how
it is used.
@stickies-v stickies-v force-pushed the 2023-10/named-args-on-arg-helper branch from 3918736 to 30a6c99 Compare March 1, 2024 14:15
Copy link
Contributor Author

@stickies-v stickies-v left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Force-pushed to:

  • rebase to latest master to address CI failure (?)
  • fix some documentation inaccuracies (1, 2)
  • address some test nits (1, 2)
  • consistently use action variable in scantxoutset as per this comment

Thank you all for the review, apologies for the slow follow-up while I was on holidays.

Same amount of code and I don't see how this would perform worse: fjahr@cbda2cf I also find this easier to reason about.

Thank for writing out the code, I had assumed it'd be a bit more overhead (even after adding the CHECK_NONFATAL which can be done in just one line). I would still prefer to stick with the current approach. As maflcko suggests, the number of parameters is always going to be very small, so given that we don't have to allocate a map I'm unsure how this would perform differently but I don't think it's worth investigating given that both will be very fast. I do prefer this approach being more self-contained inside GetParamIndex, as opposed to adding another member variable and adding to the already verbose RPCHelpMan constructor, so will keep as is.

@maflcko
Copy link
Member

maflcko commented Apr 10, 2024

Does it work with OBJ_NAMED_PARAMS?

@stickies-v
Copy link
Contributor Author

Does it work with OBJ_NAMED_PARAMS?

Nope. I think we should just address the general use case of getting OBJ/ARR args with the Arg helpers, and then that should help with OBJ_NAMED_PARAMS too?

ChainstateManager& chainman = EnsureAnyChainman(request.context);
LOCK(cs_main);
return GetNetworkHashPS(self.Arg<int>(0), self.Arg<int>(1), chainman.ActiveChain());
return GetNetworkHashPS(self.Arg<int>("nblocks"), self.Arg<int>("height"), chainman.ActiveChain());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could make sense to remove the index-based access and require the name-based access?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in #29997

@fjahr
Copy link
Contributor

fjahr commented Apr 28, 2024

Code review ACK 30a6c99

I still prefer my suggested approach but it's still an improvement and I don't want to block this.

@DrahtBot DrahtBot requested review from maflcko and tdb3 April 28, 2024 19:49
@maflcko
Copy link
Member

maflcko commented Apr 29, 2024

ACK 30a6c99 🥑

Show signature

Signature:

untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
trusted comment: ACK 30a6c999351041d6a1e8712a9659be1296a1b46a 🥑
3lgAk6/J8fpwQT5TCz4m/ixg4qM63zVPfUgyz+Lr5wGYqRByfvE0Ol9M1LF33YNs0KZW2MwO0Ic4dnbvd2Q6BQ==

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review ACK 30a6c99. Nice change! Implementation is surprisingly simple and additional unit test coverage is welcome, too.

Does it work with OBJ_NAMED_PARAMS?

Nope. I think we should just address the general use case of getting OBJ/ARR args with the Arg helpers, and then that should help with OBJ_NAMED_PARAMS too?

It would be nice to support this for consistency, but benefit is probably more minor since these arguments are already accessed by name, and omitting this keeps the code very simple.

@ryanofsky ryanofsky merged commit 19865a8 into bitcoin:master Apr 29, 2024
@stickies-v stickies-v deleted the 2023-10/named-args-on-arg-helper branch April 29, 2024 14:50
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Apr 17, 2025
Summary:
Add arg helper unit test. Compare the results of self.Arg with the request.params accessors to ensure they behave the same way.

Overload the Arg and MaybeArg helpers to allow accessing arguments by name as well.

Also update the docs to document Arg and MaybeArg separately

Use the new key-based Arg helper in a few locations to show how it is used.

This is a backport of [[bitcoin/bitcoin#29277 | core#29277]]
Depends on D17946

Test Plan: `ninja all check-all`

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D17947
@bitcoin bitcoin locked and limited conversation to collaborators Apr 29, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants