From 8ce3ef57a3e9ad13c0aaa4648e8584241d53592d Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Tue, 27 Apr 2021 11:00:20 +0200 Subject: test: ParseFixedPoint with 3 decimals for sat/vB fee rates --- src/test/util_tests.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 04b908829b..534d28e5de 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1759,6 +1759,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) -- cgit v1.2.3 From 0742c7840f03505597fd2de87db97f12597ef667 Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Tue, 27 Apr 2021 10:54:44 +0200 Subject: rpc: enable passing decimals to AmountFromValue, add doxygen --- src/rpc/util.cpp | 4 ++-- src/rpc/util.h | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp index 069669bb3b..7cf25e0c82 100644 --- a/src/rpc/util.cpp +++ b/src/rpc/util.cpp @@ -74,12 +74,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"); diff --git a/src/rpc/util.h b/src/rpc/util.h index 8ec18b2f35..41cbcc6032 100644 --- a/src/rpc/util.h +++ b/src/rpc/util.h @@ -77,7 +77,14 @@ extern uint256 ParseHashO(const UniValue& o, std::string strKey); extern std::vector ParseHexV(const UniValue& v, std::string strName); extern std::vector ParseHexO(const UniValue& o, std::string strKey); -extern 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. + */ +extern CAmount AmountFromValue(const UniValue& value, int decimals = 8); using RPCArgList = std::vector>; extern std::string HelpExampleCli(const std::string& methodname, const std::string& args); -- cgit v1.2.3 From 06a90fa0381c790f7bde2ab9bf47d2b22acef4a5 Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Tue, 27 Apr 2021 11:04:10 +0200 Subject: rpc: for sat/vB fee rates, limit ParseFixedPoint decimals to 3 --- src/wallet/rpcwallet.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 67d9d56133..31b90374bd 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -216,7 +216,8 @@ static void SetFeeEstimateMode(const CWallet& wallet, CCoinControl& cc, const Un if (!estimate_mode.isNull() && estimate_mode.get_str() != "unset") { throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both estimate_mode and fee_rate"); } - cc.m_feerate = CFeeRate(AmountFromValue(fee_rate), COIN); + // Fee rates in sat/vB cannot represent more than 3 significant digits. + cc.m_feerate = CFeeRate{AmountFromValue(fee_rate, /* decimals */ 3)}; if (override_min_fee) cc.fOverrideFeeRate = true; // Default RBF to true for explicit fee_rate, if unset. if (!cc.m_signal_bip125_rbf) cc.m_signal_bip125_rbf = true; -- cgit v1.2.3