-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
wallet: add multiple-URI support to parse_uri
and make_uri
#9830
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
base: master
Are you sure you want to change the base?
Conversation
src/simplewallet/simplewallet.cpp
Outdated
de.is_subaddress = info.is_subaddress; | ||
de.is_integrated = info.has_payment_id; | ||
|
||
if (info.has_payment_id || !payment_id_uri.empty()) |
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.
I know this isn't part of your change, but I'm curious why these two can contradict. In other words, is there a case where has_payment_id is false and payment_id_uri is not empty?
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.
I don't think my comment here should hold up the PR, since it's not a change you made here, but I'd like to hear from someone else about this too.
One tag is fine to prod me in case I missed the emails sent by Github. No need to tag me on each of my comments 👍 |
You resolved a bunch of comments without them being addressed. I suggest we either come to a conclusion before they're resolved, or you make a change and push a commit. For example, after discussing I agree no further change is needed here, so it can be resolved. |
Don't worry. Instead of letting you know every time (that seems spammy), I combined all of the suggestions into one commit and pushed them. Only time I will comment is when there is an issue. |
I wonder why my test fixture isn't getting executed properly.
|
Call the fixture to get the returned dictionary, then access it: |
Hey, Im going to stop reviewing this. There's been a persistent theme of you tagging me 8 hours after having not heard from me, and it's getting on my nerves. I've seen you do this with other people as well, people who have also spoken to you about this and asked you not to do it. I already spoke with you about this, and you said you're not going to continue pinging me. For example, not even 8 hours after leaving my last comment, you've pinged me again - I'm a human being, not a GPT, I need to sleep, I just woke up and I don't work for you (and even if I did, this would still be unacceptable). Not to mention, you're pinging me for issues that can be solved with simple debugging skills on code that you've supposedly written yourself - I'm unsure why you to ping me with regards to setting up a Python test fixture, there's plenty of documentation and examples online. |
I spent a bunch of time reviewing this and trying to help you. I wasn't going to leave another comment, until I saw your recent force-push. Instead of doing your part by doing some basic debugging to address a roadblock you encountered that was prompted by my comment, you reverted your code to a point beforewhich my comment existed for expedience. It's apparent that you don't care for improving the quality of your submission (which would in turn increase its chances of being accepted), if it requires just a tiny bit of effort for you to figure out how to write a test fixture in Python. I'm just as new as you, but this sort of lazy development doesn't have a place in this codebase, in my opinion. I do not recommend anyone else review this PR, you'll be wasting your time. OP will ignore it at the earliest sign of inconvenience if it means he gets his code crammed through faster. |
I realize now that my handling of this PR wasn’t ideal and clear enough. First off, a couple of clarifications:
I'm still fairly new to contributing to larger repositories, so I'm learning as I go (this time, the hard way). I really appreciate the effort you put into reviewing though it wasn’t at all wasted. I'll take this as a lesson to be more patient, clear about my next steps, and of course be considerate of reviewers time. |
You'll need to drop the merge commit and use rebase instead |
dd12547
to
de81583
Compare
@selsta Please review the PR. The new version (v0.18.4.0) is almost released. Major improvements from previous old review:
|
@selsta Hello, can you please tell me when you'll review this. I will patiently wait till that date. |
The three points you have written above all sound good and were necessary to get this merged. In file src/wallet/wallet_rpc_server_commands_defs.h, please update |
I tested it in monero-wallet-cli and it looks good to me. I don't have any remaining suggestions at the moment. |
parse_uri
and make_uri
parse_uri
and make_uri
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.
I'm not sure if someone else is going to review this but from my side I'll add an approval.
Is it possible to have multiple integrated addresses on one transaction? |
No multiple integrated addresses iirc. |
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.
From what I can tell this is currently broken, doing
transfer 4JtkiNvoi3iSPHHvcfXPPyj66zHQ9h1X9hmLCjDZ6kbNUhtYwDhAMm79p9GZ1iPCUhDMEvKMkMJdgb7JURAkCZUuhxNZCGqxVNDAmjcimV 0.001
[wallet 49C5ha]: show_transfer 35c55d6cc0733dc211ff15668978a3237e6e6f5b1bd48ac0a72d658b48961aee
Outgoing transaction found
txid: <35c55d6cc0733dc211ff15668978a3237e6e6f5b1bd48ac0a72d658b48961aee>
Height: 3489288
Timestamp: 2025-08-30 18:02:15Z
Amount: 0.001000000
Payment ID: 0000000000000000
Change: 0.000006040000
Fee: 0.000030580000
Destinations: 4JtkiNvoi3iSPHHvcfXPPyj66zHQ9h1X9hmLCjDZ6kbNUhtYwDhAMm79p9GZ1iPCUhDMEvKMkMJdgb7JURAkCZUuhxNZCGqxVNDAmjcimV: 0.000001000000
Note:
does not add the payment ID correctly
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.
I have some disagreements about the code structure, and the URI format itself.
src/wallet/wallet2.h
Outdated
std::string custom_convert_to_url_format(const std::string &uri) const; | ||
std::string make_uri(const std::vector<std::string> &addresses, const std::vector<uint64_t> &amounts, const std::vector<std::string> &recipient_names, const std::string &tx_description, std::string &error) const; |
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.
These new methods, including parse_uri()
, do not need to be member functions of wallet2
. I would recommend making them free functions. If they aren't to be free functions, at the very least mark the member functions as static
, please.
src/wallet/wallet_rpc_server.cpp
Outdated
{ | ||
if (!m_wallet) return not_open(er); | ||
std::string error; | ||
std::string uri = m_wallet->make_uri(req.addresses, req.amounts, req.recipient_names, req.tx_description, error); |
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.
This is why we shouldn't have make_uri()
/parse_uri()
be member functions of wallet2
: you need to have initialized a wallet2
instance for no reason.
src/wallet/wallet_rpc_server.cpp
Outdated
std::vector<std::string> addresses; | ||
std::vector<uint64_t> amounts; | ||
std::vector<std::string> recipient_names; | ||
if (!m_wallet->parse_uri(req.uri, addresses, amounts, recipient_names, res.uri.tx_description, res.unknown_parameters, error)) |
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.
Same point here
src/wallet/wallet2.cpp
Outdated
} | ||
|
||
if (amount > 0) | ||
std::string uri = "monero:" + addresses_str; |
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.
I don't like the format of <all addresses>?<all amounts>&<all messages>
, etc. Take a look at Bitcoin Unlimited's (node for Bcash) multiple address URI scheme: https://github.com/BitcoinUnlimited/BUIP/blob/master/086.md. The address, amount, and labels are next to each other for each output, which makes for more readable URIs. More importantly however, this allows the field for each output to remain undefined if desired. See this example for an actual use case: https://github.com/BitcoinUnlimited/BUIP/blob/master/086.md#example-1-bar-transaction. Here you can see that the amount field for a tip output at a bar is left empty, which triggers the client code to prompt the user to enter a desired amount. Overall, this type of URI format is way more flexible and future-proof than cramming values into a list based on field type, assuming the same structure for every single output in a transaction.
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.
FWIW this is the format we decided on. I don't remember why exactly.
https://github.com/monero-project/monero/blob/master/docs/URI_SCHEME.md
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.
Is it too late to change it if no one has a working implementation yet AFAIK?
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.
Here is some background on when it was decided on. I'm not sure if anyone actually implemented this.
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.
Seems like @trasherdk and @benevanoff wanted a similar approach to what I am bringing up here: packing info per-output, instead of packing per-value-type.
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.
Seems like @trasherdk and @benevanoff wanted a similar approach to what I am bringing up here: packing info per-output, instead of packing per-value-type.
As far as I know, XMRChat is the first and only one to use this, and we don't have anything in prod yet. We're fine with whatever format you prefer. Just hope it can be done quickly as we'd like to implement this soon.
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.
I think the design goal here was for the multi-payment scheme to match the original single-payment scheme in case of a single payment, i.e. it merely extends the existing scheme, rather than replacing it, making for a graceful upgrade (in particular, newly generated single-payment URIs work fine with existing consumers). That said, one could argue a "graceful" upgrade creates a false continuity, as multi-payments might parse OK with software that only supports single payments, making for user headaches. In any case, looking at the current tests, something has gone way off the rails, because the tests now include an output
parameter, which they shouldn't.
If you want to change the scheme, such that it's not compatible with the old one, it should be a clean break (i.e. a new scheme name), otherwise you end up violating the core principle of URI namespacing.
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.
I get what you're saying. The solution is to change the scheme name so the old clients don't accidentally parse the new multi recipient URI. I wonder what should be the new URI scheme name if that's what you mean? Additionally, should the new functions parse and generate old scheme URIs if there's it's a single recipient?
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.
We can't decide on minor issues like the scheme name before resolving the major question of whether to split the scheme at all. So, it seems any work should be on hold for now. I see two decent options:
- Extend the scheme to preserve the single-payment format and intentionally differ from it for multi-payment URIs in a manner that makes it highly unlikely multi-payment URIs introduce false compatibility.
- Keep the current single-payment URI scheme as-is, and introduce a new, multi-payment URI scheme.
In either case, I think single-payment URIs should work as-is (i.e. no changes to the single-payment use case, anything that previously worked will still work); otherwise, a lot of software breaks for a minor upgrade.
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.
Can we not modify the old functions to reject the URI as multi-recipient if it contains any output
parameter? If this is possible, this would eliminate the problem of false compatibility if I'm not wrong?
9d2f644
to
2b2ffe7
Compare
41c9746
to
4b10655
Compare
@selsta Can you review the new code. I think I have fixed the problem in the wallet cli. You can test it and see if it works now (I've tested from my side). One thing I want to point out is that it only adds payment id when you explicitly provide a payment_id parameter in the uri. Otherwise it wouldn't add, you've seen this and requested the changes. Additionally, @jeffro256 can you please review the new code (in the |
I will re-review but need a bit of time |
Am I understanding correctly that this is the new format? Is there supposed to be a question mark at the beginning? monero:?output=address1;amount1;&output=address2;amount2; |
Per my comment, this looks wrong, as the original scheme specification (https://github.com/monero-project/monero/blob/master/docs/URI_SCHEME.md) contains no mention of an |
A rewritten version of #9756 that is almost similar to it.
The previous source got deleted somehow (apologies).