Skip to content

Commit 9c85b91

Browse files
committed
Change API to estimaterawfee
Report results for all 3 possible time horizons instead of specifying time horizon as an argument.
1 parent 9edda0c commit 9c85b91

File tree

5 files changed

+67
-50
lines changed

5 files changed

+67
-50
lines changed

src/policy/feerate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class CFeeRate
4040
friend bool operator==(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK == b.nSatoshisPerK; }
4141
friend bool operator<=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK <= b.nSatoshisPerK; }
4242
friend bool operator>=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK >= b.nSatoshisPerK; }
43+
friend bool operator!=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK != b.nSatoshisPerK; }
4344
CFeeRate& operator+=(const CFeeRate& a) { nSatoshisPerK += a.nSatoshisPerK; return *this; }
4445
std::string ToString() const;
4546

src/policy/fees.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,19 @@
1616

1717
static constexpr double INF_FEERATE = 1e99;
1818

19+
std::string StringForFeeEstimateHorizon(FeeEstimateHorizon horizon) {
20+
static const std::map<FeeEstimateHorizon, std::string> horizon_strings = {
21+
{FeeEstimateHorizon::SHORT_HALFLIFE, "short"},
22+
{FeeEstimateHorizon::MED_HALFLIFE, "medium"},
23+
{FeeEstimateHorizon::LONG_HALFLIFE, "long"},
24+
};
25+
auto horizon_string = horizon_strings.find(horizon);
26+
27+
if (horizon_string == horizon_strings.end()) return "unknown";
28+
29+
return horizon_string->second;
30+
}
31+
1932
std::string StringForFeeReason(FeeReason reason) {
2033
static const std::map<FeeReason, std::string> fee_reason_strings = {
2134
{FeeReason::NONE, "None"},

src/policy/fees.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ enum FeeEstimateHorizon {
7474
LONG_HALFLIFE = 2
7575
};
7676

77+
std::string StringForFeeEstimateHorizon(FeeEstimateHorizon horizon);
78+
7779
/* Enumeration of reason for returned fee estimate */
7880
enum class FeeReason {
7981
NONE,

src/rpc/client.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ static const CRPCConvertParam vRPCConvertParams[] =
113113
{ "estimatesmartfee", 1, "conservative" },
114114
{ "estimaterawfee", 0, "nblocks" },
115115
{ "estimaterawfee", 1, "threshold" },
116-
{ "estimaterawfee", 2, "horizon" },
117116
{ "prioritisetransaction", 1, "dummy" },
118117
{ "prioritisetransaction", 2, "fee_delta" },
119118
{ "setban", 2, "bantime" },

src/rpc/mining.cpp

Lines changed: 51 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -838,9 +838,9 @@ UniValue estimatesmartfee(const JSONRPCRequest& request)
838838

839839
UniValue estimaterawfee(const JSONRPCRequest& request)
840840
{
841-
if (request.fHelp || request.params.size() < 1|| request.params.size() > 3)
841+
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
842842
throw std::runtime_error(
843-
"estimaterawfee nblocks (threshold horizon)\n"
843+
"estimaterawfee nblocks (threshold)\n"
844844
"\nWARNING: This interface is unstable and may disappear or change!\n"
845845
"\nWARNING: This is an advanced API call that is tightly coupled to the specific\n"
846846
" implementation of fee estimation. The parameters it can be called with\n"
@@ -853,68 +853,70 @@ UniValue estimaterawfee(const JSONRPCRequest& request)
853853
"2. threshold (numeric, optional) The proportion of transactions in a given feerate range that must have been\n"
854854
" confirmed within nblocks in order to consider those feerates as high enough and proceed to check\n"
855855
" lower buckets. Default: 0.95\n"
856-
"3. horizon (numeric, optional) How long a history of estimates to consider. 0=short, 1=medium, 2=long.\n"
857-
" Default: 1\n"
858856
"\nResult:\n"
859857
"{\n"
860-
" \"feerate\" : x.x, (numeric) estimate fee-per-kilobyte (in BTC)\n"
861-
" \"decay\" : x.x, (numeric) exponential decay (per block) for historical moving average of confirmation data\n"
862-
" \"scale\" : x, (numeric) The resolution of confirmation targets at this time horizon\n"
863-
" \"pass\" : { (json object) information about the lowest range of feerates to succeed in meeting the threshold\n"
864-
" \"startrange\" : x.x, (numeric) start of feerate range\n"
865-
" \"endrange\" : x.x, (numeric) end of feerate range\n"
866-
" \"withintarget\" : x.x, (numeric) number of txs over history horizon in the feerate range that were confirmed within target\n"
867-
" \"totalconfirmed\" : x.x, (numeric) number of txs over history horizon in the feerate range that were confirmed at any point\n"
868-
" \"inmempool\" : x.x, (numeric) current number of txs in mempool in the feerate range unconfirmed for at least target blocks\n"
869-
" \"leftmempool\" : x.x, (numeric) number of txs over history horizon in the feerate range that left mempool unconfirmed after target\n"
870-
" }\n"
871-
" \"fail\" : { ... } (json object) information about the highest range of feerates to fail to meet the threshold\n"
858+
" \"short\" : { (json object) estimate for short time horizon\n"
859+
" \"feerate\" : x.x, (numeric) estimate fee-per-kilobyte (in BTC)\n"
860+
" \"decay\" : x.x, (numeric) exponential decay (per block) for historical moving average of confirmation data\n"
861+
" \"scale\" : x, (numeric) The resolution of confirmation targets at this time horizon\n"
862+
" \"pass\" : { (json object) information about the lowest range of feerates to succeed in meeting the threshold\n"
863+
" \"startrange\" : x.x, (numeric) start of feerate range\n"
864+
" \"endrange\" : x.x, (numeric) end of feerate range\n"
865+
" \"withintarget\" : x.x, (numeric) number of txs over history horizon in the feerate range that were confirmed within target\n"
866+
" \"totalconfirmed\" : x.x, (numeric) number of txs over history horizon in the feerate range that were confirmed at any point\n"
867+
" \"inmempool\" : x.x, (numeric) current number of txs in mempool in the feerate range unconfirmed for at least target blocks\n"
868+
" \"leftmempool\" : x.x, (numeric) number of txs over history horizon in the feerate range that left mempool unconfirmed after target\n"
869+
" },\n"
870+
" \"fail\" : { ... }, (json object) information about the highest range of feerates to fail to meet the threshold\n"
871+
" },\n"
872+
" \"medium\" : { ... }, (json object) estimate for medium time horizon\n"
873+
" \"long\" : { ... } (json object) estimate for long time horizon\n"
872874
"}\n"
873875
"\n"
874876
"A negative feerate is returned if no answer can be given.\n"
875877
"\nExample:\n"
876-
+ HelpExampleCli("estimaterawfee", "6 0.9 1")
878+
+ HelpExampleCli("estimaterawfee", "6 0.9")
877879
);
878880

879881
RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VNUM, UniValue::VNUM}, true);
880882
RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
881883
int nBlocks = request.params[0].get_int();
882884
double threshold = 0.95;
883-
if (!request.params[1].isNull())
885+
if (!request.params[1].isNull()) {
884886
threshold = request.params[1].get_real();
885-
FeeEstimateHorizon horizon = FeeEstimateHorizon::MED_HALFLIFE;
886-
if (!request.params[2].isNull()) {
887-
int horizonInt = request.params[2].get_int();
888-
if (horizonInt < 0 || horizonInt > 2) {
889-
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid horizon for fee estimates");
890-
} else {
891-
horizon = (FeeEstimateHorizon)horizonInt;
892-
}
893887
}
888+
894889
UniValue result(UniValue::VOBJ);
895-
CFeeRate feeRate;
896-
EstimationResult buckets;
897-
feeRate = ::feeEstimator.estimateRawFee(nBlocks, threshold, horizon, &buckets);
898890

899-
result.push_back(Pair("feerate", feeRate == CFeeRate(0) ? -1.0 : ValueFromAmount(feeRate.GetFeePerK())));
900-
result.push_back(Pair("decay", buckets.decay));
901-
result.push_back(Pair("scale", (int)buckets.scale));
902-
UniValue passbucket(UniValue::VOBJ);
903-
passbucket.push_back(Pair("startrange", round(buckets.pass.start)));
904-
passbucket.push_back(Pair("endrange", round(buckets.pass.end)));
905-
passbucket.push_back(Pair("withintarget", round(buckets.pass.withinTarget * 100.0) / 100.0));
906-
passbucket.push_back(Pair("totalconfirmed", round(buckets.pass.totalConfirmed * 100.0) / 100.0));
907-
passbucket.push_back(Pair("inmempool", round(buckets.pass.inMempool * 100.0) / 100.0));
908-
passbucket.push_back(Pair("leftmempool", round(buckets.pass.leftMempool * 100.0) / 100.0));
909-
result.push_back(Pair("pass", passbucket));
910-
UniValue failbucket(UniValue::VOBJ);
911-
failbucket.push_back(Pair("startrange", round(buckets.fail.start)));
912-
failbucket.push_back(Pair("endrange", round(buckets.fail.end)));
913-
failbucket.push_back(Pair("withintarget", round(buckets.fail.withinTarget * 100.0) / 100.0));
914-
failbucket.push_back(Pair("totalconfirmed", round(buckets.fail.totalConfirmed * 100.0) / 100.0));
915-
failbucket.push_back(Pair("inmempool", round(buckets.fail.inMempool * 100.0) / 100.0));
916-
failbucket.push_back(Pair("leftmempool", round(buckets.fail.leftMempool * 100.0) / 100.0));
917-
result.push_back(Pair("fail", failbucket));
891+
for (FeeEstimateHorizon horizon : {FeeEstimateHorizon::SHORT_HALFLIFE, FeeEstimateHorizon::MED_HALFLIFE, FeeEstimateHorizon::LONG_HALFLIFE}) {
892+
CFeeRate feeRate;
893+
EstimationResult buckets;
894+
feeRate = ::feeEstimator.estimateRawFee(nBlocks, threshold, horizon, &buckets);
895+
896+
UniValue horizon_result(UniValue::VOBJ);
897+
horizon_result.push_back(Pair("feerate", feeRate == CFeeRate(0) ? -1.0 : ValueFromAmount(feeRate.GetFeePerK())));
898+
if (!(feeRate == CFeeRate(0))) {
899+
horizon_result.push_back(Pair("decay", buckets.decay));
900+
horizon_result.push_back(Pair("scale", (int)buckets.scale));
901+
UniValue passbucket(UniValue::VOBJ);
902+
passbucket.push_back(Pair("startrange", round(buckets.pass.start)));
903+
passbucket.push_back(Pair("endrange", round(buckets.pass.end)));
904+
passbucket.push_back(Pair("withintarget", round(buckets.pass.withinTarget * 100.0) / 100.0));
905+
passbucket.push_back(Pair("totalconfirmed", round(buckets.pass.totalConfirmed * 100.0) / 100.0));
906+
passbucket.push_back(Pair("inmempool", round(buckets.pass.inMempool * 100.0) / 100.0));
907+
passbucket.push_back(Pair("leftmempool", round(buckets.pass.leftMempool * 100.0) / 100.0));
908+
horizon_result.push_back(Pair("pass", passbucket));
909+
UniValue failbucket(UniValue::VOBJ);
910+
failbucket.push_back(Pair("startrange", round(buckets.fail.start)));
911+
failbucket.push_back(Pair("endrange", round(buckets.fail.end)));
912+
failbucket.push_back(Pair("withintarget", round(buckets.fail.withinTarget * 100.0) / 100.0));
913+
failbucket.push_back(Pair("totalconfirmed", round(buckets.fail.totalConfirmed * 100.0) / 100.0));
914+
failbucket.push_back(Pair("inmempool", round(buckets.fail.inMempool * 100.0) / 100.0));
915+
failbucket.push_back(Pair("leftmempool", round(buckets.fail.leftMempool * 100.0) / 100.0));
916+
horizon_result.push_back(Pair("fail", failbucket));
917+
}
918+
result.push_back(Pair(StringForFeeEstimateHorizon(horizon), horizon_result));
919+
}
918920
return result;
919921
}
920922

@@ -932,7 +934,7 @@ static const CRPCCommand commands[] =
932934
{ "util", "estimatefee", &estimatefee, true, {"nblocks"} },
933935
{ "util", "estimatesmartfee", &estimatesmartfee, true, {"nblocks", "conservative"} },
934936

935-
{ "hidden", "estimaterawfee", &estimaterawfee, true, {"nblocks", "threshold", "horizon"} },
937+
{ "hidden", "estimaterawfee", &estimaterawfee, true, {"nblocks", "threshold"} },
936938
};
937939

938940
void RegisterMiningRPCCommands(CRPCTable &t)

0 commit comments

Comments
 (0)