Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions doc/release-notes-30275.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
RPC
---

- The default mode for the `estimatesmartfee` RPC has been updated from `conservative` to `economical`.
which is expected to reduce overestimation for many users, particularly if Replace-by-Fee is an option.
For users that require high confidence in their fee estimates at the cost of potentially overestimating,
the `conservative` mode remains available.
28 changes: 28 additions & 0 deletions src/common/messages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,34 @@ const std::vector<std::pair<std::string, FeeEstimateMode>>& FeeModeMap()
return FEE_MODES;
}

std::string FeeModeInfo(const std::pair<std::string, FeeEstimateMode>& mode, std::string& default_info)
{
switch (mode.second) {
case FeeEstimateMode::UNSET:
return strprintf("%s means no mode set (%s). \n", mode.first, default_info);
case FeeEstimateMode::ECONOMICAL:
return strprintf("%s estimates use a shorter time horizon, making them more\n"
"responsive to short-term drops in the prevailing fee market. This mode\n"
"potentially returns a lower fee rate estimate.\n", mode.first);
case FeeEstimateMode::CONSERVATIVE:
return strprintf("%s estimates use a longer time horizon, making them\n"
"less responsive to short-term drops in the prevailing fee market. This mode\n"
"potentially returns a higher fee rate estimate.\n", mode.first);
default:
// Other modes apart from the ones handled are fee rate units; they should not be clarified.
assert(false);
}
}

std::string FeeModesDetail(std::string default_info)
{
std::string info;
for (const auto& fee_mode : FeeModeMap()) {
info += FeeModeInfo(fee_mode, default_info);
}
return strprintf("%s \n%s", FeeModes(", "), info);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitty nit: If this file ends up being changed again, could remove the extra space between the first %s and the newline.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you.
I will address this and @willcl-ark nit if there is need to retouch.

}

std::string FeeModes(const std::string& delimiter)
{
return Join(FeeModeMap(), delimiter, [&](const std::pair<std::string, FeeEstimateMode>& i) { return i.first; });
Expand Down
2 changes: 2 additions & 0 deletions src/common/messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ enum class PSBTError;
bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode);
std::string StringForFeeReason(FeeReason reason);
std::string FeeModes(const std::string& delimiter);
std::string FeeModeInfo(std::pair<std::string, FeeEstimateMode>& mode);
std::string FeeModesDetail(std::string default_info);
std::string InvalidEstimateModeErrorMessage();
bilingual_str PSBTErrorString(PSBTError error);
bilingual_str TransactionErrorString(const node::TransactionError error);
Expand Down
9 changes: 2 additions & 7 deletions src/rpc/fees.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include <string>

using common::FeeModeFromString;
using common::FeeModes;
using common::FeeModesDetail;
using common::InvalidEstimateModeErrorMessage;
using node::NodeContext;

Expand All @@ -37,12 +37,7 @@ static RPCHelpMan estimatesmartfee()
{
{"conf_target", RPCArg::Type::NUM, RPCArg::Optional::NO, "Confirmation target in blocks (1 - 1008)"},
{"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"economical"}, "The fee estimate mode.\n"
"Whether to return a more conservative estimate which also satisfies\n"
"a longer history. A conservative estimate potentially returns a\n"
"higher feerate and is more likely to be sufficient for the desired\n"
"target, but is not as responsive to short term drops in the\n"
"prevailing fee market. Must be one of (case insensitive):\n"
"\"" + FeeModes("\"\n\"") + "\""},
+ FeeModesDetail(std::string("default mode will be used"))},
},
RPCResult{
RPCResult::Type::OBJ, "", "",
Expand Down
14 changes: 7 additions & 7 deletions src/wallet/rpc/spend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include <univalue.h>

using common::FeeModeFromString;
using common::FeeModes;
using common::FeeModesDetail;
using common::InvalidEstimateModeErrorMessage;
using common::StringForFeeReason;
using common::TransactionErrorString;
Expand Down Expand Up @@ -245,7 +245,7 @@ RPCHelpMan sendtoaddress()
{"replaceable", RPCArg::Type::BOOL, RPCArg::DefaultHint{"wallet default"}, "Signal that this transaction can be replaced by a transaction (BIP 125)"},
{"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"},
{"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n"
"\"" + FeeModes("\"\n\"") + "\""},
+ FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))},
{"avoid_reuse", RPCArg::Type::BOOL, RPCArg::Default{true}, "(only available if avoid_reuse wallet flag is set) Avoid spending from dirty addresses; addresses are considered\n"
"dirty if they have previously been used in a transaction. If true, this also activates avoidpartialspends, grouping outputs by their addresses."},
{"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."},
Expand Down Expand Up @@ -349,7 +349,7 @@ RPCHelpMan sendmany()
{"replaceable", RPCArg::Type::BOOL, RPCArg::DefaultHint{"wallet default"}, "Signal that this transaction can be replaced by a transaction (BIP 125)"},
{"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"},
{"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n"
"\"" + FeeModes("\"\n\"") + "\""},
+ FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))},
{"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."},
{"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "If true, return extra information about the transaction."},
},
Expand Down Expand Up @@ -463,7 +463,7 @@ static std::vector<RPCArg> FundTxDoc(bool solving_data = true)
std::vector<RPCArg> args = {
{"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks", RPCArgOptions{.also_positional = true}},
{"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n"
"\"" + FeeModes("\"\n\"") + "\"", RPCArgOptions{.also_positional = true}},
+ FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used")), RPCArgOptions{.also_positional = true}},
{
"replaceable", RPCArg::Type::BOOL, RPCArg::DefaultHint{"wallet default"}, "Marks this transaction as BIP125-replaceable.\n"
"Allows this transaction to be replaced by a transaction with higher fees"
Expand Down Expand Up @@ -1018,7 +1018,7 @@ static RPCHelpMan bumpfee_helper(std::string method_name)
"still be replaceable in practice, for example if it has unconfirmed ancestors which\n"
"are replaceable).\n"},
{"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n"
"\"" + FeeModes("\"\n\"") + "\""},
+ FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))},
{"outputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The outputs specified as key-value pairs.\n"
"Each key may only appear once, i.e. there can only be one 'data' output, and no address may be duplicated.\n"
"At least one output of either type must be specified.\n"
Expand Down Expand Up @@ -1205,7 +1205,7 @@ RPCHelpMan send()
RPCArgOptions{.skip_type_check = true}},
{"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"},
{"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n"
"\"" + FeeModes("\"\n\"") + "\""},
+ FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))},
{"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."},
{"options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "",
Cat<std::vector<RPCArg>>(
Expand Down Expand Up @@ -1331,7 +1331,7 @@ RPCHelpMan sendall()
},
{"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"},
{"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n"
"\"" + FeeModes("\"\n\"") + "\""},
+ FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))},
{"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."},
{
"options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "",
Expand Down