Skip to content

Commit b55232a

Browse files
committed
Merge bitcoin/bitcoin#22722: rpc: update estimatesmartfee to return max of CBlockPolicyEstimator::estimateSmartFee, mempoolMinFee and minRelayTxFee
ea31caf update estimatesmartfee rpc to return max of estimateSmartFee, mempoolMinFee and minRelayTxFee. (pranabp-bit) Pull request description: This PR is in response to the issue [#19699](bitcoin/bitcoin#19699). Based on the discussion in the comments of PR [#22673](bitcoin/bitcoin#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](bitcoin/bitcoin#16072). The test file test/functional/feature_fee_estimation.py has also been updated to check this functionality. ACKs for top commit: meshcollider: re-utACK ea31caf Tree-SHA512: 8f36153a07cbd552c5c13d11d9c6e987a7a555ea4cc83f2573c0c92dd97c706d90c30a7248671437c2f3a836d3272f8fad53d15a5fa6efaa0409ae8009b0a18d
2 parents d6492d4 + ea31caf commit b55232a

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

src/rpc/mining.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,8 @@ static RPCHelpMan estimatesmartfee()
11031103
RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
11041104

11051105
CBlockPolicyEstimator& fee_estimator = EnsureAnyFeeEstimator(request.context);
1106+
const NodeContext& node = EnsureAnyNodeContext(request.context);
1107+
const CTxMemPool& mempool = EnsureMemPool(node);
11061108

11071109
unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
11081110
unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target);
@@ -1118,7 +1120,10 @@ static RPCHelpMan estimatesmartfee()
11181120
UniValue result(UniValue::VOBJ);
11191121
UniValue errors(UniValue::VARR);
11201122
FeeCalculation feeCalc;
1121-
CFeeRate feeRate = fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative);
1123+
CFeeRate feeRate{fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative)};
1124+
CFeeRate min_mempool_feerate{mempool.GetMinFee(gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000)};
1125+
CFeeRate min_relay_feerate{::minRelayTxFee};
1126+
feeRate = std::max({feeRate, min_mempool_feerate, min_relay_feerate});
11221127
if (feeRate != CFeeRate(0)) {
11231128
result.pushKV("feerate", ValueFromAmount(feeRate.GetFeePerK()));
11241129
} else {

test/functional/feature_fee_estimation.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,13 @@ def check_smart_estimates(node, fees_seen):
132132
delta = 1.0e-6 # account for rounding error
133133
last_feerate = float(max(fees_seen))
134134
all_smart_estimates = [node.estimatesmartfee(i) for i in range(1, 26)]
135+
mempoolMinFee = node.getmempoolinfo()['mempoolminfee']
136+
minRelaytxFee = node.getmempoolinfo()['minrelaytxfee']
135137
for i, e in enumerate(all_smart_estimates): # estimate is for i+1
136138
feerate = float(e["feerate"])
137139
assert_greater_than(feerate, 0)
140+
assert_greater_than_or_equal(feerate, float(mempoolMinFee))
141+
assert_greater_than_or_equal(feerate, float(minRelaytxFee))
138142

139143
if feerate + delta < min(fees_seen) or feerate - delta > max(fees_seen):
140144
raise AssertionError(f"Estimated fee ({feerate}) out of range ({min(fees_seen)},{max(fees_seen)})")
@@ -275,6 +279,12 @@ def run_test(self):
275279
self.log.info("Final estimates after emptying mempools")
276280
check_estimates(self.nodes[1], self.fees_per_kb)
277281

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+
high_val = 3*self.nodes[1].estimatesmartfee(1)['feerate']
285+
self.restart_node(1, extra_args=[f'-minrelaytxfee={high_val}'])
286+
check_estimates(self.nodes[1], self.fees_per_kb)
287+
278288
self.log.info("Testing that fee estimation is disabled in blocksonly.")
279289
self.restart_node(0, ["-blocksonly"])
280290
assert_raises_rpc_error(-32603, "Fee estimation disabled",

0 commit comments

Comments
 (0)