mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -04:00
wallet: update fee rate units, use sat/vB for fee_rate error messages
and BTC/kvB for feeRate error messages.
This commit is contained in:
parent
7f9835a05a
commit
173b5b5fe0
9 changed files with 22 additions and 21 deletions
|
@ -38,7 +38,7 @@ CAmount CFeeRate::GetFee(size_t nBytes_) const
|
||||||
std::string CFeeRate::ToString(const FeeEstimateMode& fee_estimate_mode) const
|
std::string CFeeRate::ToString(const FeeEstimateMode& fee_estimate_mode) const
|
||||||
{
|
{
|
||||||
switch (fee_estimate_mode) {
|
switch (fee_estimate_mode) {
|
||||||
case FeeEstimateMode::SAT_B: return strprintf("%d.%03d %s/B", nSatoshisPerK / 1000, nSatoshisPerK % 1000, CURRENCY_ATOM);
|
case FeeEstimateMode::SAT_VB: return strprintf("%d.%03d %s/vB", nSatoshisPerK / 1000, nSatoshisPerK % 1000, CURRENCY_ATOM);
|
||||||
default: return strprintf("%d.%08d %s/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN, CURRENCY_UNIT);
|
default: return strprintf("%d.%08d %s/kvB", nSatoshisPerK / COIN, nSatoshisPerK % COIN, CURRENCY_UNIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,8 @@ enum class FeeEstimateMode {
|
||||||
UNSET, //!< Use default settings based on other criteria
|
UNSET, //!< Use default settings based on other criteria
|
||||||
ECONOMICAL, //!< Force estimateSmartFee to use non-conservative estimates
|
ECONOMICAL, //!< Force estimateSmartFee to use non-conservative estimates
|
||||||
CONSERVATIVE, //!< Force estimateSmartFee to use conservative estimates
|
CONSERVATIVE, //!< Force estimateSmartFee to use conservative estimates
|
||||||
BTC_KB, //!< Use explicit BTC/kB fee given in coin control
|
BTC_KVB, //!< Use BTC/kvB fee rate unit
|
||||||
SAT_B, //!< Use explicit sat/B fee given in coin control
|
SAT_VB, //!< Use sat/vB fee rate unit
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,7 +65,7 @@ public:
|
||||||
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; }
|
||||||
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; }
|
CFeeRate& operator+=(const CFeeRate& a) { nSatoshisPerK += a.nSatoshisPerK; return *this; }
|
||||||
std::string ToString(const FeeEstimateMode& fee_estimate_mode = FeeEstimateMode::BTC_KB) const;
|
std::string ToString(const FeeEstimateMode& fee_estimate_mode = FeeEstimateMode::BTC_KVB) const;
|
||||||
|
|
||||||
SERIALIZE_METHODS(CFeeRate, obj) { READWRITE(obj.nSatoshisPerK); }
|
SERIALIZE_METHODS(CFeeRate, obj) { READWRITE(obj.nSatoshisPerK); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(BinaryOperatorTest)
|
||||||
BOOST_CHECK(a <= a);
|
BOOST_CHECK(a <= a);
|
||||||
BOOST_CHECK(b >= a);
|
BOOST_CHECK(b >= a);
|
||||||
BOOST_CHECK(b >= b);
|
BOOST_CHECK(b >= b);
|
||||||
// a should be 0.00000002 BTC/kB now
|
// a should be 0.00000002 BTC/kvB now
|
||||||
a += a;
|
a += a;
|
||||||
BOOST_CHECK(a == b);
|
BOOST_CHECK(a == b);
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,9 @@ BOOST_AUTO_TEST_CASE(ToStringTest)
|
||||||
{
|
{
|
||||||
CFeeRate feeRate;
|
CFeeRate feeRate;
|
||||||
feeRate = CFeeRate(1);
|
feeRate = CFeeRate(1);
|
||||||
BOOST_CHECK_EQUAL(feeRate.ToString(), "0.00000001 BTC/kB");
|
BOOST_CHECK_EQUAL(feeRate.ToString(), "0.00000001 BTC/kvB");
|
||||||
|
BOOST_CHECK_EQUAL(feeRate.ToString(FeeEstimateMode::BTC_KVB), "0.00000001 BTC/kvB");
|
||||||
|
BOOST_CHECK_EQUAL(feeRate.ToString(FeeEstimateMode::SAT_VB), "0.001 sat/vB");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
@ -3136,7 +3136,7 @@ void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& f
|
||||||
}
|
}
|
||||||
CFeeRate fee_rate(AmountFromValue(options["feeRate"]));
|
CFeeRate fee_rate(AmountFromValue(options["feeRate"]));
|
||||||
if (fee_rate <= CFeeRate(0)) {
|
if (fee_rate <= CFeeRate(0)) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid feeRate %s (must be greater than 0)", fee_rate.ToString()));
|
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid feeRate %s (must be greater than 0)", fee_rate.ToString(FeeEstimateMode::BTC_KVB)));
|
||||||
}
|
}
|
||||||
coinControl.m_feerate = fee_rate;
|
coinControl.m_feerate = fee_rate;
|
||||||
coinControl.fOverrideFeeRate = true;
|
coinControl.fOverrideFeeRate = true;
|
||||||
|
|
|
@ -2834,7 +2834,7 @@ bool CWallet::CreateTransactionInternal(
|
||||||
// Do not, ever, assume that it's fine to change the fee rate if the user has explicitly
|
// Do not, ever, assume that it's fine to change the fee rate if the user has explicitly
|
||||||
// provided one
|
// provided one
|
||||||
if (coin_control.m_feerate && nFeeRateNeeded > *coin_control.m_feerate) {
|
if (coin_control.m_feerate && nFeeRateNeeded > *coin_control.m_feerate) {
|
||||||
error = strprintf(_("Fee rate (%s) is lower than the minimum fee rate setting (%s)"), coin_control.m_feerate->ToString(), nFeeRateNeeded.ToString());
|
error = strprintf(_("Fee rate (%s) is lower than the minimum fee rate setting (%s)"), coin_control.m_feerate->ToString(FeeEstimateMode::SAT_VB), nFeeRateNeeded.ToString(FeeEstimateMode::SAT_VB));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -752,9 +752,9 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||||
node.fundrawtransaction, rawtx, {"estimate_mode": mode, "conf_target": n, "add_inputs": True})
|
node.fundrawtransaction, rawtx, {"estimate_mode": mode, "conf_target": n, "add_inputs": True})
|
||||||
|
|
||||||
self.log.info("Test invalid fee rate settings")
|
self.log.info("Test invalid fee rate settings")
|
||||||
assert_raises_rpc_error(-4, "Fee rate (0.00000000 BTC/kB) is lower than the minimum fee rate setting (0.00001000 BTC/kB)",
|
assert_raises_rpc_error(-4, "Fee rate (0.000 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)",
|
||||||
node.fundrawtransaction, rawtx, {"fee_rate": 0, "add_inputs": True})
|
node.fundrawtransaction, rawtx, {"fee_rate": 0, "add_inputs": True})
|
||||||
assert_raises_rpc_error(-8, "Invalid feeRate 0.00000000 BTC/kB (must be greater than 0)",
|
assert_raises_rpc_error(-8, "Invalid feeRate 0.00000000 BTC/kvB (must be greater than 0)",
|
||||||
node.fundrawtransaction, rawtx, {"feeRate": 0, "add_inputs": True})
|
node.fundrawtransaction, rawtx, {"feeRate": 0, "add_inputs": True})
|
||||||
for param, value in {("fee_rate", 100000), ("feeRate", 1.000)}:
|
for param, value in {("fee_rate", 100000), ("feeRate", 1.000)}:
|
||||||
assert_raises_rpc_error(-4, "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)",
|
assert_raises_rpc_error(-4, "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)",
|
||||||
|
@ -768,7 +768,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||||
|
|
||||||
# Test setting explicit fee rate just below the minimum.
|
# Test setting explicit fee rate just below the minimum.
|
||||||
self.log.info("- raises RPC error 'fee rate too low' if fee_rate of 0.99999999 sat/vB is passed")
|
self.log.info("- raises RPC error 'fee rate too low' if fee_rate of 0.99999999 sat/vB is passed")
|
||||||
msg = "Fee rate (0.00000999 BTC/kB) is lower than the minimum fee rate setting (0.00001000 BTC/kB)"
|
msg = "Fee rate (0.999 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)"
|
||||||
assert_raises_rpc_error(-4, msg, node.fundrawtransaction, rawtx, {"fee_rate": 0.99999999, "add_inputs": True})
|
assert_raises_rpc_error(-4, msg, node.fundrawtransaction, rawtx, {"fee_rate": 0.99999999, "add_inputs": True})
|
||||||
# This feeRate test only passes if `coinControl.fOverrideFeeRate = true` in wallet/rpcwallet.cpp::FundTransaction is removed.
|
# This feeRate test only passes if `coinControl.fOverrideFeeRate = true` in wallet/rpcwallet.cpp::FundTransaction is removed.
|
||||||
# assert_raises_rpc_error(-4, msg, node.fundrawtransaction, rawtx, {"feeRate": 0.00000999, "add_inputs": True})
|
# assert_raises_rpc_error(-4, msg, node.fundrawtransaction, rawtx, {"feeRate": 0.00000999, "add_inputs": True})
|
||||||
|
|
|
@ -194,9 +194,9 @@ class PSBTTest(BitcoinTestFramework):
|
||||||
assert_approx(res2["fee"], 0.055, 0.005)
|
assert_approx(res2["fee"], 0.055, 0.005)
|
||||||
|
|
||||||
self.log.info("Test invalid fee rate settings")
|
self.log.info("Test invalid fee rate settings")
|
||||||
assert_raises_rpc_error(-4, "Fee rate (0.00000000 BTC/kB) is lower than the minimum fee rate setting (0.00001000 BTC/kB)",
|
assert_raises_rpc_error(-4, "Fee rate (0.000 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)",
|
||||||
self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"fee_rate": 0, "add_inputs": True})
|
self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"fee_rate": 0, "add_inputs": True})
|
||||||
assert_raises_rpc_error(-8, "Invalid feeRate 0.00000000 BTC/kB (must be greater than 0)",
|
assert_raises_rpc_error(-8, "Invalid feeRate 0.00000000 BTC/kvB (must be greater than 0)",
|
||||||
self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"feeRate": 0, "add_inputs": True})
|
self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"feeRate": 0, "add_inputs": True})
|
||||||
for param, value in {("fee_rate", 100000), ("feeRate", 1)}:
|
for param, value in {("fee_rate", 100000), ("feeRate", 1)}:
|
||||||
assert_raises_rpc_error(-4, "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)",
|
assert_raises_rpc_error(-4, "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)",
|
||||||
|
@ -246,7 +246,7 @@ class PSBTTest(BitcoinTestFramework):
|
||||||
|
|
||||||
# Test setting explicit fee rate just below the minimum.
|
# Test setting explicit fee rate just below the minimum.
|
||||||
self.log.info("- raises RPC error 'fee rate too low' if feerate_sat_vb of 0.99999999 is passed")
|
self.log.info("- raises RPC error 'fee rate too low' if feerate_sat_vb of 0.99999999 is passed")
|
||||||
assert_raises_rpc_error(-4, "Fee rate (0.00000999 BTC/kB) is lower than the minimum fee rate setting (0.00001000 BTC/kB)",
|
assert_raises_rpc_error(-4, "Fee rate (0.999 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)",
|
||||||
self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"fee_rate": 0.99999999, "add_inputs": True})
|
self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"fee_rate": 0.99999999, "add_inputs": True})
|
||||||
|
|
||||||
self.log.info("Test walletcreatefundedpsbt with too-high fee rate produces total fee well above -maxtxfee and raises RPC error")
|
self.log.info("Test walletcreatefundedpsbt with too-high fee rate produces total fee well above -maxtxfee and raises RPC error")
|
||||||
|
|
|
@ -250,11 +250,11 @@ class WalletTest(BitcoinTestFramework):
|
||||||
|
|
||||||
# Test setting explicit fee rate just below the minimum.
|
# Test setting explicit fee rate just below the minimum.
|
||||||
self.log.info("Test sendmany raises 'fee rate too low' if fee_rate of 0.99999999 is passed")
|
self.log.info("Test sendmany raises 'fee rate too low' if fee_rate of 0.99999999 is passed")
|
||||||
assert_raises_rpc_error(-6, "Fee rate (0.00000999 BTC/kB) is lower than the minimum fee rate setting (0.00001000 BTC/kB)",
|
assert_raises_rpc_error(-6, "Fee rate (0.999 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)",
|
||||||
self.nodes[2].sendmany, amounts={address: 10}, fee_rate=0.99999999)
|
self.nodes[2].sendmany, amounts={address: 10}, fee_rate=0.99999999)
|
||||||
|
|
||||||
self.log.info("Test sendmany raises if fee_rate of 0 or -1 is passed")
|
self.log.info("Test sendmany raises if fee_rate of 0 or -1 is passed")
|
||||||
assert_raises_rpc_error(-6, "Fee rate (0.00000000 BTC/kB) is lower than the minimum fee rate setting (0.00001000 BTC/kB)",
|
assert_raises_rpc_error(-6, "Fee rate (0.000 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)",
|
||||||
self.nodes[2].sendmany, amounts={address: 10}, fee_rate=0)
|
self.nodes[2].sendmany, amounts={address: 10}, fee_rate=0)
|
||||||
assert_raises_rpc_error(-3, OUT_OF_RANGE, self.nodes[2].sendmany, amounts={address: 10}, fee_rate=-1)
|
assert_raises_rpc_error(-3, OUT_OF_RANGE, self.nodes[2].sendmany, amounts={address: 10}, fee_rate=-1)
|
||||||
|
|
||||||
|
@ -421,11 +421,11 @@ class WalletTest(BitcoinTestFramework):
|
||||||
|
|
||||||
# Test setting explicit fee rate just below the minimum.
|
# Test setting explicit fee rate just below the minimum.
|
||||||
self.log.info("Test sendtoaddress raises 'fee rate too low' if fee_rate of 0.99999999 is passed")
|
self.log.info("Test sendtoaddress raises 'fee rate too low' if fee_rate of 0.99999999 is passed")
|
||||||
assert_raises_rpc_error(-6, "Fee rate (0.00000999 BTC/kB) is lower than the minimum fee rate setting (0.00001000 BTC/kB)",
|
assert_raises_rpc_error(-6, "Fee rate (0.999 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)",
|
||||||
self.nodes[2].sendtoaddress, address=address, amount=1, fee_rate=0.99999999)
|
self.nodes[2].sendtoaddress, address=address, amount=1, fee_rate=0.99999999)
|
||||||
|
|
||||||
self.log.info("Test sendtoaddress raises if fee_rate of 0 or -1 is passed")
|
self.log.info("Test sendtoaddress raises if fee_rate of 0 or -1 is passed")
|
||||||
assert_raises_rpc_error(-6, "Fee rate (0.00000000 BTC/kB) is lower than the minimum fee rate setting (0.00001000 BTC/kB)",
|
assert_raises_rpc_error(-6, "Fee rate (0.000 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)",
|
||||||
self.nodes[2].sendtoaddress, address=address, amount=10, fee_rate=0)
|
self.nodes[2].sendtoaddress, address=address, amount=10, fee_rate=0)
|
||||||
assert_raises_rpc_error(-3, OUT_OF_RANGE, self.nodes[2].sendtoaddress, address=address, amount=1.0, fee_rate=-1)
|
assert_raises_rpc_error(-3, OUT_OF_RANGE, self.nodes[2].sendtoaddress, address=address, amount=1.0, fee_rate=-1)
|
||||||
|
|
||||||
|
|
|
@ -306,11 +306,10 @@ class WalletSendTest(BitcoinTestFramework):
|
||||||
self.test_send(from_wallet=w0, to_wallet=w1, amount=1, conf_target=v, estimate_mode=mode,
|
self.test_send(from_wallet=w0, to_wallet=w1, amount=1, conf_target=v, estimate_mode=mode,
|
||||||
expect_error=(-3, "Expected type number for conf_target, got {}".format(k)))
|
expect_error=(-3, "Expected type number for conf_target, got {}".format(k)))
|
||||||
|
|
||||||
# TODO: The error message should use sat/vB units instead of BTC/kB.
|
|
||||||
# Test setting explicit fee rate just below the minimum.
|
# Test setting explicit fee rate just below the minimum.
|
||||||
self.log.info("Explicit fee rate raises RPC error 'fee rate too low' if fee_rate of 0.99999999 is passed")
|
self.log.info("Explicit fee rate raises RPC error 'fee rate too low' if fee_rate of 0.99999999 is passed")
|
||||||
self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=0.99999999,
|
self.test_send(from_wallet=w0, to_wallet=w1, amount=1, fee_rate=0.99999999,
|
||||||
expect_error=(-4, "Fee rate (0.00000999 BTC/kB) is lower than the minimum fee rate setting (0.00001000 BTC/kB)"))
|
expect_error=(-4, "Fee rate (0.999 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)"))
|
||||||
|
|
||||||
# TODO: Return hex if fee rate is below -maxmempool
|
# TODO: Return hex if fee rate is below -maxmempool
|
||||||
# res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, conf_target=0.1, estimate_mode="sat/b", add_to_wallet=False)
|
# res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, conf_target=0.1, estimate_mode="sat/b", add_to_wallet=False)
|
||||||
|
|
Loading…
Add table
Reference in a new issue