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

backport: bitcoin#18275, #20220, #20305, #20410, #20426, #20573, #21083, #21201, #21786, #21787 (fee backports) #6245

Merged
merged 11 commits into from
Sep 25, 2024
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
5 changes: 4 additions & 1 deletion src/bench/coin_selection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ static void CoinSelection(benchmark::Bench& bench)
coins.emplace_back(wtx.get(), 0 /* iIn */, 6 * 24 /* nDepthIn */, true /* spendable */, true /* solvable */, true /* safe */);
}
const CoinEligibilityFilter filter_standard(1, 6, 0);
const CoinSelectionParams coin_selection_params(true, 34, 148, CFeeRate(0), 0, false);
const CoinSelectionParams coin_selection_params(/* use_bnb= */ true, /* change_output_size= */ 34,
/* change_spend_size= */ 148, /* effective_feerate= */ CFeeRate(0),
/* long_term_feerate= */ CFeeRate(0), /* discard_feerate= */ CFeeRate(0),
/* tx_no_inputs_size= */ 0, /* avoid_partial= */ false);
bench.run([&] {
std::set<CInputCoin> setCoinsRet;
CAmount nValueRet;
Expand Down
2 changes: 1 addition & 1 deletion src/coinjoin/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ CTransactionBuilder::CTransactionBuilder(std::shared_ptr<CWallet> pwalletIn, con
// Generate a feerate which will be used to consider if the remainder is dust and will go into fees or not
coinControl.m_discard_feerate = ::GetDiscardRate(*pwallet);
// Generate a feerate which will be used by calculations of this class and also by CWallet::CreateTransaction
coinControl.m_feerate = std::max(pwallet->chain().estimateSmartFee(int(pwallet->m_confirm_target), true, nullptr), pwallet->m_pay_tx_fee);
coinControl.m_feerate = std::max(GetRequiredFeeRate(*pwallet), pwallet->m_pay_tx_fee);
// Change always goes back to origin
coinControl.destChange = tallyItemIn.txdest;
// Only allow tallyItems inputs for tx creation
Expand Down
11 changes: 8 additions & 3 deletions src/policy/feerate.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ 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
DASH_KB, //!< Use explicit DASH/kB fee given in coin control
DUFF_B, //!< Use explicit duff/B fee given in coin control
DASH_KB, //!< Use DASH/kB fee rate unit
DUFF_B, //!< Use duff/B fee rate unit
};

/**
Expand All @@ -39,7 +39,12 @@ class CFeeRate
// We've previously had bugs creep in from silent double->int conversion...
static_assert(std::is_integral<I>::value, "CFeeRate should be used without floats");
}
/** Constructor for a fee rate in satoshis per kB. The size in bytes must not exceed (2^63 - 1)*/
/** Constructor for a fee rate in satoshis per kB (duff/kB).
*
* Passing a num_bytes value of COIN (1e8) returns a fee rate in satoshis per B (sat/B),
* e.g. (nFeePaid * 1e8 / 1e3) == (nFeePaid / 1e5),
* where 1e5 is the ratio to convert from DASH/kB to sat/B.
*/
CFeeRate(const CAmount& nFeePaid, uint32_t num_bytes);
/**
* Return the fee in satoshis for the given size in bytes.
Expand Down
9 changes: 6 additions & 3 deletions src/rpc/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "sendtoaddress", 6, "use_cj" },
{ "sendtoaddress", 7, "conf_target" },
{ "sendtoaddress", 9, "avoid_reuse" },
{ "sendtoaddress", 10, "verbose"},
{ "sendtoaddress", 10, "fee_rate"},
{ "sendtoaddress", 11, "verbose"},
{ "settxfee", 0, "amount" },
{ "sethdseed", 0, "newkeypool" },
{ "getreceivedbyaddress", 1, "minconf" },
Expand Down Expand Up @@ -91,7 +92,8 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "sendmany", 6, "use_is" },
{ "sendmany", 7, "use_cj" },
{ "sendmany", 8, "conf_target" },
{ "sendmany", 10, "verbose" },
{ "sendmany", 10, "fee_rate" },
{ "sendmany", 11, "verbose" },
{ "deriveaddresses", 1, "range" },
{ "scantxoutset", 1, "scanobjects" },
{ "addmultisigaddress", 0, "nrequired" },
Expand Down Expand Up @@ -152,7 +154,8 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "lockunspent", 1, "transactions" },
{ "send", 0, "outputs" },
{ "send", 1, "conf_target" },
{ "send", 3, "options" },
{ "send", 3, "fee_rate"},
{ "send", 4, "options" },
{ "importprivkey", 2, "rescan" },
{ "importelectrumwallet", 1, "index" },
{ "importaddress", 2, "rescan" },
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,7 @@ static RPCHelpMan estimatesmartfee()
if (!request.params[1].isNull()) {
FeeEstimateMode fee_mode;
if (!FeeModeFromString(request.params[1].get_str(), fee_mode)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
throw JSONRPCError(RPC_INVALID_PARAMETER, InvalidEstimateModeErrorMessage());
}
if (fee_mode == FeeEstimateMode::ECONOMICAL) conservative = false;
}
Expand Down
13 changes: 7 additions & 6 deletions src/rpc/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ void RPCTypeCheckObj(const UniValue& o,
}
}

CAmount AmountFromValue(const UniValue& value)
CAmount AmountFromValue(const UniValue& value, int decimals)
{
if (!value.isNum() && !value.isStr())
throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number or string");
CAmount amount;
if (!ParseFixedPoint(value.getValStr(), 8, &amount))
if (!ParseFixedPoint(value.getValStr(), decimals, &amount))
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
if (!MoneyRange(amount))
throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range");
Expand Down Expand Up @@ -319,11 +319,12 @@ UniValue DescribeAddress(const CTxDestination& dest)

unsigned int ParseConfirmTarget(const UniValue& value, unsigned int max_target)
{
int target = value.get_int();
if (target < 1 || (unsigned int)target > max_target) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid conf_target, must be between %u - %u", 1, max_target));
const int target{value.get_int()};
const unsigned int unsigned_target{static_cast<unsigned int>(target)};
if (target < 1 || unsigned_target > max_target) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid conf_target, must be between %u and %u", 1, max_target));
}
return (unsigned int)target;
return unsigned_target;
}

/**
Expand Down
9 changes: 8 additions & 1 deletion src/rpc/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,14 @@ int64_t ParseInt64V(const UniValue& v, const std::string &strName);
double ParseDoubleV(const UniValue& v, const std::string &strName);
bool ParseBoolV(const UniValue& v, const std::string &strName);

CAmount AmountFromValue(const UniValue& value);
/**
* Validate and return a CAmount from a UniValue number or string.
*
* @param[in] value UniValue number or string to parse.
* @param[in] decimals Number of significant digits (default: 8).
* @returns a CAmount if the various checks pass.
*/
CAmount AmountFromValue(const UniValue& value, int decimals = 8);

using RPCArgList = std::vector<std::pair<std::string, UniValue>>;
std::string HelpExampleCli(const std::string& methodname, const std::string& args);
Expand Down
2 changes: 2 additions & 0 deletions src/test/amount_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ BOOST_AUTO_TEST_CASE(ToStringTest)
CFeeRate feeRate;
feeRate = CFeeRate(1);
BOOST_CHECK_EQUAL(feeRate.ToString(), "0.00000001 DASH/kB");
BOOST_CHECK_EQUAL(feeRate.ToString(FeeEstimateMode::DASH_KB), "0.00000001 DASH/kB");
BOOST_CHECK_EQUAL(feeRate.ToString(FeeEstimateMode::DUFF_B), "0.001 duff/B");
}

BOOST_AUTO_TEST_SUITE_END()
9 changes: 9 additions & 0 deletions src/test/util_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2044,6 +2044,15 @@ BOOST_AUTO_TEST_CASE(test_ParseFixedPoint)
BOOST_CHECK(!ParseFixedPoint("1.1e", 8, &amount));
BOOST_CHECK(!ParseFixedPoint("1.1e-", 8, &amount));
BOOST_CHECK(!ParseFixedPoint("1.", 8, &amount));

// Test with 3 decimal places for fee rates in sat/vB.
BOOST_CHECK(ParseFixedPoint("0.001", 3, &amount));
BOOST_CHECK_EQUAL(amount, CAmount{1});
BOOST_CHECK(!ParseFixedPoint("0.0009", 3, &amount));
BOOST_CHECK(!ParseFixedPoint("31.00100001", 3, &amount));
BOOST_CHECK(!ParseFixedPoint("31.0011", 3, &amount));
BOOST_CHECK(!ParseFixedPoint("31.99999999", 3, &amount));
BOOST_CHECK(!ParseFixedPoint("31.999999999999999999999", 3, &amount));
}

static void TestOtherThread(fs::path dirname, std::string lockname, bool *result)
Expand Down
7 changes: 5 additions & 2 deletions src/util/fees.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ const std::vector<std::pair<std::string, FeeEstimateMode>>& FeeModeMap()
{"unset", FeeEstimateMode::UNSET},
{"economical", FeeEstimateMode::ECONOMICAL},
{"conservative", FeeEstimateMode::CONSERVATIVE},
{(CURRENCY_UNIT + "/kB"), FeeEstimateMode::DASH_KB},
{(CURRENCY_ATOM + "/B"), FeeEstimateMode::DUFF_B},
};
return FEE_MODES;
}
Expand All @@ -51,6 +49,11 @@ std::string FeeModes(const std::string& delimiter)
return Join(FeeModeMap(), delimiter, [&](const std::pair<std::string, FeeEstimateMode>& i) { return i.first; });
}

const std::string InvalidEstimateModeErrorMessage()
{
return "Invalid estimate_mode parameter, must be one of: \"" + FeeModes("\", \"") + "\"";
}

bool FeeModeFromString(const std::string& mode_string, FeeEstimateMode& fee_estimate_mode)
{
auto searchkey = ToUpper(mode_string);
Expand Down
1 change: 1 addition & 0 deletions src/util/fees.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,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);
const std::string InvalidEstimateModeErrorMessage();

#endif // BITCOIN_UTIL_FEES_H
Loading
Loading