rpc: update estimatesmartfee to return max of CBlockPolicyEstimator::estimateSmartFee, mempoolMinFee and minRelayTxFee #22722

pull pranabp-bit wants to merge 1 commits into bitcoin:master from pranabp-bit:estimatesmartfee changing 2 files +16 −1
  1. pranabp-bit commented at 6:51 am on August 17, 2021: contributor

    This PR is in response to the issue #19699.

    Based on the discussion in the comments of PR #22673 changes have been made in the estimatesmartfee itself such that it takes into account mempoolMinFee and relayMinFee . Hence it provides a fee estimate that is most likely to be paid by the user in an actual transaction, preventing issues such as #16072.

    The test file test/functional/feature_fee_estimation.py has also been updated to check this functionality.

  2. DrahtBot added the label Mining on Aug 17, 2021
  3. DrahtBot added the label RPC/REST/ZMQ on Aug 17, 2021
  4. in src/rpc/mining.cpp:1125 in 3f3e2b962c outdated
    1120+        feeRate = min_mempool_feerate;
    1121+    }
    1122+    CFeeRate min_relay_feerate = ::minRelayTxFee;
    1123+    if (feeRate < min_relay_feerate) {
    1124+        feeRate = min_relay_feerate;
    1125+    }
    


    jonatack commented at 8:19 am on August 17, 2021:

    Suggestion, you could use braced initialization and std::max with an initializer list.

     0-    CFeeRate feeRate = fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative);
     1-    CFeeRate min_mempool_feerate = mempool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
     2-    if (feeRate < min_mempool_feerate) {
     3-        feeRate = min_mempool_feerate;
     4-    }
     5-    CFeeRate min_relay_feerate = ::minRelayTxFee;
     6-    if (feeRate < min_relay_feerate) {
     7-        feeRate = min_relay_feerate;
     8-    }
     9+    CFeeRate feeRate{fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative)};
    10+    CFeeRate min_mempool_feerate{mempool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000)};
    11+    CFeeRate min_relay_feerate{::minRelayTxFee};
    12+    feeRate = std::max({feeRate, min_mempool_feerate, min_relay_feerate});
    
  5. in test/functional/feature_fee_estimation.py:286 in 3f3e2b962c outdated
    281@@ -278,6 +282,11 @@ def run_test(self):
    282         self.log.info("Final estimates after emptying mempools")
    283         check_estimates(self.nodes[1], self.fees_per_kb)
    284 
    285+        # check that the effective feerate is greater than or equal to the mempoolminfee even for high mempoolminfee
    286+        self.log.info("Estimates after restarting node with high MempoolMinFee")
    


    jonatack commented at 8:21 am on August 17, 2021:
    0        self.log.info("Test fee rate estimation after restarting node with high MempoolMinFee")
    
  6. in test/functional/feature_fee_estimation.py:142 in 3f3e2b962c outdated
    137+    minRelaytxFee = node.getmempoolinfo()['minrelaytxfee']
    138     for i, e in enumerate(all_smart_estimates):  # estimate is for i+1
    139         feerate = float(e["feerate"])
    140         assert_greater_than(feerate, 0)
    141+        assert_greater_than_or_equal(feerate,float(mempoolMinFee))
    142+        assert_greater_than_or_equal(feerate,float(minRelaytxFee))
    


    jonatack commented at 8:21 am on August 17, 2021:

    nit, missing space

    0-        assert_greater_than_or_equal(feerate,float(mempoolMinFee))
    1-        assert_greater_than_or_equal(feerate,float(minRelaytxFee))
    2+        assert_greater_than_or_equal(feerate, float(mempoolMinFee))
    3+        assert_greater_than_or_equal(feerate, float(minRelaytxFee))
    
  7. jonatack commented at 8:23 am on August 17, 2021: member
    Concept ACK
  8. in src/rpc/mining.cpp:1100 in 3f3e2b962c outdated
    1096@@ -1097,6 +1097,8 @@ static RPCHelpMan estimatesmartfee()
    1097     RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
    1098 
    1099     CBlockPolicyEstimator& fee_estimator = EnsureAnyFeeEstimator(request.context);
    1100+    NodeContext& node = EnsureAnyNodeContext(request.context);
    


    jonatack commented at 8:26 am on August 17, 2021:

    can be const

    0    const NodeContext& node = EnsureAnyNodeContext(request.context);
    
  9. ghost commented at 8:37 am on August 17, 2021: none

    Concept ACK (Including mempoolMinFee)

    estimatesmartfee should become better (smart) after this change although I am not sure about the approach. Will test it today.

  10. kristapsk commented at 6:14 pm on August 17, 2021: contributor
    Concept ACK
  11. ghost commented at 1:16 pm on August 19, 2021: none

    Tried this on Pop!_OS with regtest. Initially had issues understanding how GetMinFee() works, Andrew Chow answered it in detail on stackexchange: https://bitcoin.stackexchange.com/questions/108126/getminfee-in-blockchain-cpp

    I saved minrelaytxfee 0.0002 similar to /test/functional/feature_fee_estimation.py and did some test transactions with different fee rate.

    image

    estimatesmartfee suggests 20 sat/vB conf_target 2

    Changed minrelaytxfee to 0.00001 (default value)

    image

    estimatesmartfee suggests 1 sat/vB conf_target 2

    Expected results:

    0$bitcoin-cli estimatesmartfee 1
    1
    2{
    3  "feerate_min": 0.00001000
    4  "feerate_max": 0.00020000
    5  "blocks: 2
    6}
    
    0$bitcoin-cli estimatesmartfee 1
    1
    2{
    3  "feerate_min": 0.00001000
    4  "feerate_max": 0.00100000
    5  "blocks: 2
    6}
    

    feerate_min based on mempool fee rate distribution and feerate_max is the fee_rate returned right now

    How to calculate feerate_min when conf_target is 2 ?

    1. 2 * average_block_vsize where average_block_vsize is average virtual size of last N blocks

    2. bytes from getmempoolinfo

    3. if ((bytes/ 2 * average_block_vsize) < 1 use minimum fee rate from getmempoolinfo else use same as feerate_max.

    Why this will be useful?

    1. Users get a range instead of one fee rate
    2. Better estimates based on fee rates in mempool
    3. Can use feerate_min for RBF transaction and replace with feerate_max if not confirmed in next block

    conf_target works for 1 to 1008 blocks right now. This can be reduced to 1-10 if others agree to change it.

    https://github.com/TrueLevelSA/btc-congestion-manager

    It returns mempool position which can be added in output for estimatesmartfee:

    image

  12. darosior commented at 7:02 am on August 20, 2021: member
    Concept ACK, but i think this should not be restricted to the estimatesmartfee RPC. Maybe we could have a wrapper to CBlockPolicyEstimator’s estimateSmartFee in CTxMemPool that would return the max of minerPolicyEstimator->estimateSmartFee() and GetMinFee? This way the node interface would call this wrapper instead of the estimator’s one and it would apply this behaviour to all the current call sites.
  13. pranabp-bit commented at 8:16 am on August 23, 2021: contributor
    @prayank23 Thank you for the detailed review. Just wanted to confirm, are you suggesting to change estimatesmartfee such that is returns “feerate_min” and “feerate_max” ? If yes, then maybe I could try that later in a different PR.
  14. pranabp-bit commented at 12:06 pm on August 23, 2021: contributor
    @darosior Thank you for the suggestion. But as of now, I only found one other call for the estimateSmartFee and it was in the GetMinimumFeeRate function. And this function returns the feerate_needed after considering the mempoolMinFee. So maybe we can keep this change limited to the estimatesmartfee RPC.
  15. darosior commented at 12:17 pm on August 23, 2021: member

    But as of now, I only found one other call

    Sounds good to me, it’s already a fix as is and we can always de-duplicate the min(estimateSmarFee, mempoolMinFee) logic in a folowup.

  16. ghost commented at 12:42 pm on August 23, 2021: none

    are you suggesting to change estimatesmartfee such that is returns “feerate_min” and “feerate_max” ? If yes, then maybe I could try that later in a different PR.

    Yes. We could do something similar in follow up to improve estimatesmartfee. However, I also wanted to share that results for estimatesmartfee even after this PR are not helpful or misleading in some cases.

    For example: In first case mempool has some transactions with fee rate ranging from 1 to 100 sat/vB (less than 2MvB), estimatesmartfee should suggest fee rate close to 1 sat/vB for conf_target 2. It shows 20x what we actually need minimum at that moment.

  17. instagibbs commented at 10:33 pm on August 25, 2021: member
    concept ACK, can you please squash?
  18. pranabp-bit force-pushed on Aug 26, 2021
  19. in test/functional/feature_fee_estimation.py:284 in c7e871dd12 outdated
    278@@ -275,6 +279,11 @@ def run_test(self):
    279         self.log.info("Final estimates after emptying mempools")
    280         check_estimates(self.nodes[1], self.fees_per_kb)
    281 
    282+        # check that the effective feerate is greater than or equal to the mempoolminfee even for high mempoolminfee
    283+        self.log.info("Test fee rate estimation after restarting node with high MempoolMinFee")
    284+        self.restart_node(1, extra_args=['-minrelaytxfee=0.0003'])
    


    instagibbs commented at 2:35 am on August 26, 2021:
    can we programmatically make sure that this new minrelaytxfee value is higher than before to avoid regressions?
  20. instagibbs approved
  21. instagibbs commented at 2:36 am on August 26, 2021: member
    ACK aside from test nit
  22. pranabp-bit force-pushed on Aug 26, 2021
  23. pranabp-bit commented at 4:08 am on August 28, 2021: contributor
    I updated the test such that in the end, it sets the minrelaytxfee to a value which is 3 times the estimatesmartfee(1) called from the same node. So the test would be more robust against future changes than the previous one in which I set it directly to “0.0003”. I have incorporated most of the suggestions I got, and some of them, I would take up as follow-up in the future. But for now, do suggest if any other change is required in the current PR.
  24. laanwj commented at 6:43 pm on September 16, 2021: member
    Can you please change to a more descriptive PR title and commit message? “update estimatesmartfee” doesn’t say much :smile:
  25. pranabp-bit force-pushed on Sep 17, 2021
  26. pranabp-bit renamed this:
    rpc: update estimatesmartfee
    rpc: update estimatesmartfee to return max of CBlockPolicyEstimator::estimateSmartFee, mempoollMinFee and minRelayTxFee
    on Sep 17, 2021
  27. DrahtBot commented at 1:35 am on September 24, 2021: member

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #23074 (Package-aware fee estimation by darosior)
    • #22539 (Re-include RBF replacement txs in fee estimation by darosior)

    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.

  28. meshcollider commented at 12:45 pm on September 27, 2021: contributor
    utACK b2152f3ff21aeee185be6dcfcfcc73b28d989de2
  29. MarcoFalke renamed this:
    rpc: update estimatesmartfee to return max of CBlockPolicyEstimator::estimateSmartFee, mempoollMinFee and minRelayTxFee
    rpc: update estimatesmartfee to return max of CBlockPolicyEstimator::estimateSmartFee, mempoolMinFee and minRelayTxFee
    on Sep 27, 2021
  30. darosior commented at 3:43 pm on September 27, 2021: member
    utACK b2152f3ff21aeee185be6dcfcfcc73b28d989de2
  31. in src/rpc/mining.cpp:1124 in b2152f3ff2 outdated
    1114@@ -1113,7 +1115,10 @@ static RPCHelpMan estimatesmartfee()
    1115     UniValue result(UniValue::VOBJ);
    1116     UniValue errors(UniValue::VARR);
    1117     FeeCalculation feeCalc;
    1118-    CFeeRate feeRate = fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative);
    1119+    CFeeRate feeRate{fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative)};
    1120+    CFeeRate min_mempool_feerate{mempool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000)};
    


    meshcollider commented at 2:57 am on September 28, 2021:
    Silent merge conflict: this needs to use gArgs.GetIntArg now (as of #22976)
  32. pranabp-bit force-pushed on Sep 28, 2021
  33. pranabp-bit force-pushed on Sep 28, 2021
  34. update estimatesmartfee rpc to return max of estimateSmartFee, mempoolMinFee and minRelayTxFee.
    This will provide better estimates which would be closer to fee paid in actual
    transactions.
    The test has also been changed such that when the node is restarted with a
    high mempoolMinFee, the estimatesmartfee still returns a feeRate greater
    than or equal to the mempoolMinFee, minRelayTxFee.(just like the feeRate of actual transactions)
    ea31caf6b4
  35. pranabp-bit force-pushed on Sep 28, 2021
  36. meshcollider commented at 9:55 pm on September 28, 2021: contributor
    re-utACK ea31caf6b4c182c6f10f136548f84e603800511c
  37. meshcollider merged this on Sep 28, 2021
  38. meshcollider closed this on Sep 28, 2021

  39. sidhujag referenced this in commit efce452c82 on Sep 28, 2021
  40. luke-jr referenced this in commit 73a5d927f3 on Oct 10, 2021
  41. MarcoFalke referenced this in commit 084c81c8b6 on Dec 7, 2021
  42. sidhujag referenced this in commit eb5c717d65 on Dec 7, 2021
  43. luke-jr referenced this in commit e4fbffea5d on Dec 14, 2021
  44. DrahtBot locked this on Oct 30, 2022

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-12-03 15:12 UTC

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