-
Notifications
You must be signed in to change notification settings - Fork 38.7k
[wallet] getbalance: Add option to include non-mempool UTXOs #11020
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
d1ec4d5 to
5b644c8
Compare
|
Not sure why |
|
The zapwallettxes' failure is intermittent. Respinned travis. |
|
I'd hoped that #10330 had fixed the zapwallettxes intermittency. @MarcoFalke do you have an example of it failing (the failure on this PR is no longer available since the task was restarted in Travis). (apologies for being off-topic) |
|
@jnewbery Sorry I didn't keep track of the exact failure this time, I assume it was one of the known issues that popped up recently. |
promag
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.
Should add the same option to getunconfirmedbalance?
src/wallet/wallet.h
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.
Nit, snake case.
src/wallet/wallet.h
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.
Nit, snake case.
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.
Not sure what you mean -- most other argument names are written in this style, e.g. redeemScript, mapKeyBirth, etc.
test/functional/wallet.py
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.
Assert exact value?
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.
Asserting on exact values can make the test more brittle. I think it's fine to test strict lesser than here.
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.
Asserting on exact values can make the test more brittle.
Is that a bad thing?
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.
It's bad if the test will intermittently fail for unrelated reasons (rounding errors, for example).
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.
That should not happen. There are lots of exact asserts through out this file.
src/wallet/wallet.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.
Nit, snake case.
src/wallet/wallet.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.
Update comment.
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.
Concept ACK. A few questions about the interface and naming inline.
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.
I think this argument name is a bit confusing. Perhaps include_not_yet_spendable. It's a bit of a mouthful, but 'unspendable' sounds too permanent to me.
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 was hoping the description of the argument would alleviate that, but you may be right.
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.
Also, please align other arguments as this is currently the longest.
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.
Actually, include_watchonly is slightly longer, but I think realigning is a good idea yeah.
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.
This is confusing for me. include_unspendable only has effect if:
accountis not specified; andminconfis not specified; andinclude_watchonlyis not specified
Additionally, if account is specified as "" (ie balance not associated with any account), the returned balance will use GetBalance() if include_unspendable is not set, but GetLegacyBalance() if it is set.
Can you explain the reasoning here?
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 argument is the last in the list, and there's no way to give a default value for account because it's not being JSON parsed (you can't pass "null" as it would become the string "null"). Using named arguments, you can do this, but otherwise I have to make the "special case" of you passing defaults in.
The legacy balance seems to not be very used and possibly even about to be deprecated, so I didn't feel the need to update it. That, and it already kind of does what the PR is doing when you do a 0 minconf and account="*".
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 find it surprising that minconf and watchonly only have effect if account is specified, and now include_unspendable only has effect if account is not specified. There doesn't appear to be any user documentation explaining that.
I'm afraid I don't know the history or motivation for that. @ryanofsky made changes in this area recently. Perhaps he can shed light on this.
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.
I find it confusing that the API uses include_unspendable, but internally you use ignoreUnspendable which is the inverse. Any reason not to be consistent?
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.
It ended up that way. You're right, will fix.
test/functional/wallet.py
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.
Asserting on exact values can make the test more brittle. I think it's fine to test strict lesser than here.
src/wallet/wallet.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.
Again, I think the name ignoreUnspendable could be made clearer.
|
@promag @jnewbery Thanks for the review!
|
|
zapwallettxes.py again, @jnewbery: https://pastebin.com/70bQ7CLq |
|
IMO from the wallet point of view those UTXO should always be part of the balance, and in that case this should be a bug fix and not require more options. WDYT? Edit: unless |
|
Yes Hm, |
3fd1c22 to
2812048
Compare
2812048 to
8d6a264
Compare
8d6a264 to
bc5fc21
Compare
bc5fc21 to
ae468c1
Compare
ae468c1 to
6f4b15c
Compare
6f4b15c to
d30f03e
Compare
d30f03e to
97f4399
Compare
|
Rebased this, but now it is not available unless the user enables deprecated account. I could
Ping @jnewbery. Edit: I went with the second option in c8c147a. |
7752812 to
c8c147a
Compare
|
I think I prefer option (1). Overloading parameters can be confusing, but I think it's better in this case because:
|
|
@jnewbery I definitely prefer option 1 but I wasn't sure it would be disruptive. Will switch. |
c8c147a to
b93fbc4
Compare
|
@jnewbery See 0c28d8f -- I split up the descriptions based on deprecation, and fixed several text issues (e.g. RPC examples using the deprecated stuff). I think this change alone is worth a PR, to be honest. FWIW I also removed Since "accounts" is not JSON-parsed and "include_unavailable" wants to be, I am temporarily doing the conversion manually (testing for "true" or "1"). Once accounts are removed, we can add param 0 to clients.cpp and remove the manual stuff. |
b93fbc4 to
fdbf735
Compare
src/wallet/wallet.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.
nit: variables and arguments should be in snake_case (same for all args below)
src/wallet/wallet.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.
Should this call IsTrusted() with includeUnavailable? If not, coins that are in the mempool could show up in both the balance and the unconfirmed balance.
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. I'll add tests to check that this is not the case.
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.
nit: can be moved below the if (IsDeprecatedRPCEnabled("accounts")) { block and the !IsDeprecatedRPCEnabled("accounts") condition removed (since the code below the if (IsDeprecatedRPCEnabled("accounts")) { block is effectively the else branch.
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.
Good point!
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.
nit: since you're changing the help text for this and getunconfirmedbalance, perhaps correct it to say "the wallet's ..." instead of "the server's ..."
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.
It's a bit ugly to replicate the univalue parsing here, but I think it's ok since it's only going to be in here for one release.
I think you should remove the request.params[0].get_str() == "1" (1 isn't interpreted as true in univalue). You may also throw an error if request.params[0].get_str() is not false or true (so passing True for example doesn't silently fail and leave include_unavailable as 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.
I thought 1 was true. E.g. getrawtransaction <id> 1. But that seems to be a special case for getrawtransaction, actually. Changing as you suggest.
…nspendable UTXOs. In some cases, a transaction will fail to go into the mempool, e.g. if it is in a too-long chain of transactions. getbalance will ignore the change UTXOs for these, giving you the impression that you have less balance than you actually do. This commit adds a flag include_unavailable to get(unconfirmed)balance, which, if enabled, will also account for transactions NOT in the mempool but in your wallet.
fdbf735 to
a73ecd6
Compare
Looking at the tests (it was a while since I wrote this), I think the idea was that it should be counted in both (see wallet_basic.py changes). Is this problematic? |
| Needs rebase |
|
Needs rebase. @kallewoof - how urgently do you want this? If it can wait until after v0.17, then it'll probably be easier and a smaller diff once the accounts API code has been removed. I intend to do that as soon as 0.17 is branched. |
|
@jnewbery Not urgent. I will wait until 0.17 branches off. |
|
Happy birthday. Closing due to lack of interest. |
|
I commit to reviewing this after it's rebased on #13825 |
|
@jnewbery OK! |
|
@jnewbery I began to rebase this, but self-reflectively decided this is a bit too invasive for the improvement it provides. I think it's a bit weird that 'getbalance' will suddenly drop significantly just because you ran out of chain length, but I'm no longer confident this is the right approach. Sorry for wasting your time! |
Not wasted. No need to apologise! |
Currently, if the wallet generates a transaction that cannot currently go into the mempool (e.g. due to too-long-mempool-chain), the wallet UTXOs related to this will vanish from
getbalance, giving the appearance that the user has less funds than they actually do.From a "get spendable balance" perspective, this is perfectly valid, but users may sometimes want to see their actual balance, regardless of whether they can spend it or not at that time.
This PR adds an
include_unspendableoption (default=false) togetbalancewhich, whentrue, will consider non-mempool transactions as trusted, and thus display these in the tally.Note: this flag does nothing when a user specifies an account (i.e.
GetLegacyBalance), and the legacy balance in fact already does whatinclude_unspendable=truedoes, given the right arguments.