Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wallet] [rpc] sendtoaddress/sendmany: Add explicit feerate option #11413

Merged
merged 8 commits into from Jun 25, 2020
11 changes: 11 additions & 0 deletions doc/release-notes-11413.md
@@ -0,0 +1,11 @@
Updated or changed RPC
----------------------

The `bumpfee`, `fundrawtransaction`, `sendmany`, `sendtoaddress`, and `walletcreatefundedpsbt`
Copy link
Member

Choose a reason for hiding this comment

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

Note that this will also trigger bip125 opt-in.

Copy link
Member Author

@kallewoof kallewoof Mar 2, 2020

Choose a reason for hiding this comment

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

Added note.

RPC commands have been updated to include two new fee estimation methods "BTC/kB" and "sat/B".
Copy link
Contributor

Choose a reason for hiding this comment

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

5ee0e46 nit: missing comma after "methods"

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it's okay as it is. The methods a and b were added.

The target is the fee expressed explicitly in the given form. Note that use of this feature
will trigger BIP 125 (replace-by-fee) opt-in.

In addition, the `estimate_mode` parameter is now case insensitive for all of the above RPC commands.

The `bumpfee` command now uses `conf_target` rather than `confTarget` in the options.
kallewoof marked this conversation as resolved.
Show resolved Hide resolved
9 changes: 5 additions & 4 deletions src/policy/feerate.cpp
Expand Up @@ -7,8 +7,6 @@

#include <tinyformat.h>

const std::string CURRENCY_UNIT = "BTC";

CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nBytes_)
{
assert(nBytes_ <= uint64_t(std::numeric_limits<int64_t>::max()));
Expand Down Expand Up @@ -37,7 +35,10 @@ CAmount CFeeRate::GetFee(size_t nBytes_) const
return nFee;
}

std::string CFeeRate::ToString() const
std::string CFeeRate::ToString(const FeeEstimateMode& fee_estimate_mode) const
{
return strprintf("%d.%08d %s/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN, CURRENCY_UNIT);
switch (fee_estimate_mode) {
case FeeEstimateMode::SAT_B: return strprintf("%d.%03d %s/B", nSatoshisPerK / 1000, nSatoshisPerK % 1000, CURRENCY_ATOM);
default: return strprintf("%d.%08d %s/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN, CURRENCY_UNIT);
}
}
14 changes: 12 additions & 2 deletions src/policy/feerate.h
Expand Up @@ -11,7 +11,17 @@

#include <string>

extern const std::string CURRENCY_UNIT;
const std::string CURRENCY_UNIT = "BTC"; // One formatted unit
const std::string CURRENCY_ATOM = "sat"; // One indivisible minimum value unit

/* Used to determine type of fee estimation requested */
enum class FeeEstimateMode {
UNSET, //!< Use default settings based on other criteria
ECONOMICAL, //!< Force estimateSmartFee to use non-conservative estimates
CONSERVATIVE, //!< Force estimateSmartFee to use conservative estimates
BTC_KB, //!< Use explicit BTC/kB fee given in coin control
SAT_B, //!< Use explicit sat/B fee given in coin control
};

/**
* Fee rate in satoshis per kilobyte: CAmount / kB
Expand Down Expand Up @@ -46,7 +56,7 @@ class CFeeRate
friend bool operator>=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK >= b.nSatoshisPerK; }
friend bool operator!=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK != b.nSatoshisPerK; }
CFeeRate& operator+=(const CFeeRate& a) { nSatoshisPerK += a.nSatoshisPerK; return *this; }
std::string ToString() const;
std::string ToString(const FeeEstimateMode& fee_estimate_mode = FeeEstimateMode::BTC_KB) const;

SERIALIZE_METHODS(CFeeRate, obj) { READWRITE(obj.nSatoshisPerK); }
};
Expand Down
7 changes: 0 additions & 7 deletions src/policy/fees.h
Expand Up @@ -45,13 +45,6 @@ enum class FeeReason {
REQUIRED,
};

/* Used to determine type of fee estimation requested */
enum class FeeEstimateMode {
UNSET, //!< Use default settings based on other criteria
ECONOMICAL, //!< Force estimateSmartFee to use non-conservative estimates
CONSERVATIVE, //!< Force estimateSmartFee to use conservative estimates
};

/* Used to return detailed information about a feerate bucket */
struct EstimatorBucket
{
Expand Down
40 changes: 30 additions & 10 deletions src/util/fees.cpp
Expand Up @@ -6,11 +6,16 @@
#include <util/fees.h>

#include <policy/fees.h>
#include <util/strencodings.h>
#include <util/string.h>

#include <map>
#include <string>
#include <vector>
#include <utility>

std::string StringForFeeReason(FeeReason reason) {
std::string StringForFeeReason(FeeReason reason)
{
static const std::map<FeeReason, std::string> fee_reason_strings = {
{FeeReason::NONE, "None"},
{FeeReason::HALF_ESTIMATE, "Half Target 60% Threshold"},
Expand All @@ -29,16 +34,31 @@ std::string StringForFeeReason(FeeReason reason) {
return reason_string->second;
}

bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode) {
static const std::map<std::string, FeeEstimateMode> fee_modes = {
{"UNSET", FeeEstimateMode::UNSET},
{"ECONOMICAL", FeeEstimateMode::ECONOMICAL},
{"CONSERVATIVE", FeeEstimateMode::CONSERVATIVE},
const std::vector<std::pair<std::string, FeeEstimateMode>>& FeeModeMap()
{
static const std::vector<std::pair<std::string, FeeEstimateMode>> FEE_MODES = {
{"unset", FeeEstimateMode::UNSET},
{"economical", FeeEstimateMode::ECONOMICAL},
{"conservative", FeeEstimateMode::CONSERVATIVE},
{(CURRENCY_UNIT + "/kB"), FeeEstimateMode::BTC_KB},
{(CURRENCY_ATOM + "/B"), FeeEstimateMode::SAT_B},
};
auto mode = fee_modes.find(mode_string);
return FEE_MODES;
}

if (mode == fee_modes.end()) return false;
std::string FeeModes(const std::string& delimiter)
Copy link
Contributor

Choose a reason for hiding this comment

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

0ebb85b perhaps add "\"\n\"" as a default value for delimiter

Copy link
Member Author

Choose a reason for hiding this comment

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

Seems like an odd default, tbh, even though it would reduce code elsewhere.

{
return Join(FeeModeMap(), delimiter, [&](const std::pair<std::string, FeeEstimateMode>& i) { return i.first; });
}

fee_estimate_mode = mode->second;
return true;
bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode)
{
auto searchkey = ToUpper(mode_string);
for (const auto& pair : FeeModeMap()) {
if (ToUpper(pair.first) == searchkey) {
fee_estimate_mode = pair.second;
return true;
}
}
return false;
}
1 change: 1 addition & 0 deletions src/util/fees.h
Expand Up @@ -12,5 +12,6 @@ enum class FeeReason;

bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode);
std::string StringForFeeReason(FeeReason reason);
std::string FeeModes(const std::string& delimiter);

#endif // BITCOIN_UTIL_FEES_H