Skip to content

Commit ea31caf

Browse files
committed
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)
1 parent dccf3d2 commit ea31caf

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)