-
Notifications
You must be signed in to change notification settings - Fork 38.2k
rpc: introduce 'label' API for wallet #7729
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
Conversation
|
Concept ACK. My idea was it to duplicate the current wallet implementation ( The second wallet could come without API stableness (for the first two releases or so) and could be marked as experimental. |
I disagree:
The point here is to give a non-deprecated equivalent to the 'label' system as used in the GUI, so the subset of the 'account system' that people are still allowed to use. This is a required, but up to now missing part of deprecating the account system. I'm not trying to rule out any other work that is being done such as multi-wallet support. I think this is pretty much orthogonal. As for alternative wallets, they've been proposed since at least 2012 - but none have materialized yet. And none of this change rules them out. |
Yes. I agree. |
|
Note getaccountaddress does not presently get a "default" address, it gets an unused address with the label, creating one if necessary. This seems useful only for mining, since no other context can guarantee an address hasn't been "used" but not sent to yet. I can't think of a good way to deprecate this, however. |
I wonder if we can find a better (or at least simpler, the |
I thought of the following: you could use two labels, one for the 'active' address, one for the 'normal'. Say When the miner needs an address it will:
This is a little bit more involved at the user side, but it avoids special administration (needing to keep around |
|
That looks like a lot of overhead, and this is a rather time-sensitive call, as the miner is working on stale work until it's done. Also, why are there no getreceivedbylabel/listreceivedbylabel? These don't have anything to do with balances. |
I'd suggest to try it. It shouldn't be much slower.
Looks like you're right.
|
|
@luke-jr Wouldn't it be feasible to instead generate a sequence of deterministic addresses for mining, for example using BIP32 derivation with the block height as index? |
@laanwj getreceivedbyaddress at least would loop over all the wtx... and then there's the additional latency from the back and forth of multiple calls. I haven't tried it yet, though.
@sipa Perhaps, if the wallet had a way to do this. Using the height seems incompatible with gap limits, though? |
|
@luke-jr I mean the mining software can do derivation, and import the keys into the wallet when a block is found. |
|
The functional test coverage for accounts is minimal or not existent, I think we should move forward with this pull. Needs rebase. |
|
Re-Concept ACK. |
|
Needs tests. |
|
@wallclockbuilder No shit, have you seen the TODOs at the bottom of the opening post? |
|
To be clear I posted this to get comments on the API, is there anything left to be done there? I'm going to write tests when it is clear that this is what we want at all. |
I would not consider this optional. User will always do what you not want them to do. |
|
Concept ACK |
|
listtransactions has an "account" argument where you now you would pass "*" if you need to supply non-default args for count, from, and includeWatchOnly. Will there be a way to query for transactions affecting any address with a given label? Could we tack on a "label" argument to listtransactions? |
|
I think the account argument of listtransactions could simply be re-used as a label argument. As listing transactions to a label has nothing to do with per-label balances there is no need to drop that particular functionality, |
|
repurposing the "account" argument to be "label" makes sense to me |
|
@ryanofsky Thank you! Replaced the branch with that one. |
| "\nExamples:\n" | ||
| + HelpExampleCli("setlabel", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"tabby\"") | ||
| + HelpExampleRpc("setlabel", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"tabby\"") | ||
| + HelpExampleCli("setlabel", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"tabby\"") |
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.
Unrelated change?
If you really wanted to change that DummyAddress(Params()) would be a better choice.
Sjors
left a comment
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.
tACK fef4178.
I just noticed that changing or removing a label in the console live updates the Receiving Addresses UI, nice! For a future PR we should figure out what to do with the Receive and Transaction tab "labels", as these seem to use an independent mechanism.
| "\nReturns the current Bitcoin address for receiving payments to this label.\n" | ||
| "\nReturns the current 'label address' for this label.\n" | ||
| "\nArguments:\n" | ||
| "1. \"label\" (string, required) The label name for the address. It can also be set to the empty string \"\" to represent the default label. The label does not need to exist, it will be created and a new address created if there is no label by the given name.\n" |
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 fine with removing this remark, but note that the behavior of creating a new address still exists (though without an address type param). It might make sense to deprecate that behavior in a followup PR, and require getnewaddress if getlabeladdress doesn't return anything. That also makes the choice of potentially reusing an address more explicit.
Transaction tab labels use the same mechanism so it would be a matter of listening to a notification and repainting. Receive requests are stored separately, because they have extra metadata besides a label. |
|
Ah yes, I see it. Restarting QT doesn't change or remove a label from Requested payments history for me, as you point out. Switching tabs is enough to update labels in the transactions view. |
jnewbery
left a comment
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.
Comments inline.
Feel free to squash my second commit into the first.
| { "wallet", "getaccountaddress", &getlabeladdress, {"account"} }, | ||
| { "wallet", "getaccount", &getaccount, {"address"} }, | ||
| { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, {"account"} }, | ||
| { "wallet", "getaddressinfo", &getaddressinfo, {"address"} }, |
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 getaddressinfo should be deprecated. It's not an account rpc
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 getaddressinfo should be deprecated. It's not an account rpc
Good catch. getaddressinfo should remain where it was above "getbalance". It's my fault for accidentally moving it into this section during a rebase.
| if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) | ||
| throw std::runtime_error( | ||
| "setlabel \"address\" \"label\"\n" | ||
| "setlabel \"bitcoinaddress\" \"label\"\n" |
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.
Why rename the arguments/return values to bitcoinaddress everywhere? Seems like a gratuitous API break.
address is used in many RPCs for a bitcoin address. Why not continue that convention? (and if you really must change this, current style guidelines call for snake_case for 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.
src/wallet/rpcwallet.cpp
Outdated
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.
Comment: https://github.com/bitcoin/bitcoin/pull/7729/files#r121986789 not addressed. Result also includes an array of destdata. Please update help text.
EDIT: I think we should just drop the destdata from the response. It wasn't available in the old account RPCs, and it appears to me that the only place we add to destdata is in saveReceiveRequest().
We can always add destdata to the response in a later PR if required.
| "\nArguments:\n" | ||
| "1. \"bitcoinaddress\" (string, required) The bitcoin address for label lookup.\n" | ||
| "\nResult:\n" | ||
| " { (json object with information about address)\n" |
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 make this RPC return an array? We may want to be able to attach multiple labels to addresses in the future (#7729 (comment)), and making this RPC return an array will allow us to do that without a breaking API change
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 make this RPC return an array?
It might be better to not add a getlabel RPC at all but instead just return this information in getaddressinfo (recently added in #10583).
| } | ||
| } | ||
| UniValue ret(UniValue::VARR); | ||
| for (const std::string &name : setLabels) { |
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.
Should we sort the label names before returning?
| if (item.second.name == strLabel) { | ||
| ret.push_back(Pair(EncodeDestination(item.first), AddressBookDataToJSON(item.second, false))); | ||
| } | ||
| } |
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.
Should this throw an error if the label doesn't exist? Currently it returns an empty object.
| throw std::runtime_error( | ||
| "getlabeladdress \"label\"\n" | ||
| "\nReturns the current Bitcoin address for receiving payments to this label.\n" | ||
| "\nReturns the current 'label address' for this label.\n" |
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.
The behaviour for this RPC is weird. If called for a label that doesn't exist, it creates a new label, and then adds a new address as the 'label address' for that label. That's not very intuitive, and I think it's a bad experience (for example if a user typos an existing label name). Can we change this so that the rpc returns an error if called with a non-existent label name?
|
|
||
| from test_framework.test_framework import BitcoinTestFramework | ||
| from test_framework.util import assert_equal | ||
| from collections import defaultdict |
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.
nit: standard library imports before project imports please!
|
@laanwj - it seems like you're struggling to find time to maintain this PR. I'd like to push this forwards and make sure it gets in for v0.17. Would you object if I took ownership? |
|
Maybe there should be a call returning all addresses and all labels (a bulk call). If you want to dump all address-label pairs this would involve many RPC calls right now. This bulk call should even (optionally?) include internal addresses such as pool addresses. Simply all data. I have had the need many times to reflect over absolutely all wallet contents and such an API call would have been very welcome. |
|
Indeed thanks to @laanwj for initiating it and coming up with the original version of the code. And thx to @ryanofsky and @jnewbery for picking it up. |
This change only updates strings and adds RPC aliases, but should simplify the implementation of address labels in bitcoin#7729, by getting renaming out of the way and letting it focus on semantics. The difference between accounts and labels is that labels apply only to addresses, while accounts apply to both addresses and transactions (transactions have "from" and "to" accounts). The code associating accounts with transactions is clumsy and unreliable so we would like get rid of it.
This change only updates strings and adds RPC aliases, but should simplify the implementation of address labels in bitcoin#7729, by getting renaming out of the way and letting it focus on semantics. The difference between accounts and labels is that labels apply only to addresses, while accounts apply to both addresses and transactions (transactions have "from" and "to" accounts). The code associating accounts with transactions is clumsy and unreliable so we would like get rid of it.
This change only updates strings and adds RPC aliases, but should simplify the implementation of address labels in bitcoin#7729, by getting renaming out of the way and letting it focus on semantics. The difference between accounts and labels is that labels apply only to addresses, while accounts apply to both addresses and transactions (transactions have "from" and "to" accounts). The code associating accounts with transactions is clumsy and unreliable so we would like get rid of it.
This change only updates strings and adds RPC aliases, but should simplify the implementation of address labels in bitcoin#7729, by getting renaming out of the way and letting it focus on semantics. The difference between accounts and labels is that labels apply only to addresses, while accounts apply to both addresses and transactions (transactions have "from" and "to" accounts). The code associating accounts with transactions is clumsy and unreliable so we would like get rid of it.
This change only updates strings and adds RPC aliases, but should simplify the implementation of address labels in bitcoin#7729, by getting renaming out of the way and letting it focus on semantics. The difference between accounts and labels is that labels apply only to addresses, while accounts apply to both addresses and transactions (transactions have "from" and "to" accounts). The code associating accounts with transactions is clumsy and unreliable so we would like get rid of it.
d2527bd Rename wallet_accounts.py test (Russell Yanofsky) 045eeb8 Rename account to label where appropriate (Russell Yanofsky) Pull request description: Rename account to label where appropriate This change only updates strings and adds RPC aliases, but should simplify the implementation of address labels in bitcoin#7729, by getting renaming out of the way and letting that change focus on semantics. The difference between accounts and labels is that labels apply only to addresses, while accounts apply to both addresses and transactions (transactions have "from" and "to" accounts). The code associating accounts with transactions is clumsy and unreliable so we would like get rid of it. --- There is a rebased version of bitcoin#7729 atop this PR at https://github.com/ryanofsky/bitcoin/commits/pr/label, see bitcoin#7729 (comment). Tree-SHA512: b3f934e612922d6290f50137f8ba71ddfaea4485713c7d97e89400a8b73b09b254f9186dffa462c77f5847721f5af9852b5572ade5443d8ee95dd150b3edb7ff
d2527bd Rename wallet_accounts.py test (Russell Yanofsky) 045eeb8 Rename account to label where appropriate (Russell Yanofsky) Pull request description: Rename account to label where appropriate This change only updates strings and adds RPC aliases, but should simplify the implementation of address labels in bitcoin#7729, by getting renaming out of the way and letting that change focus on semantics. The difference between accounts and labels is that labels apply only to addresses, while accounts apply to both addresses and transactions (transactions have "from" and "to" accounts). The code associating accounts with transactions is clumsy and unreliable so we would like get rid of it. --- There is a rebased version of bitcoin#7729 atop this PR at https://github.com/ryanofsky/bitcoin/commits/pr/label, see bitcoin#7729 (comment). Tree-SHA512: b3f934e612922d6290f50137f8ba71ddfaea4485713c7d97e89400a8b73b09b254f9186dffa462c77f5847721f5af9852b5572ade5443d8ee95dd150b3edb7ff
d2527bd Rename wallet_accounts.py test (Russell Yanofsky) 045eeb8 Rename account to label where appropriate (Russell Yanofsky) Pull request description: Rename account to label where appropriate This change only updates strings and adds RPC aliases, but should simplify the implementation of address labels in bitcoin#7729, by getting renaming out of the way and letting that change focus on semantics. The difference between accounts and labels is that labels apply only to addresses, while accounts apply to both addresses and transactions (transactions have "from" and "to" accounts). The code associating accounts with transactions is clumsy and unreliable so we would like get rid of it. --- There is a rebased version of bitcoin#7729 atop this PR at https://github.com/ryanofsky/bitcoin/commits/pr/label, see bitcoin#7729 (comment). Tree-SHA512: b3f934e612922d6290f50137f8ba71ddfaea4485713c7d97e89400a8b73b09b254f9186dffa462c77f5847721f5af9852b5572ade5443d8ee95dd150b3edb7ff
d2527bd Rename wallet_accounts.py test (Russell Yanofsky) 045eeb8 Rename account to label where appropriate (Russell Yanofsky) Pull request description: Rename account to label where appropriate This change only updates strings and adds RPC aliases, but should simplify the implementation of address labels in bitcoin#7729, by getting renaming out of the way and letting that change focus on semantics. The difference between accounts and labels is that labels apply only to addresses, while accounts apply to both addresses and transactions (transactions have "from" and "to" accounts). The code associating accounts with transactions is clumsy and unreliable so we would like get rid of it. --- There is a rebased version of bitcoin#7729 atop this PR at https://github.com/ryanofsky/bitcoin/commits/pr/label, see bitcoin#7729 (comment). Tree-SHA512: b3f934e612922d6290f50137f8ba71ddfaea4485713c7d97e89400a8b73b09b254f9186dffa462c77f5847721f5af9852b5572ade5443d8ee95dd150b3edb7ff
Add label API to wallet RPC.
This is one step towards #3816 ("Remove bolt-on account system") although it doesn't actually remove anything yet (that would be a follow-up pull).
These initially mirror the account functions, with the following differences:
getreceivedbylabellistlabelslistreceivedbylabelcan show received transactions to addresses with a label, not use the account tally (currently it is removed, but according to discussion that goes too far as this doesn't inherently have to do with balance)listlabelshas no minconf or watchonly argumentmovesetlabel, but an explicit calldeletelabelwhich assigns all address to the default label may make sense.accountargument renamed tolabel:importaddressimportprivkeyimportpubkeyAPI
Short description of every RPC call: for detailed information check RPC help. The general idea is to offer the same functionality as the GUI label system. Labels are simply a name for an address, or a group of addresses.
Do not use the deprecated account system and the label system with the same wallet at the same time. These APIs use the same underlying data in the database for (slightly) different purposes, using them interchangeably will give unexpected results. (Just like using the GUI labels and account system at the same time. Using the GUI labels and the label API at the same time, however, is no problem)
getlabel: returns the label (and other address book data) associated with an addressgetaddressesbylabel: get addresses labelled with one labellistlabels: list all labels (or labels with a certain purpose, such as receive/send)setlabel: assign a label to an addressgetlabeladdress: get the 'label address' for the specified label. This gets an unused address with the label, creating one if necessary should be removed according to discussionThese calls have a deprecated account parameter, which can be turned into a label-parameter as is:
listtransactionsOpen questions
'no', labels are just a name for one or more addresses, intuitively there is no "default address",
and it also isn't a GUI feature (->no)