Skip to content

Conversation

stickies-v
Copy link
Contributor

@stickies-v stickies-v commented Jul 15, 2025

The RPCHelpMan::{Arg,MaybeArg} helpers avoid copying (potentially) large strings by returning them as const std::string* (MaybeArg) or const std::string& (Arg). For MaybeArg, this has the not-so-nice effect that users need to deal with raw pointers, potentially also requiring new functions (e.g. EnsureUniqueWalletName ) with raw pointers being implemented.

This PR aims to improve on this by returning a trivially copyable std::string_view (Arg) or std::optional<std::string_view> (MaybeArg), modernizing the interface without introducing any additional copying overhead. In doing so, it also generalizes whether we return by value or by pointer/reference using std::is_trivially_copyable_v instead of defining the types manually.

In cases where functions currently take a const std::string& and it would be too much work / touching consensus logic to update them (signmessage.cpp), a std::string copy is made (which was already happening anyway).

The last 2 commits increase usage of the {Arg,MaybeArg}<std::string_view> helpers, and could be dropped/pruned if anything turns out to be controversial - I just think it's a nice little cleanup.

@DrahtBot
Copy link
Contributor

DrahtBot commented Jul 15, 2025

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

Code Coverage & Benchmarks

For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32983.

Reviews

See the guideline for information on the review process.

Type Reviewers
Stale ACK w0xlt, pablomartin4btc

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

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #32958 (wallet/refactor: change PSBTError to PSBTResult and remove std::optionalcommon::PSBTResult and return common::PSBTResult by kevkevinpal)
  • #32394 (net: make m_nodes_mutex non-recursive by vasild)
  • #32326 (net: improve the interface around FindNode() and avoid a recursive mutex lock by vasild)
  • #32065 (i2p: make a time gap between creating transient sessions and using them by vasild)
  • #31560 (rpc: allow writing UTXO set to a named pipe, introduce dump_to_sqlite.sh script by theStack)

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.

Copy link
Contributor

@w0xlt w0xlt left a comment

Choose a reason for hiding this comment

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

ACK 319abd6

Copy link
Member

@pablomartin4btc pablomartin4btc left a comment

Choose a reason for hiding this comment

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

ACK 319abd6

I like this refactoring — the general idea of reducing unnecessary string allocations via string_view makes sense.

I’m a bit unsure about the changes in mining.cpp and signmessage.cpp. It seems like we’re going from stringstring_viewstring, which introduces a bit of unnecessary churn and could lead to confusion down the line. I understand the intention may be to eventually update those functions to accept string_view(?), but without that broader change in place, it’s hard to see a clear benefit to doing it this way for now.

@stickies-v stickies-v force-pushed the 2025-07/maybearg-string-view branch from 319abd6 to b8772ef Compare July 24, 2025 11:37
@stickies-v
Copy link
Contributor Author

stickies-v commented Jul 24, 2025

Force-pushed from 319abd6 to b8772ef to remove a std::string copy in rpc/mining.cpp, addressing (part of) @pablomartin4btc's feedback.


It seems like we’re going from stringstring_viewstring

string_view is a non-owning read-only reference, so by definition it has to point to some other string-like type. stringstring_view doesn't incur any allocations, is trivial, and by definition happens anytime we have a string_view. The string_viewstring operation indeed involves a new std::string allocation, and should be avoided where possible.

In signmessage.cpp, we were already coping the 3 strings, so 91a8ed2 does not add any overhead to what we currently have. We could optimize for performance and revert to using the request.params[{0,1,2}}.get_str(); syntax which would eliminate the copies, but I don't think the cost of these copies is meaningful to the overall cost of this cryptographically heavy function. I'd personally favour readability and phasing out the old interface, but I'm happy to change that if reviewers prefer to optimize for performance here. Another alternative would be to keep the Arg<std::string> specialization, but I think it is much better to get rid of it now so it doesn't get used in new places.

In mining.cpp, 91a8ed2 indeed introduced a new allocation. I thought avoiding it would touch too much code change, but I just had another look and it's actually pretty trivial (and enables one more use case of the Arg helper in the last commit), so I force-pushed to improve that in 122b432. Thanks for your review!

@stickies-v stickies-v force-pushed the 2025-07/maybearg-string-view branch from b8772ef to 122b432 Compare July 24, 2025 12:11
@DrahtBot
Copy link
Contributor

🚧 At least one of the CI tasks failed.
Task ARM, unit tests, no functional tests: https://github.com/bitcoin/bitcoin/runs/46641144470
LLM reason (✨ experimental): The CI failure is caused by a compilation error in descriptors.cpp due to a type mismatch error involving 'const char*' being used where a 'std::span' is expected.

Hints

Try to run the tests locally, according to the documentation. However, a CI failure may still
happen due to a number of reasons, for example:

  • Possibly 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.

  • A sanitizer issue, which can only be found by compiling with the sanitizer and running the
    affected test.

  • An intermittent issue.

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

Copy link
Member

@pablomartin4btc pablomartin4btc left a comment

Choose a reason for hiding this comment

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

re-ACK 122b432

Not blocking: I’d personally prefer keeping Arg<std::string> in signmessage.cpp if we're not planning to update MessageVerify to accept string_view instead of const std::string&. Is updating MessageVerify something you’d prefer to avoid at this stage?

@DrahtBot DrahtBot requested a review from w0xlt July 24, 2025 13:58
@stickies-v
Copy link
Contributor Author

Is updating MessageVerify something you’d prefer to avoid at this stage?

Yes. It involves a cascade of changes, many touching consensus code, that require significant review and have mostly nothing to do with RPC, so it would blow up the scope of this PR.

@stickies-v stickies-v force-pushed the 2025-07/maybearg-string-view branch from 122b432 to 137319b Compare July 25, 2025 20:29
@stickies-v
Copy link
Contributor Author

Force-pushed from 122b432 to 137319b to address silent merge conflict from #32845:

  • replaced self.MaybeArg<std::string> with self.MaybeArg<std::string_view> in wallet/rpc/wallet.cpp
  • updated EnsureUniqueWalletName signature to take std::optional<std::string_view> instead of const std::string*.

Otherwise no changes.

Modernizes interface by not forcing users to deal with raw pointers,
without adding copying overhead. Generalizes the logic of whether
we return by value or by optional/pointer.

In cases where functions take a `const std::string&` and it would
be too much work to update them, a string copy is made (which was
already happening anyway).
Update select functions that take a const std::string& to take a
std::string_view instead. In a next commit, this allows us to use
the {Arg,MaybeArg}<std::string_view> helper.
Use the {Arg,MaybeArg}<std::string_view> helper in all places where
it is a trivial change. In many places, this simplifies the logic
and reduces duplication of default values.
@stickies-v stickies-v force-pushed the 2025-07/maybearg-string-view branch from 137319b to 24d4863 Compare August 19, 2025 11:38
@stickies-v
Copy link
Contributor Author

Rebased to address merge conflict from #32896, no other changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants