[RPC] Include coinbase transactions in receivedby RPCs#14707
[RPC] Include coinbase transactions in receivedby RPCs#14707maflcko merged 3 commits intobitcoin:masterfrom
Conversation
|
Concept ACK, but you can't break compatibility by reordering another argument to |
|
Do we know a usecase where anyone would want this behaviour? It seems transparently broken to me. If not, I think I would prefer we fix it and have a LOUD release note about the change, and if we're feeling especially conservative have a hidden config option to restore the old behaviour which we can drop after a couple releases if no one reports needing it. Having an option presents a perpetual usage complexity increase, and defaulting the option to the old behaviour risks users being messed up by continuing to miss these payments. One thing to consider, however, is that coinbase payments have different deconfirmation risks then general transactions... and cannot be spent for 100 blocks. E.g. you don't want service that accept a 1 conf deposit and withdraw being exploited as a orphan risk eliminator. Nor do we want to undermine parties cashflow handling by causing them to think they can spend more now than they can. There is justification for treating coinbase payments differently (e.g. only showing them once they're spendable), just not for hiding them completely. Having a "include coinbase payments yes/no" doesn't solve these concerns. Having a "delay them by 100 blocks, yes/no" probably would. So maybe I would suggest having an argument to hide them until maturity, defaulting on, a hidden option to get the old behaviour, defaulting off, to be removed once it's confirmed no one needs it, and a loud release note explaining the change. |
|
@gmaxwell it is however useful to know if a payment was made regardless if it takes 100 blocks to be spendable? |
|
It can be, but listreceivedbyaddress doesn't normally show unconfirmed payments and the output IIRC doesn't even tell you if its an immature coinbase payment (and if it did, many people who didn't even realize coinbase payments were possible would not know to check for it) |
|
@gmaxwell what if we consider |
|
@gmaxwell I agree. I think it is an error that should be corrected. I'm not sure why anyone would want coinbase txs excluded. I haven't seen a good explanation for why they are filtered out, or a usecase. |
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
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. |
f3d8ca1 to
8d03722
Compare
|
Commits and PR description have been updated. |
8d03722 to
1a622e7
Compare
|
I refactored the |
1a622e7 to
ca9da49
Compare
3a1cc7c to
97602b5
Compare
|
@gmaxwell Updated this PR with your suggestions. |
97602b5 to
edb44f7
Compare
edb44f7 to
a9d182d
Compare
b49685a to
0fa9b60
Compare
13e344a to
08c1c6e
Compare
c7c662b to
77da829
Compare
src/wallet/rpcwallet.cpp
Outdated
| || (wtx.IsCoinBase() && (depth < 1 || filter_coinbase)) | ||
| || (!include_immature && wtx.IsImmatureCoinBase()) |
There was a problem hiding this comment.
Consistency helps readability. I think you can make this more consistent and readable as:
| || (wtx.IsCoinBase() && (depth < 1 || filter_coinbase)) | |
| || (!include_immature && wtx.IsImmatureCoinBase()) | |
| || (wtx.IsCoinBase() && (depth < 1 || !include_coinbase)) | |
| || (wtx.IsImmatureCoinBase() && !include_immature_coinbase) |
(where include_coinbase = !(wallet.chain().rpcEnableDeprecated("filter_coinbase")))
There was a problem hiding this comment.
Another idea, this logic is close to that added to ListReceived() further down in this file; have you considered refactoring this logic into a separate small function? This may make the logic unit-testable, but may not be worth it.
There was a problem hiding this comment.
@jnewbery Great suggestion, I agree this makes it much more readable.
@LarryRuane Since there are only two instances of this duplication, should we defer to the rule of three?
glozow
left a comment
There was a problem hiding this comment.
Concept ACK to not filtering out coinbases (especially if they're mature, I can't imagine why someone would want to filter those out). I have a few questions.
| // Coinbase with less than 1 confirmation is an orphan | ||
| || (wtx.IsCoinBase() && (depth < 1 || filter_coinbase)) | ||
| || (!include_immature && wtx.IsImmatureCoinBase()) | ||
| || !wallet.chain().checkFinalTx(*wtx.tx)) { |
There was a problem hiding this comment.
I expect this refers to outputs that we can't spend yet because a timelock hasn't been met. If a user wants to include immature coinbases, might they want to include nonfinal ones too? I understand that include_immature is supposed to be only for immature coinbases but I think a user might find it more helpful to be able to configure spendability in general rather than just for coinbases
There was a problem hiding this comment.
I thought this was an interesting idea. However, while implementing and trying to write a test, I was unable to broadcast a non-final tx (rejected with non-final). Do you know any way that a wallet would be able to have a non-final tx? If not, then it's possible this check is unnecessary and can be removed.
There was a problem hiding this comment.
Oh hm, I guess the finality wouldn't really be reflected in the received transaction's header, but in the redeem script for it. I'm not too sure how the wallet keeps track of timelocked outputs 🤔 I don't think this check should be removed though
| self.nodes[0].invalidateblock(hash) | ||
|
|
||
| self.log.info("getreceivedbyaddress does not include orphan when minconf is 0 when including immature") | ||
| balance = self.nodes[0].getreceivedbyaddress(address=address, minconf=0, include_immature=True) |
There was a problem hiding this comment.
Question: What happens if a user puts -spendzeroconfchange=0 (it's True by default, right?) and then calls getreceivedbyaddress(minconf=0)?
There was a problem hiding this comment.
Hmm I'm not sure there is any effect in this case. The getreceivedby* RPCs only return a balance, and setting minconf=0 would return the unconfirmed balance using the tally code in GetReceived. I don't believe it would be affected by spendzeroconfchange, which from what I can see is only used in CWallet::SelectCoins.
|
@jnewbery @glozow @LarryRuane thank you all for your review! I've updated with all of your suggestions. |
jnewbery
left a comment
There was a problem hiding this comment.
Code review ACK 5e13dac43f257cc0869150c8f8b400b353885997 modulo release note comment.
There was a problem hiding this comment.
nit: remove extra linebreak if you retouch this branch.
There was a problem hiding this comment.
Feel free to remove this extra newline if you need to touch this branch again.
|
@jnewbery not sure what commit your ACK is referencing. Looks like github does not recognize it either. |
Oops, sorry @andrewtoth - I rebased your branch on master before building/reviewing (building a branch that's based on a very old master commit results in a very slow build since lots of header files have changed). I then accidentally left my ACK for my new head commit hash instead of the one in this PR. ACK 164e26d42e |
|
reACK 1f084ec0ef @andrewtoth: github doesn't generate a notification for reviewers if you just force-push a rebase. If you want people to re-review after a rebase you should leave a comment. That'll notify everyone who has previously reviewed the PR. |
LarryRuane
left a comment
There was a problem hiding this comment.
This PR has hidden conflicts in the functional test; the generate() and generatetoaddress() signatures have changed.
|
Yeah, needs rebase again. |
|
Rebased. |
|
Looks like there are test failures with descriptor wallets? |
|
@MarcoFalke fixed. |
|
reACK 1dcba99 |
maflcko
left a comment
There was a problem hiding this comment.
Sorry for the incremental review
| This release changes this behaviour and returns results accounting for received coins from coinbase outputs. | ||
|
|
||
| A new option, `include_immature_coinbase` (default=`false`), determines whether to account for immature coinbase transactions. | ||
| Immature coinbase transactions are coinbase transactions that have 100 or fewer confirmations, and are not spendable. |
There was a problem hiding this comment.
Is this still up-to-date? The default seems to be true. Also, instead of using the release notes to explain what immature txs are, what about moving this to the rpc help? Either this is relevant for future releases as well, or not at all.
There was a problem hiding this comment.
There was a problem hiding this comment.
No, not a blocker.
Sorry for the brain fart. I keep messing up true and false for boolean values lately.
There was a problem hiding this comment.
Maybe for clarity (in the future) the second section can be switched with the third section, so that the behavior changing stuff is bundled together and the new rpc arg option is in a separate bundle?
There was a problem hiding this comment.
If someone decides to address the nits, the notes snippet can also be moved to the main release notes file in the same pull request, to avoid having to touch it again.
The current
*receivedby*RPCs filter out coinbase transactions. This doesn't seem correct since an output to your address in a coinbase transaction is receiving those coins.This PR corrects this behaviour. Also, a new option
include_immature_coinbaseis added (default=false) that includes immature coinbase transactions when set to true.However, since this is potentially a breaking change this PR introduces a hidden configuration option
-deprecatedrpc=exclude_coinbase. This can be set to revert to previous behaviour. If no reports of broken workflow are received, then this option can be removed in a future release.Fixes #14654.