Wallet: Catches situations where capping on maxtxfee drops the fee too low #16192

pull gertjaap wants to merge 1 commits into bitcoin:master from gertjaap:issue-10122 changing 5 files +121 −0
  1. gertjaap commented at 7:19 am on June 12, 2019: contributor

    This is a possible fix for #10122

    If the fee is capped on -maxtxfee, it will check if the fee is still above -mintxfee and -paytxfee for the given transaction. However, it seems this is a very edge case. In order to run into this, I had to pass -maxtxfee=0.01 -mintxfee=0.005 and then send a transaction that was about 89kB.

    It seems that under the defaults no one would run into this; but maybe there’s more scenario’s under which this would be a problem.

  2. DrahtBot added the label Wallet on Jun 12, 2019
  3. MarcoFalke commented at 10:04 am on June 12, 2019: member
    ACK. Don’t forget to update the help text for the option and add some release notes. A test would be nice.
  4. gertjaap commented at 12:38 pm on June 12, 2019: contributor

    @MarcoFalke the help text already contains ...setting this too low may abort large transactions.. It feels redundant to add something like If this maximum makes the fee per kB for a transaction lower than -mintxfee, it will be aborted.?

    How do I add release notes?

  5. MarcoFalke commented at 12:44 pm on June 12, 2019: member

    To add release notes run vim doc/release-notes-16192.md and type

    0Wallet
    1------
    2
    3- blabla
    
  6. gertjaap renamed this:
    Catches situations where capping on maxtxfee drops the fee too low
    Wallet: Catches situations where capping on maxtxfee drops the fee too low
    on Jun 12, 2019
  7. kristapsk commented at 1:04 pm on June 12, 2019: contributor
    Would like to have a test for this too, otherwise ACK.
  8. promag commented at 1:10 pm on June 12, 2019: member
    I think a test must be added.
  9. Empact commented at 1:45 pm on June 12, 2019: member
    Concept ACK - please add test
  10. gertjaap commented at 1:52 pm on June 12, 2019: contributor
    While writing the test I realized that it makes sense to check both the -paytxfee and -mintxfee settings. When capping the fee on -maxtxfee, it should still be above both, imo?
  11. in src/wallet/wallet.cpp:2967 in 4079a7d550 outdated
    2958@@ -2959,6 +2959,16 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
    2959                     return false;
    2960                 }
    2961 
    2962+                // If the fee was capped to MAXTXFEE and this results in a too low fee rate given our current
    2963+                // configuration, abort.
    2964+                if (feeCalc.reason == FeeReason::MAXTXFEE && nFeeNeeded < m_pay_tx_fee.GetFee(nBytes)) {
    2965+                    strFailReason = _("Transaction is too large to fit in the maximum fee at the configured fixed fee rate");
    2966+                    return false;
    2967+                } else if (feeCalc.reason == FeeReason::MAXTXFEE && nFeeNeeded < m_min_fee.GetFee(nBytes)) {
    


    promag commented at 2:10 pm on June 12, 2019:
    remove else.

    gertjaap commented at 4:24 pm on June 12, 2019:
    Adjusted
  12. in src/wallet/test/wallet_tests.cpp:527 in 4079a7d550 outdated
    521+        BOOST_CHECK(!result);
    522+        BOOST_CHECK(error.compare("Transaction is too large to fit in the maximum fee at the minimum fee rate") == 0);
    523+    } 
    524+}
    525+
    526+
    


    promag commented at 2:12 pm on June 12, 2019:
    nit, remove unnecessary lines.

    gertjaap commented at 4:24 pm on June 12, 2019:
    Adjusted
  13. Empact commented at 2:20 pm on June 12, 2019: member

    https://github.com/bitcoin/bitcoin/pull/16192/commits/58ac729278b71a0fc3d4795777593ffd266dfc2a is unnecessary as the condition will short-circuit. I.e. GetFee already won’t be called if the reason is different.

    For the built-in logical AND operator, the result is true if both operands are true. Otherwise, the result is false. This operator is short-circuiting: if the first operand is false, the second operand is not evaluated https://en.cppreference.com/w/cpp/language/operator_logical

  14. gertjaap force-pushed on Jun 12, 2019
  15. gertjaap commented at 2:24 pm on June 12, 2019: contributor
    @Empact you’re right. Wouldn’t it still run the comparison twice in situations where feeCalc.reason != FeeReason::MAXTXFEE
  16. Empact commented at 2:49 pm on June 12, 2019: member

    Wouldn’t it still run the comparison twice in situations where feeCalc.reason != FeeReason::MAXTXFEE

    Would expect it to be optimized out by essentially any compiler.

  17. in src/wallet/wallet.cpp:2968 in 5f508cd314 outdated
    2963+                // configuration, abort.
    2964+                if (feeCalc.reason == FeeReason::MAXTXFEE) {
    2965+                    if (nFeeNeeded < m_pay_tx_fee.GetFee(nBytes)) {
    2966+                        strFailReason = _("Transaction is too large to fit in the maximum fee at the configured fixed fee rate");
    2967+                        return false;
    2968+                    } else if (nFeeNeeded < m_min_fee.GetFee(nBytes)) {
    


    promag commented at 3:23 pm on June 12, 2019:
    Remove else?

    gertjaap commented at 4:24 pm on June 12, 2019:
    Adjusted
  18. in src/wallet/wallet.cpp:2969 in 5f508cd314 outdated
    2964+                if (feeCalc.reason == FeeReason::MAXTXFEE) {
    2965+                    if (nFeeNeeded < m_pay_tx_fee.GetFee(nBytes)) {
    2966+                        strFailReason = _("Transaction is too large to fit in the maximum fee at the configured fixed fee rate");
    2967+                        return false;
    2968+                    } else if (nFeeNeeded < m_min_fee.GetFee(nBytes)) {
    2969+                        strFailReason = _("Transaction is too large to fit in the maximum fee at the minimum fee rate");
    


    promag commented at 3:24 pm on June 12, 2019:
    Is it me or this message is kind of confusing? Is it worth mentioning fit in the maximum fee?

    gertjaap commented at 4:28 pm on June 12, 2019:
    It is a tad confusing, but by removing the ...to fit in the maximum fee... etc would make it collide with this. It’s the combination of size and fee parameters that makes it fail - not just the size.

    promag commented at 7:26 pm on June 12, 2019:
    I think I didn’t explain well. I mean something as simple as fee rate too low?

    gertjaap commented at 6:22 am on June 13, 2019:
    Changed to Fee rate too low after limiting to -maxtxfee. Just specifying fee rate too low could get people thinking they configured it too low, which is not necessarily the case. Increasing the configured fee would make the problem worse.
  19. in doc/release-notes-16192.md:5 in 5f508cd314 outdated
    0@@ -0,0 +1,12 @@
    1+Wallet: Transaction fees
    2+------------------------
    3+
    4+Bitcoin Core caps fees at `-maxtxfee=<x>` (default: 
    


    promag commented at 3:29 pm on June 12, 2019:
    How about Currently the wallet caps fees at ...?

    gertjaap commented at 4:23 pm on June 12, 2019:
    Adjusted
  20. promag commented at 3:30 pm on June 12, 2019: member
    Concept ACK. Maybe a functional test could also be added?
  21. gertjaap commented at 4:05 pm on June 12, 2019: contributor

    OK, I can revert it if that’s desirable. Any pointers as to why example_test.py is failing?

    EDIT: Never mind, it succeeded on the next check-in - must have been some transient issue

  22. in src/wallet/test/wallet_tests.cpp:512 in af2ef5d739 outdated
    507+    wallet->m_pay_tx_fee = CFeeRate(CAmount(5000000));
    508+    {
    509+        auto locked_chain = chain->lock();
    510+        bool result = wallet->CreateTransaction(*locked_chain, recips, tx, reservekey, fee, changePos, error, dummy);
    511+        BOOST_CHECK(!result);
    512+        BOOST_CHECK(error.compare("Transaction is too large to fit in the maximum fee at the configured fixed fee rate") == 0);
    


    promag commented at 7:22 pm on June 12, 2019:
    nit, use BOOST_CHECK_EQUAL(error, ...).

    gertjaap commented at 6:21 am on June 13, 2019:
    Adjusted
  23. fanquake commented at 7:51 am on June 13, 2019: member
    Please squash your commits when you’ve finished addressing review comments.
  24. fanquake added the label Waiting for author on Jun 13, 2019
  25. gertjaap force-pushed on Jun 13, 2019
  26. gertjaap force-pushed on Jun 13, 2019
  27. gertjaap commented at 8:35 am on June 13, 2019: contributor
    @fanquake Done!
  28. fanquake removed the label Waiting for author on Jun 13, 2019
  29. in src/wallet/test/wallet_tests.cpp:490 in edc4366e5f outdated
    485+    CWallet::ScanResult result = wallet->ScanForWalletTransactions(::ChainActive().Genesis()->GetBlockHash(), {} /* stop_block */, reserver, false /* update */);
    486+
    487+    // Create a transaction with a lot of outputs so it's big enough to trigger the error at
    488+    // the configured paytxfee and mintxfee levels.
    489+    std::vector<CRecipient> recips = {};
    490+    recips.resize(8000,CRecipient{GetScriptForRawPubKey({}), 5000, false /* subtract fee */});
    


    promag commented at 10:09 pm on June 13, 2019:
    nit, missing space after , in a couple of places.

    MarcoFalke commented at 9:54 am on June 14, 2019:
    Don’t forget to install clang-format and run the https://github.com/bitcoin/bitcoin/tree/master/contrib/devtools#clang-format-diffpy script to preempt whitespace nitpicking.

    gertjaap commented at 11:31 am on June 14, 2019:
    Thanks! Ran it, squashed & pushed.
  30. gertjaap force-pushed on Jun 14, 2019
  31. Empact commented at 2:12 pm on June 14, 2019: member
    0wallet/test/wallet_tests.cpp:49:25: warning: unused variable 'result' [-Wunused-variable]
    1    CWallet::ScanResult result = wallet->ScanForWalletTransactions(::ChainActive().Genesis()->GetBlockHash(), {} /* stop_block */, reserver, false /* update */);
    

    Could use:

    0BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS);
    

    (line numbers are off because I saw this when running the new test case against the current master)

  32. gertjaap force-pushed on Jun 14, 2019
  33. gertjaap force-pushed on Jun 14, 2019
  34. gertjaap commented at 4:03 pm on June 14, 2019: contributor
    Fixed that in the test. Did however not get that warning myself while compiling (using gcc version 7.4)
  35. Empact commented at 4:08 pm on June 14, 2019: member

    FTR I’m running with:

    0$ gcc --version
    1Apple LLVM version 10.0.1 (clang-1001.0.46.4)
    2Target: x86_64-apple-darwin18.6.0
    
  36. gertjaap force-pushed on Jun 20, 2019
  37. gertjaap commented at 2:29 pm on June 20, 2019: contributor
    Added a functional test as well.
  38. gertjaap commented at 4:06 pm on June 20, 2019: contributor
    I think this is ready for a final review
  39. in test/functional/wallet_maxtxfee.py:21 in f947c151b6 outdated
    16+
    17+    def run_test(self):
    18+        self.nodes[0].generate(105)
    19+
    20+        outputs = {}
    21+        
    


    MarcoFalke commented at 5:04 pm on June 20, 2019:

    gertjaap commented at 6:51 pm on June 20, 2019:
    Fixed the linting errors, sorry about that. I managed to figure out how to run these locally before I commit now. So this shouldn’t happen to me again.
  40. MarcoFalke commented at 5:04 pm on June 20, 2019: member
    There is some trailing white-space in some files, which is why travis failed.
  41. MarcoFalke closed this on Jun 20, 2019

  42. MarcoFalke reopened this on Jun 20, 2019

  43. Catches a cap on maxtxfee making the fee too low 5a1726517b
  44. gertjaap force-pushed on Jun 20, 2019
  45. Sjors commented at 1:48 am on June 21, 2019: member
    See also #16257 which removes the fee cap entirely and instead throws if -maxtxfee is exceeded.
  46. meshcollider commented at 10:21 pm on June 27, 2019: contributor
    @gertjaap appreciate your work! But I think we will close this in favour of #16257 because it seems like it is much safer in general and solves this issue in the process. Thanks for contributing :)
  47. meshcollider closed this on Jun 27, 2019

  48. DrahtBot locked this on Dec 16, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-07-05 22:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me