Skip to content

Commit 63ac87f

Browse files
committed
merge bitcoin#22722: update estimatesmartfee rpc to return max of estimateSmartFee, mempoolMinFee and minRelayTxFee.
1 parent 07e4c2c commit 63ac87f

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

src/rpc/mining.cpp

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

11441144
CBlockPolicyEstimator& fee_estimator = EnsureAnyFeeEstimator(request.context);
1145+
const NodeContext& node = EnsureAnyNodeContext(request.context);
1146+
const CTxMemPool& mempool = EnsureMemPool(node);
11451147

11461148
unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
11471149
unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target);
@@ -1157,7 +1159,10 @@ static RPCHelpMan estimatesmartfee()
11571159
UniValue result(UniValue::VOBJ);
11581160
UniValue errors(UniValue::VARR);
11591161
FeeCalculation feeCalc;
1160-
CFeeRate feeRate = fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative);
1162+
CFeeRate feeRate{fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative)};
1163+
CFeeRate min_mempool_feerate{mempool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000)};
1164+
CFeeRate min_relay_feerate{::minRelayTxFee};
1165+
feeRate = std::max({feeRate, min_mempool_feerate, min_relay_feerate});
11611166
if (feeRate != CFeeRate(0)) {
11621167
result.pushKV("feerate", ValueFromAmount(feeRate.GetFeePerK()));
11631168
} else {

test/functional/feature_fee_estimation.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,13 @@ def check_smart_estimates(node, fees_seen):
135135
delta = 1.0e-6 # account for rounding error
136136
last_feerate = float(max(fees_seen))
137137
all_smart_estimates = [node.estimatesmartfee(i) for i in range(1, 26)]
138+
mempoolMinFee = node.getmempoolinfo()['mempoolminfee']
139+
minRelaytxFee = node.getmempoolinfo()['minrelaytxfee']
138140
for i, e in enumerate(all_smart_estimates): # estimate is for i+1
139141
feerate = float(e["feerate"])
140142
assert_greater_than(feerate, 0)
143+
assert_greater_than_or_equal(feerate, float(mempoolMinFee))
144+
assert_greater_than_or_equal(feerate, float(minRelaytxFee))
141145

142146
if feerate + delta < min(fees_seen) or feerate - delta > max(fees_seen):
143147
raise AssertionError("Estimated fee (%f) out of range (%f,%f)"
@@ -281,6 +285,13 @@ def run_test(self):
281285
self.log.info("Final estimates after emptying mempools")
282286
check_estimates(self.nodes[1], self.fees_per_kb)
283287

288+
# check that the effective feerate is greater than or equal to the mempoolminfee even for high mempoolminfee
289+
self.log.info("Test fee rate estimation after restarting node with high MempoolMinFee")
290+
high_val = 3*self.nodes[1].estimatesmartfee(1)['feerate']
291+
self.restart_node(1, extra_args=[f'-minrelaytxfee={high_val}'])
292+
check_estimates(self.nodes[1], self.fees_per_kb)
293+
self.stop_node(1, expected_stderr="Warning: -minrelaytxfee is set very high! The wallet will avoid paying less than the minimum relay fee.")
294+
284295
self.log.info("Testing that fee estimation is disabled in blocksonly.")
285296
self.restart_node(0, ["-blocksonly"])
286297
assert_raises_rpc_error(-32603, "Fee estimation disabled",

0 commit comments

Comments
 (0)