mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-09 10:43:19 -05:00
Merge bitcoin/bitcoin#22220: util: make ParseMoney return a std::optional<CAmount>
f7752adba5
util: check MoneyRange() inside ParseMoney() (fanquake)5ef2738089
util: make ParseMoney return a std::optional<CAmount> (fanquake) Pull request description: Related discussion in #22193. ACKs for top commit: MarcoFalke: review ACKf7752adba5
📄 Tree-SHA512: 88453f9e28f668deff4290d4bc0b2468cbd54699a3be1bfeac63a512276d309354672e7ea7deefa01466c3d9d826e837cc1ea244d4d74b4fa9c11c56f074e098
This commit is contained in:
commit
61a843e43b
9 changed files with 123 additions and 140 deletions
|
@ -188,10 +188,11 @@ static void RegisterLoad(const std::string& strInput)
|
|||
|
||||
static CAmount ExtractAndValidateValue(const std::string& strValue)
|
||||
{
|
||||
CAmount value;
|
||||
if (!ParseMoney(strValue, value))
|
||||
if (std::optional<CAmount> parsed = ParseMoney(strValue)) {
|
||||
return parsed.value();
|
||||
} else {
|
||||
throw std::runtime_error("invalid TX output value");
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
static void MutateTxVersion(CMutableTransaction& tx, const std::string& cmdVal)
|
||||
|
|
26
src/init.cpp
26
src/init.cpp
|
@ -921,10 +921,11 @@ bool AppInitParameterInteraction(const ArgsManager& args)
|
|||
// incremental relay fee sets the minimum feerate increase necessary for BIP 125 replacement in the mempool
|
||||
// and the amount the mempool min fee increases above the feerate of txs evicted due to mempool limiting.
|
||||
if (args.IsArgSet("-incrementalrelayfee")) {
|
||||
CAmount n = 0;
|
||||
if (!ParseMoney(args.GetArg("-incrementalrelayfee", ""), n))
|
||||
if (std::optional<CAmount> inc_relay_fee = ParseMoney(args.GetArg("-incrementalrelayfee", ""))) {
|
||||
::incrementalRelayFee = CFeeRate{inc_relay_fee.value()};
|
||||
} else {
|
||||
return InitError(AmountErrMsg("incrementalrelayfee", args.GetArg("-incrementalrelayfee", "")));
|
||||
incrementalRelayFee = CFeeRate(n);
|
||||
}
|
||||
}
|
||||
|
||||
// block pruning; get the amount of disk space (in MiB) to allot for block & undo files
|
||||
|
@ -956,12 +957,12 @@ bool AppInitParameterInteraction(const ArgsManager& args)
|
|||
}
|
||||
|
||||
if (args.IsArgSet("-minrelaytxfee")) {
|
||||
CAmount n = 0;
|
||||
if (!ParseMoney(args.GetArg("-minrelaytxfee", ""), n)) {
|
||||
if (std::optional<CAmount> min_relay_fee = ParseMoney(args.GetArg("-minrelaytxfee", ""))) {
|
||||
// High fee check is done afterward in CWallet::Create()
|
||||
::minRelayTxFee = CFeeRate{min_relay_fee.value()};
|
||||
} else {
|
||||
return InitError(AmountErrMsg("minrelaytxfee", args.GetArg("-minrelaytxfee", "")));
|
||||
}
|
||||
// High fee check is done afterward in CWallet::Create()
|
||||
::minRelayTxFee = CFeeRate(n);
|
||||
} else if (incrementalRelayFee > ::minRelayTxFee) {
|
||||
// Allow only setting incrementalRelayFee to control both
|
||||
::minRelayTxFee = incrementalRelayFee;
|
||||
|
@ -971,18 +972,19 @@ bool AppInitParameterInteraction(const ArgsManager& args)
|
|||
// Sanity check argument for min fee for including tx in block
|
||||
// TODO: Harmonize which arguments need sanity checking and where that happens
|
||||
if (args.IsArgSet("-blockmintxfee")) {
|
||||
CAmount n = 0;
|
||||
if (!ParseMoney(args.GetArg("-blockmintxfee", ""), n))
|
||||
if (!ParseMoney(args.GetArg("-blockmintxfee", ""))) {
|
||||
return InitError(AmountErrMsg("blockmintxfee", args.GetArg("-blockmintxfee", "")));
|
||||
}
|
||||
}
|
||||
|
||||
// Feerate used to define dust. Shouldn't be changed lightly as old
|
||||
// implementations may inadvertently create non-standard transactions
|
||||
if (args.IsArgSet("-dustrelayfee")) {
|
||||
CAmount n = 0;
|
||||
if (!ParseMoney(args.GetArg("-dustrelayfee", ""), n))
|
||||
if (std::optional<CAmount> parsed = ParseMoney(args.GetArg("-dustrelayfee", ""))) {
|
||||
dustRelayFee = CFeeRate{parsed.value()};
|
||||
} else {
|
||||
return InitError(AmountErrMsg("dustrelayfee", args.GetArg("-dustrelayfee", "")));
|
||||
dustRelayFee = CFeeRate(n);
|
||||
}
|
||||
}
|
||||
|
||||
fRequireStandard = !args.GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard());
|
||||
|
|
|
@ -73,11 +73,11 @@ static BlockAssembler::Options DefaultOptions()
|
|||
// If -blockmaxweight is not given, limit to DEFAULT_BLOCK_MAX_WEIGHT
|
||||
BlockAssembler::Options options;
|
||||
options.nBlockMaxWeight = gArgs.GetArg("-blockmaxweight", DEFAULT_BLOCK_MAX_WEIGHT);
|
||||
CAmount n = 0;
|
||||
if (gArgs.IsArgSet("-blockmintxfee") && ParseMoney(gArgs.GetArg("-blockmintxfee", ""), n)) {
|
||||
options.blockMinFeeRate = CFeeRate(n);
|
||||
if (gArgs.IsArgSet("-blockmintxfee")) {
|
||||
std::optional<CAmount> parsed = ParseMoney(gArgs.GetArg("-blockmintxfee", ""));
|
||||
options.blockMinFeeRate = CFeeRate{parsed.value_or(DEFAULT_BLOCK_MIN_TX_FEE)};
|
||||
} else {
|
||||
options.blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE);
|
||||
options.blockMinFeeRate = CFeeRate{DEFAULT_BLOCK_MIN_TX_FEE};
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
|
|
@ -83,9 +83,8 @@ FUZZ_TARGET_INIT(integer, initialize_integer)
|
|||
(void)FormatISO8601Date(i64);
|
||||
(void)FormatISO8601DateTime(i64);
|
||||
{
|
||||
int64_t parsed_money;
|
||||
if (ParseMoney(FormatMoney(i64), parsed_money)) {
|
||||
assert(parsed_money == i64);
|
||||
if (std::optional<CAmount> parsed = ParseMoney(FormatMoney(i64))) {
|
||||
assert(parsed.value() == i64);
|
||||
}
|
||||
}
|
||||
(void)GetSizeOfCompactSize(u64);
|
||||
|
@ -126,9 +125,8 @@ FUZZ_TARGET_INIT(integer, initialize_integer)
|
|||
(void)ToLower(ch);
|
||||
(void)ToUpper(ch);
|
||||
{
|
||||
int64_t parsed_money;
|
||||
if (ParseMoney(ValueFromAmount(i64).getValStr(), parsed_money)) {
|
||||
assert(parsed_money == i64);
|
||||
if (std::optional<CAmount> parsed = ParseMoney(ValueFromAmount(i64).getValStr())) {
|
||||
assert(parsed.value() == i64);
|
||||
}
|
||||
}
|
||||
if (i32 >= 0 && i32 <= 16) {
|
||||
|
|
|
@ -12,8 +12,7 @@ FUZZ_TARGET(parse_numbers)
|
|||
{
|
||||
const std::string random_string(buffer.begin(), buffer.end());
|
||||
|
||||
CAmount amount;
|
||||
(void)ParseMoney(random_string, amount);
|
||||
(void)ParseMoney(random_string);
|
||||
|
||||
double d;
|
||||
(void)ParseDouble(random_string, &d);
|
||||
|
|
|
@ -1222,86 +1222,59 @@ BOOST_AUTO_TEST_CASE(util_FormatMoney)
|
|||
|
||||
BOOST_AUTO_TEST_CASE(util_ParseMoney)
|
||||
{
|
||||
CAmount ret = 0;
|
||||
BOOST_CHECK(ParseMoney("0.0", ret));
|
||||
BOOST_CHECK_EQUAL(ret, 0);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("0.0").value(), 0);
|
||||
|
||||
BOOST_CHECK(ParseMoney("12345.6789", ret));
|
||||
BOOST_CHECK_EQUAL(ret, (COIN/10000)*123456789);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("12345.6789").value(), (COIN/10000)*123456789);
|
||||
|
||||
BOOST_CHECK(ParseMoney("100000000.00", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN*100000000);
|
||||
BOOST_CHECK(ParseMoney("10000000.00", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN*10000000);
|
||||
BOOST_CHECK(ParseMoney("1000000.00", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN*1000000);
|
||||
BOOST_CHECK(ParseMoney("100000.00", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN*100000);
|
||||
BOOST_CHECK(ParseMoney("10000.00", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN*10000);
|
||||
BOOST_CHECK(ParseMoney("1000.00", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN*1000);
|
||||
BOOST_CHECK(ParseMoney("100.00", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN*100);
|
||||
BOOST_CHECK(ParseMoney("10.00", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN*10);
|
||||
BOOST_CHECK(ParseMoney("1.00", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN);
|
||||
BOOST_CHECK(ParseMoney("1", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN);
|
||||
BOOST_CHECK(ParseMoney(" 1", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN);
|
||||
BOOST_CHECK(ParseMoney("1 ", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN);
|
||||
BOOST_CHECK(ParseMoney(" 1 ", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN);
|
||||
BOOST_CHECK(ParseMoney("0.1", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN/10);
|
||||
BOOST_CHECK(ParseMoney("0.01", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN/100);
|
||||
BOOST_CHECK(ParseMoney("0.001", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN/1000);
|
||||
BOOST_CHECK(ParseMoney("0.0001", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN/10000);
|
||||
BOOST_CHECK(ParseMoney("0.00001", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN/100000);
|
||||
BOOST_CHECK(ParseMoney("0.000001", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN/1000000);
|
||||
BOOST_CHECK(ParseMoney("0.0000001", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN/10000000);
|
||||
BOOST_CHECK(ParseMoney("0.00000001", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN/100000000);
|
||||
BOOST_CHECK(ParseMoney(" 0.00000001 ", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN/100000000);
|
||||
BOOST_CHECK(ParseMoney("0.00000001 ", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN/100000000);
|
||||
BOOST_CHECK(ParseMoney(" 0.00000001", ret));
|
||||
BOOST_CHECK_EQUAL(ret, COIN/100000000);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("10000000.00").value(), COIN*10000000);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("1000000.00").value(), COIN*1000000);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("100000.00").value(), COIN*100000);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("10000.00").value(), COIN*10000);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("1000.00").value(), COIN*1000);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("100.00").value(), COIN*100);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("10.00").value(), COIN*10);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("1.00").value(), COIN);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("1").value(), COIN);
|
||||
BOOST_CHECK_EQUAL(ParseMoney(" 1").value(), COIN);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("1 ").value(), COIN);
|
||||
BOOST_CHECK_EQUAL(ParseMoney(" 1 ").value(), COIN);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("0.1").value(), COIN/10);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("0.01").value(), COIN/100);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("0.001").value(), COIN/1000);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("0.0001").value(), COIN/10000);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("0.00001").value(), COIN/100000);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("0.000001").value(), COIN/1000000);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("0.0000001").value(), COIN/10000000);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("0.00000001").value(), COIN/100000000);
|
||||
BOOST_CHECK_EQUAL(ParseMoney(" 0.00000001 ").value(), COIN/100000000);
|
||||
BOOST_CHECK_EQUAL(ParseMoney("0.00000001 ").value(), COIN/100000000);
|
||||
BOOST_CHECK_EQUAL(ParseMoney(" 0.00000001").value(), COIN/100000000);
|
||||
|
||||
// Parsing amount that can not be represented in ret should fail
|
||||
BOOST_CHECK(!ParseMoney("0.000000001", ret));
|
||||
// Parsing amount that can not be represented should fail
|
||||
BOOST_CHECK(!ParseMoney("100000000.00"));
|
||||
BOOST_CHECK(!ParseMoney("0.000000001"));
|
||||
|
||||
// Parsing empty string should fail
|
||||
BOOST_CHECK(!ParseMoney("", ret));
|
||||
BOOST_CHECK(!ParseMoney(" ", ret));
|
||||
BOOST_CHECK(!ParseMoney(" ", ret));
|
||||
BOOST_CHECK(!ParseMoney(""));
|
||||
BOOST_CHECK(!ParseMoney(" "));
|
||||
BOOST_CHECK(!ParseMoney(" "));
|
||||
|
||||
// Parsing two numbers should fail
|
||||
BOOST_CHECK(!ParseMoney("1 2", ret));
|
||||
BOOST_CHECK(!ParseMoney(" 1 2 ", ret));
|
||||
BOOST_CHECK(!ParseMoney(" 1.2 3 ", ret));
|
||||
BOOST_CHECK(!ParseMoney(" 1 2.3 ", ret));
|
||||
BOOST_CHECK(!ParseMoney("1 2"));
|
||||
BOOST_CHECK(!ParseMoney(" 1 2 "));
|
||||
BOOST_CHECK(!ParseMoney(" 1.2 3 "));
|
||||
BOOST_CHECK(!ParseMoney(" 1 2.3 "));
|
||||
|
||||
// Attempted 63 bit overflow should fail
|
||||
BOOST_CHECK(!ParseMoney("92233720368.54775808", ret));
|
||||
BOOST_CHECK(!ParseMoney("92233720368.54775808"));
|
||||
|
||||
// Parsing negative amounts must fail
|
||||
BOOST_CHECK(!ParseMoney("-1", ret));
|
||||
BOOST_CHECK(!ParseMoney("-1"));
|
||||
|
||||
// Parsing strings with embedded NUL characters should fail
|
||||
BOOST_CHECK(!ParseMoney("\0-1"s, ret));
|
||||
BOOST_CHECK(!ParseMoney(STRING_WITH_EMBEDDED_NULL_CHAR, ret));
|
||||
BOOST_CHECK(!ParseMoney("1\0"s, ret));
|
||||
BOOST_CHECK(!ParseMoney("\0-1"s));
|
||||
BOOST_CHECK(!ParseMoney(STRING_WITH_EMBEDDED_NULL_CHAR));
|
||||
BOOST_CHECK(!ParseMoney("1\0"s));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(util_IsHex)
|
||||
|
|
|
@ -5,10 +5,13 @@
|
|||
|
||||
#include <util/moneystr.h>
|
||||
|
||||
#include <amount.h>
|
||||
#include <tinyformat.h>
|
||||
#include <util/strencodings.h>
|
||||
#include <util/string.h>
|
||||
|
||||
#include <optional>
|
||||
|
||||
std::string FormatMoney(const CAmount n)
|
||||
{
|
||||
// Note: not using straight sprintf here because we do NOT want
|
||||
|
@ -35,14 +38,14 @@ std::string FormatMoney(const CAmount n)
|
|||
}
|
||||
|
||||
|
||||
bool ParseMoney(const std::string& money_string, CAmount& nRet)
|
||||
std::optional<CAmount> ParseMoney(const std::string& money_string)
|
||||
{
|
||||
if (!ValidAsCString(money_string)) {
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
const std::string str = TrimString(money_string);
|
||||
if (str.empty()) {
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::string strWhole;
|
||||
|
@ -62,21 +65,25 @@ bool ParseMoney(const std::string& money_string, CAmount& nRet)
|
|||
break;
|
||||
}
|
||||
if (IsSpace(*p))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
if (!IsDigit(*p))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
strWhole.insert(strWhole.end(), *p);
|
||||
}
|
||||
if (*p) {
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
if (strWhole.size() > 10) // guard against 63 bit overflow
|
||||
return false;
|
||||
return std::nullopt;
|
||||
if (nUnits < 0 || nUnits > COIN)
|
||||
return false;
|
||||
return std::nullopt;
|
||||
int64_t nWhole = atoi64(strWhole);
|
||||
CAmount nValue = nWhole*COIN + nUnits;
|
||||
|
||||
nRet = nValue;
|
||||
return true;
|
||||
CAmount value = nWhole * COIN + nUnits;
|
||||
|
||||
if (!MoneyRange(value)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <amount.h>
|
||||
#include <attributes.h>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
/* Do not use these functions to represent or parse monetary amounts to or from
|
||||
|
@ -19,6 +20,6 @@
|
|||
*/
|
||||
std::string FormatMoney(const CAmount n);
|
||||
/** Parse an amount denoted in full coins. E.g. "0.0034" supplied on the command line. **/
|
||||
[[nodiscard]] bool ParseMoney(const std::string& str, CAmount& nRet);
|
||||
std::optional<CAmount> ParseMoney(const std::string& str);
|
||||
|
||||
#endif // BITCOIN_UTIL_MONEYSTR_H
|
||||
|
|
|
@ -2609,72 +2609,73 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
|
|||
}
|
||||
|
||||
if (gArgs.IsArgSet("-mintxfee")) {
|
||||
CAmount n = 0;
|
||||
if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n) {
|
||||
std::optional<CAmount> min_tx_fee = ParseMoney(gArgs.GetArg("-mintxfee", ""));
|
||||
if (!min_tx_fee || min_tx_fee.value() == 0) {
|
||||
error = AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", ""));
|
||||
return nullptr;
|
||||
}
|
||||
if (n > HIGH_TX_FEE_PER_KB) {
|
||||
} else if (min_tx_fee.value() > HIGH_TX_FEE_PER_KB) {
|
||||
warnings.push_back(AmountHighWarn("-mintxfee") + Untranslated(" ") +
|
||||
_("This is the minimum transaction fee you pay on every transaction."));
|
||||
}
|
||||
walletInstance->m_min_fee = CFeeRate(n);
|
||||
|
||||
walletInstance->m_min_fee = CFeeRate{min_tx_fee.value()};
|
||||
}
|
||||
|
||||
if (gArgs.IsArgSet("-maxapsfee")) {
|
||||
const std::string max_aps_fee{gArgs.GetArg("-maxapsfee", "")};
|
||||
CAmount n = 0;
|
||||
if (max_aps_fee == "-1") {
|
||||
n = -1;
|
||||
} else if (!ParseMoney(max_aps_fee, n)) {
|
||||
walletInstance->m_max_aps_fee = -1;
|
||||
} else if (std::optional<CAmount> max_fee = ParseMoney(max_aps_fee)) {
|
||||
if (max_fee.value() > HIGH_APS_FEE) {
|
||||
warnings.push_back(AmountHighWarn("-maxapsfee") + Untranslated(" ") +
|
||||
_("This is the maximum transaction fee you pay (in addition to the normal fee) to prioritize partial spend avoidance over regular coin selection."));
|
||||
}
|
||||
walletInstance->m_max_aps_fee = max_fee.value();
|
||||
} else {
|
||||
error = AmountErrMsg("maxapsfee", max_aps_fee);
|
||||
return nullptr;
|
||||
}
|
||||
if (n > HIGH_APS_FEE) {
|
||||
warnings.push_back(AmountHighWarn("-maxapsfee") + Untranslated(" ") +
|
||||
_("This is the maximum transaction fee you pay (in addition to the normal fee) to prioritize partial spend avoidance over regular coin selection."));
|
||||
}
|
||||
walletInstance->m_max_aps_fee = n;
|
||||
}
|
||||
|
||||
if (gArgs.IsArgSet("-fallbackfee")) {
|
||||
CAmount nFeePerK = 0;
|
||||
if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK)) {
|
||||
std::optional<CAmount> fallback_fee = ParseMoney(gArgs.GetArg("-fallbackfee", ""));
|
||||
if (!fallback_fee) {
|
||||
error = strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), gArgs.GetArg("-fallbackfee", ""));
|
||||
return nullptr;
|
||||
}
|
||||
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
|
||||
} else if (fallback_fee.value() > HIGH_TX_FEE_PER_KB) {
|
||||
warnings.push_back(AmountHighWarn("-fallbackfee") + Untranslated(" ") +
|
||||
_("This is the transaction fee you may pay when fee estimates are not available."));
|
||||
}
|
||||
walletInstance->m_fallback_fee = CFeeRate(nFeePerK);
|
||||
walletInstance->m_fallback_fee = CFeeRate{fallback_fee.value()};
|
||||
}
|
||||
|
||||
// Disable fallback fee in case value was set to 0, enable if non-null value
|
||||
walletInstance->m_allow_fallback_fee = walletInstance->m_fallback_fee.GetFeePerK() != 0;
|
||||
|
||||
if (gArgs.IsArgSet("-discardfee")) {
|
||||
CAmount nFeePerK = 0;
|
||||
if (!ParseMoney(gArgs.GetArg("-discardfee", ""), nFeePerK)) {
|
||||
std::optional<CAmount> discard_fee = ParseMoney(gArgs.GetArg("-discardfee", ""));
|
||||
if (!discard_fee) {
|
||||
error = strprintf(_("Invalid amount for -discardfee=<amount>: '%s'"), gArgs.GetArg("-discardfee", ""));
|
||||
return nullptr;
|
||||
}
|
||||
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
|
||||
} else if (discard_fee.value() > HIGH_TX_FEE_PER_KB) {
|
||||
warnings.push_back(AmountHighWarn("-discardfee") + Untranslated(" ") +
|
||||
_("This is the transaction fee you may discard if change is smaller than dust at this level"));
|
||||
}
|
||||
walletInstance->m_discard_rate = CFeeRate(nFeePerK);
|
||||
walletInstance->m_discard_rate = CFeeRate{discard_fee.value()};
|
||||
}
|
||||
|
||||
if (gArgs.IsArgSet("-paytxfee")) {
|
||||
CAmount nFeePerK = 0;
|
||||
if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK)) {
|
||||
std::optional<CAmount> pay_tx_fee = ParseMoney(gArgs.GetArg("-paytxfee", ""));
|
||||
if (!pay_tx_fee) {
|
||||
error = AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", ""));
|
||||
return nullptr;
|
||||
}
|
||||
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
|
||||
} else if (pay_tx_fee.value() > HIGH_TX_FEE_PER_KB) {
|
||||
warnings.push_back(AmountHighWarn("-paytxfee") + Untranslated(" ") +
|
||||
_("This is the transaction fee you will pay if you send a transaction."));
|
||||
}
|
||||
walletInstance->m_pay_tx_fee = CFeeRate(nFeePerK, 1000);
|
||||
|
||||
walletInstance->m_pay_tx_fee = CFeeRate{pay_tx_fee.value(), 1000};
|
||||
|
||||
if (chain && walletInstance->m_pay_tx_fee < chain->relayMinFee()) {
|
||||
error = strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
|
||||
gArgs.GetArg("-paytxfee", ""), chain->relayMinFee().ToString());
|
||||
|
@ -2683,20 +2684,21 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
|
|||
}
|
||||
|
||||
if (gArgs.IsArgSet("-maxtxfee")) {
|
||||
CAmount nMaxFee = 0;
|
||||
if (!ParseMoney(gArgs.GetArg("-maxtxfee", ""), nMaxFee)) {
|
||||
std::optional<CAmount> max_fee = ParseMoney(gArgs.GetArg("-maxtxfee", ""));
|
||||
if (!max_fee) {
|
||||
error = AmountErrMsg("maxtxfee", gArgs.GetArg("-maxtxfee", ""));
|
||||
return nullptr;
|
||||
}
|
||||
if (nMaxFee > HIGH_MAX_TX_FEE) {
|
||||
} else if (max_fee.value() > HIGH_MAX_TX_FEE) {
|
||||
warnings.push_back(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction."));
|
||||
}
|
||||
if (chain && CFeeRate(nMaxFee, 1000) < chain->relayMinFee()) {
|
||||
|
||||
if (chain && CFeeRate{max_fee.value(), 1000} < chain->relayMinFee()) {
|
||||
error = strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
|
||||
gArgs.GetArg("-maxtxfee", ""), chain->relayMinFee().ToString());
|
||||
return nullptr;
|
||||
}
|
||||
walletInstance->m_default_max_tx_fee = nMaxFee;
|
||||
|
||||
walletInstance->m_default_max_tx_fee = max_fee.value();
|
||||
}
|
||||
|
||||
if (chain && chain->relayMinFee().GetFeePerK() > HIGH_TX_FEE_PER_KB) {
|
||||
|
|
Loading…
Add table
Reference in a new issue