-
Notifications
You must be signed in to change notification settings - Fork 37.7k
wallet: fix when sufficient preset inputs and subtractFeeFromOutputs #17568
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
src/wallet/wallet.cpp
Outdated
if (res) { | ||
bnb_used = false; | ||
} else { | ||
res = value_to_select <= 0 || |
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 leave this case here when we know it is 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.
Oops, forgot to delete that.
fd05e41
to
9b40c0d
Compare
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. |
The new test passes on current master without the code change |
Not for me:
|
I've tested this. This is really strange, I wonder what causes the difference in behavior for @meshcollider . |
FWIW the test pass on master for me as well (without the code change). |
samuel@hansome-pc:~/git/bitcoin$ git diff master
diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py
index 693051edc..6f1ae0d3b 100755
--- a/test/functional/rpc_fundrawtransaction.py
+++ b/test/functional/rpc_fundrawtransaction.py
@@ -92,6 +92,7 @@ class RawTransactionsTest(BitcoinTestFramework):
self.test_option_feerate()
self.test_address_reuse()
self.test_option_subtract_fee_from_outputs()
+ self.test_subtract_fee_with_presets()
def test_change_position(self):
"""Ensure setting changePosition in fundraw with an exact match is handled properly."""
@@ -741,5 +742,17 @@ class RawTransactionsTest(BitcoinTestFramework):
# The total subtracted from the outputs is equal to the fee.
assert_equal(share[0] + share[2] + share[3], result[0]['fee'])
+ def test_subtract_fee_with_presets(self):
+ self.log.info("Test fundrawtxn subtract fee from outputs with preset inputs that are sufficient")
+
+ addr = self.nodes[0].getnewaddress()
+ txid = self.nodes[0].sendtoaddress(addr, 10)
+ vout = find_vout_for_address(self.nodes[0], txid, addr)
+
+ rawtx = self.nodes[0].createrawtransaction([{'txid': txid, 'vout': vout}], [{self.nodes[0].getnewaddress(): 5}])
+ fundedtx = self.nodes[0].fundrawtransaction(rawtx, {'subtractFeeFromOutputs': [0]})
+ signedtx = self.nodes[0].signrawtransactionwithwallet(fundedtx['hex'])
+ self.nodes[0].sendrawtransaction(signedtx['hex'])
+
if __name__ == '__main__':
RawTransactionsTest().main()
samuel@hansome-pc:~/git/bitcoin$ make -j5
Making all in src
make[1]: Entering directory '/home/samuel/git/bitcoin/src'
make[2]: Entering directory '/home/samuel/git/bitcoin/src'
CXX libbitcoinconsensus_la-arith_uint256.lo
CXX libbitcoinconsensus_la-hash.lo
CXX libbitcoinconsensus_la-pubkey.lo
CXX libbitcoinconsensus_la-uint256.lo
...
CXX qt/qt_libbitcoinqt_a-moc_walletview.o
CXX qt/qt_libbitcoinqt_a-qrc_bitcoin.o
CXX qt/qt_libbitcoinqt_a-qrc_bitcoin_locale.o
CXXLD bitcoind
CXXLD test/test_bitcoin
CXXLD bench/bench_bitcoin
AR qt/libbitcoinqt.a
CXXLD qt/bitcoin-qt
CXXLD qt/test/test_bitcoin-qt
make[2]: Leaving directory '/home/samuel/git/bitcoin/src'
make[1]: Leaving directory '/home/samuel/git/bitcoin/src'
Making all in doc/man
make[1]: Entering directory '/home/samuel/git/bitcoin/doc/man'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/samuel/git/bitcoin/doc/man'
make[1]: Entering directory '/home/samuel/git/bitcoin'
make[1]: Nothing to be done for 'all-am'.
make[1]: Leaving directory '/home/samuel/git/bitcoin'
samuel@hansome-pc:~/git/bitcoin$ ./test/functional/test_runner.py rpc_fundrawtransaction.py
Temporary test directory at /tmp/test_runner_?_??_20191124_180027
Remaining jobs: [rpc_fundrawtransaction.py]
1/1 - rpc_fundrawtransaction.py passed, Duration: 13 s
TEST | STATUS | DURATION
rpc_fundrawtransaction.py | ? Passed | 13 s
ALL | ? Passed | 13 s (accumulated)
Runtime: 13 s Clean branch, up to date master, fresh build. Ubuntu 18.04.1. Idk why it passes but yours doesn't. Also tested with Travis, (https://travis-ci.org/meshcollider/bitcoin/builds/616192547) - jobs .4 and .8 passed rpc_fundrawtransaction.py |
9b40c0d
to
d3ca0b4
Compare
I figured out why we are getting different test results on master. It's because bnb_used is not initialized, so the access is undefined behavior and changes depending on the optimizations used. I always configured with I've pushed another commit which should completely address this type of issue, at least until we merge #17331 which gets rid of that variable entirely. Instead of setting it at each of the non-BnB cases that can occur, we just default assume |
Ah, good find. Code review ACK d3ca0b4 |
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.
ACK 4b0d19b
@practicalswift spotted a similar issue in #13546. Let's also actually initialize this thing, as @promag suggested: Line 2681 in 2a97d2b
|
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.
Second commit needs a rework of the commit message since it's just an additional test now.
d3ca0b4
to
16d1e12
Compare
16d1e12
to
eadd130
Compare
Changed |
utACK eadd130 |
ACK eadd130. I can't get this new test to fail on macOS (without this PR). It passes whether or not I compile with |
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.
ACK eadd130
SelectCoins()
is only called in CreateTransaction()
. bnb_used
is set to false before that call (and again inside SelectCoins()
) which is before any calls to SelectCoinsMinConf()
.
Looking forward to something like #17331 which not only removes bnb_used
but simplifies the wallet.cpp logic. As we've currently got code like this:
// Choose coins to use
bool bnb_used = false;
if (pick_new_inputs) {
<snip>
} else {
bnb_used = false;
}
and are doing similar things with coin_selection_params.use_bnb
.
…eeFromOutputs eadd130 tests: Add a test for funding with sufficient preset inputs and subtractFeeFromOutputs (Andrew Chow) ff330ba Default to bnb_used = false as there are many cases where BnB is not used (Andrew Chow) Pull request description: #17290 introduced a bug where, when we had preset inputs that covered the amount being sent and subtractFeeFrromOutputs was being used, transaction funding would result in a `Fee exceeds maximum configured by -maxtxfee` error. This was happening because we weren't setting `bnb_used = false` when the preset inputs were used as it should have been. This resulted in a too high fee because the change would go to fees accidentally. Apparently this particular case doesn't have a test, so I've added one as well. ACKs for top commit: Sjors: ACK eadd130. I can't get this new test to fail on macOS (without this PR). It passes whether or not I compile with `--enable-debug`. It does fail on Ubuntu. Yay undefined behavior... Anyway, it's a useful test. fanquake: ACK eadd130 instagibbs: utACK eadd130 Tree-SHA512: 7286c321f78666eea558cc591174630d210263594df41cab1065417510591ee514ade0e1d0cec8af09a785757da68de82592b013e8fe8d4966cec3254368706e
…btractFeeFromOutputs eadd130 tests: Add a test for funding with sufficient preset inputs and subtractFeeFromOutputs (Andrew Chow) ff330ba Default to bnb_used = false as there are many cases where BnB is not used (Andrew Chow) Pull request description: bitcoin#17290 introduced a bug where, when we had preset inputs that covered the amount being sent and subtractFeeFrromOutputs was being used, transaction funding would result in a `Fee exceeds maximum configured by -maxtxfee` error. This was happening because we weren't setting `bnb_used = false` when the preset inputs were used as it should have been. This resulted in a too high fee because the change would go to fees accidentally. Apparently this particular case doesn't have a test, so I've added one as well. ACKs for top commit: Sjors: ACK eadd130. I can't get this new test to fail on macOS (without this PR). It passes whether or not I compile with `--enable-debug`. It does fail on Ubuntu. Yay undefined behavior... Anyway, it's a useful test. fanquake: ACK eadd130 instagibbs: utACK bitcoin@eadd130 Tree-SHA512: 7286c321f78666eea558cc591174630d210263594df41cab1065417510591ee514ade0e1d0cec8af09a785757da68de82592b013e8fe8d4966cec3254368706e
…eeFromOutputs Summary: eadd1304c81e0b89178e4cc7630bd31650850c85 tests: Add a test for funding with sufficient preset inputs and subtractFeeFromOutputs (Andrew Chow) ff330badd45067cb520b1cfa1844f60a4c9f2031 Default to bnb_used = false as there are many cases where BnB is not used (Andrew Chow) Pull request description: #17290 introduced a bug where, when we had preset inputs that covered the amount being sent and subtractFeeFrromOutputs was being used, transaction funding would result in a `Fee exceeds maximum configured by -maxtxfee` error. This was happening because we weren't setting `bnb_used = false` when the preset inputs were used as it should have been. This resulted in a too high fee because the change would go to fees accidentally. Apparently this particular case doesn't have a test, so I've added one as well. Backport of Core [[bitcoin/bitcoin#17568 | PR17568]] Depends on D7688 Test Plan: ``` ninja check test_runner.py rpc_fundrawtransaction ``` Reviewers: #bitcoin_abc, majcosta Reviewed By: #bitcoin_abc, majcosta Differential Revision: https://reviews.bitcoinabc.org/D7691
…btractFeeFromOutputs eadd130 tests: Add a test for funding with sufficient preset inputs and subtractFeeFromOutputs (Andrew Chow) ff330ba Default to bnb_used = false as there are many cases where BnB is not used (Andrew Chow) Pull request description: bitcoin#17290 introduced a bug where, when we had preset inputs that covered the amount being sent and subtractFeeFrromOutputs was being used, transaction funding would result in a `Fee exceeds maximum configured by -maxtxfee` error. This was happening because we weren't setting `bnb_used = false` when the preset inputs were used as it should have been. This resulted in a too high fee because the change would go to fees accidentally. Apparently this particular case doesn't have a test, so I've added one as well. ACKs for top commit: Sjors: ACK eadd130. I can't get this new test to fail on macOS (without this PR). It passes whether or not I compile with `--enable-debug`. It does fail on Ubuntu. Yay undefined behavior... Anyway, it's a useful test. fanquake: ACK eadd130 instagibbs: utACK bitcoin@eadd130 Tree-SHA512: 7286c321f78666eea558cc591174630d210263594df41cab1065417510591ee514ade0e1d0cec8af09a785757da68de82592b013e8fe8d4966cec3254368706e
#17290 introduced a bug where, when we had preset inputs that covered the amount being sent and subtractFeeFrromOutputs was being used, transaction funding would result in a
Fee exceeds maximum configured by -maxtxfee
error. This was happening because we weren't settingbnb_used = false
when the preset inputs were used as it should have been. This resulted in a too high fee because the change would go to fees accidentally.Apparently this particular case doesn't have a test, so I've added one as well.