mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-05-12 19:20:42 +02:00
Merge 20391 via rpc_setfeerate-28+knots
This commit is contained in:
commit
a22e586743
@ -13,6 +13,7 @@
|
||||
|
||||
class CBlock;
|
||||
class CBlockHeader;
|
||||
class CFeeRate;
|
||||
class CScript;
|
||||
class CTransaction;
|
||||
struct CMutableTransaction;
|
||||
@ -41,6 +42,7 @@ bool DecodeHexBlockHeader(CBlockHeader&, const std::string& hex_header);
|
||||
|
||||
// core_write.cpp
|
||||
UniValue ValueFromAmount(const CAmount amount);
|
||||
UniValue ValueFromFeeRate(const CFeeRate& fee_rate);
|
||||
std::string FormatScript(const CScript& script);
|
||||
std::string EncodeHexTx(const CTransaction& tx);
|
||||
std::string SighashToStr(unsigned char sighash_type);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <consensus/consensus.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <key_io.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <script/descriptor.h>
|
||||
#include <script/script.h>
|
||||
#include <script/solver.h>
|
||||
@ -36,6 +37,11 @@ UniValue ValueFromAmount(const CAmount amount)
|
||||
strprintf("%s%d.%08d", amount < 0 ? "-" : "", quotient, remainder));
|
||||
}
|
||||
|
||||
UniValue ValueFromFeeRate(const CFeeRate& fee_rate)
|
||||
{
|
||||
return UniValue(UniValue::VNUM, fee_rate.SatsToString());
|
||||
}
|
||||
|
||||
std::string FormatScript(const CScript& script)
|
||||
{
|
||||
std::string ret;
|
||||
|
@ -43,3 +43,7 @@ std::string CFeeRate::ToString(const FeeEstimateMode& fee_estimate_mode) const
|
||||
default: return strprintf("%d.%08d %s/kvB", nSatoshisPerK / COIN, nSatoshisPerK % COIN, CURRENCY_UNIT);
|
||||
}
|
||||
}
|
||||
|
||||
std::string CFeeRate::SatsToString() const {
|
||||
return strprintf("%d.%03d", nSatoshisPerK / 1000, nSatoshisPerK % 1000);
|
||||
}
|
||||
|
@ -68,7 +68,10 @@ 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; }
|
||||
CFeeRate& operator+=(const CFeeRate& a) { nSatoshisPerK += a.nSatoshisPerK; return *this; }
|
||||
/** Return the fee rate in sat/vB or BTC/kvB, with units, as a string. */
|
||||
std::string ToString(const FeeEstimateMode& fee_estimate_mode = FeeEstimateMode::BTC_KVB) const;
|
||||
/** Return the fee rate in sat/vB, without units, as a string. */
|
||||
std::string SatsToString() const;
|
||||
friend CFeeRate operator*(const CFeeRate& f, int a) { return CFeeRate(a * f.nSatoshisPerK); }
|
||||
friend CFeeRate operator*(int a, const CFeeRate& f) { return CFeeRate(a * f.nSatoshisPerK); }
|
||||
|
||||
|
@ -47,6 +47,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||
{ "sendtoaddress", 8, "avoid_reuse" },
|
||||
{ "sendtoaddress", 9, "fee_rate"},
|
||||
{ "sendtoaddress", 10, "verbose"},
|
||||
{ "setfeerate", 0, "amount" },
|
||||
{ "settxfee", 0, "amount" },
|
||||
{ "sethdseed", 0, "newkeypool" },
|
||||
{ "getreceivedbyaddress", 1, "minconf" },
|
||||
|
@ -139,4 +139,12 @@ BOOST_AUTO_TEST_CASE(ToStringTest)
|
||||
BOOST_CHECK_EQUAL(feeRate.ToString(FeeEstimateMode::SAT_VB), "0.001 sat/vB");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SatsToStringTest)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(CFeeRate(1).SatsToString(), "0.001");
|
||||
BOOST_CHECK_EQUAL(CFeeRate(70).SatsToString(), "0.070");
|
||||
BOOST_CHECK_EQUAL(CFeeRate(3141).SatsToString(), "3.141");
|
||||
BOOST_CHECK_EQUAL(CFeeRate(10002).SatsToString(), "10.002");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
@ -311,6 +311,17 @@ BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values)
|
||||
BOOST_CHECK_THROW(AmountFromValue(ValueFromString("93e+9")), UniValue); //overflow error
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(rpc_parse_fee_rate_values)
|
||||
{
|
||||
// Test ValueFromFeeRate() and CFeeRate()
|
||||
// ...using default CFeeRate constructor
|
||||
BOOST_CHECK_EQUAL(ValueFromFeeRate(CFeeRate(AmountFromValue(0.00001234))).get_real(), 1.234);
|
||||
BOOST_CHECK_EQUAL(ValueFromFeeRate(CFeeRate(AmountFromValue(0.1234))).get_real(), 12340.000);
|
||||
BOOST_CHECK_EQUAL(ValueFromFeeRate(CFeeRate(AmountFromValue(1234))).get_real(), 123400000.000);
|
||||
// ...using CFeeRate constructor with bytes 1000
|
||||
BOOST_CHECK_EQUAL(ValueFromFeeRate(CFeeRate(AmountFromValue(0.00001234), 1000)).get_real(), 1.234);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(rpc_ban)
|
||||
{
|
||||
BOOST_CHECK_NO_THROW(CallRPC(std::string("clearbanned")));
|
||||
|
@ -433,6 +433,80 @@ RPCHelpMan sendmany()
|
||||
};
|
||||
}
|
||||
|
||||
RPCHelpMan setfeerate()
|
||||
{
|
||||
return RPCHelpMan{
|
||||
"setfeerate",
|
||||
"\nSet the transaction fee rate in " + CURRENCY_ATOM + "/vB for this wallet.\n"
|
||||
"Overrides the global -paytxfee configuration option. Like -paytxfee, it is not persisted after bitcoind shutdown/restart.\n"
|
||||
"Can be deactivated by passing 0 as the fee rate, in which case automatic fee selection will be used by default.\n",
|
||||
{
|
||||
{"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The transaction fee rate in " + CURRENCY_ATOM + "/vB to set (0 to unset)"},
|
||||
},
|
||||
RPCResult{
|
||||
RPCResult::Type::OBJ, "", "",
|
||||
{
|
||||
{RPCResult::Type::STR, "wallet_name", "Name of the wallet the fee rate setting applies to"},
|
||||
{RPCResult::Type::NUM, "fee_rate", "Fee rate in " + CURRENCY_ATOM + "/vB for the wallet after this operation"},
|
||||
{RPCResult::Type::STR, "result", /* optional */ true, "Description of result, if successful"},
|
||||
{RPCResult::Type::STR, "error", /* optional */ true, "Description of error, if any"},
|
||||
},
|
||||
},
|
||||
RPCExamples{
|
||||
""
|
||||
"\nSet a fee rate of 1 " + CURRENCY_ATOM + "/vB\n"
|
||||
+ HelpExampleCli("setfeerate", "1") +
|
||||
"\nSet a fee rate of 3.141 " + CURRENCY_ATOM + "/vB\n"
|
||||
+ HelpExampleCli("setfeerate", "3.141") +
|
||||
"\nSet a fee rate of 7.75 " + CURRENCY_ATOM + "/vB with named arguments\n"
|
||||
+ HelpExampleCli("-named setfeerate", "amount=\"7.75\"") +
|
||||
"\nSet a fee rate of 25 " + CURRENCY_ATOM + "/vB with the RPC\n"
|
||||
+ HelpExampleRpc("setfeerate", "25")
|
||||
},
|
||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
|
||||
std::shared_ptr<CWallet> const rpc_wallet{GetWalletForJSONRPCRequest(request)};
|
||||
if (!rpc_wallet) return NullUniValue;
|
||||
CWallet& wallet = *rpc_wallet;
|
||||
|
||||
LOCK(wallet.cs_wallet);
|
||||
const CFeeRate amount{AmountFromValue(request.params[0]), COIN /* sat/vB */};
|
||||
const CFeeRate relay_min_feerate{wallet.chain().relayMinFee().GetFeePerK()};
|
||||
const CFeeRate wallet_min_feerate{wallet.m_min_fee.GetFeePerK()};
|
||||
const CFeeRate wallet_max_feerate{wallet.m_default_max_tx_fee, 1000 /* BTC/kvB */};
|
||||
const CFeeRate zero{CFeeRate{0}};
|
||||
const std::string amount_str{amount.ToString(FeeEstimateMode::SAT_VB)};
|
||||
const std::string current_setting{strprintf("The current setting of %s for this wallet remains unchanged.", wallet.m_pay_tx_fee == zero ? "0 (unset)" : wallet.m_pay_tx_fee.ToString(FeeEstimateMode::SAT_VB))};
|
||||
std::string result, error;
|
||||
|
||||
if (amount == zero) {
|
||||
if (request.params[0].get_real() != 0) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
|
||||
wallet.m_pay_tx_fee = amount;
|
||||
result = "Fee rate for transactions with this wallet successfully unset. By default, automatic fee selection will be used.";
|
||||
} else if (amount < relay_min_feerate) {
|
||||
error = strprintf("The requested fee rate of %s cannot be less than the minimum relay fee rate of %s. %s", amount_str, relay_min_feerate.ToString(FeeEstimateMode::SAT_VB), current_setting);
|
||||
} else if (amount < wallet_min_feerate) {
|
||||
error = strprintf("The requested fee rate of %s cannot be less than the wallet min fee rate of %s. %s", amount_str, wallet_min_feerate.ToString(FeeEstimateMode::SAT_VB), current_setting);
|
||||
} else if (amount > wallet_max_feerate) {
|
||||
error = strprintf("The requested fee rate of %s cannot be greater than the wallet max fee rate of %s. %s", amount_str, wallet_max_feerate.ToString(FeeEstimateMode::SAT_VB), current_setting);
|
||||
} else {
|
||||
wallet.m_pay_tx_fee = amount;
|
||||
result = "Fee rate for transactions with this wallet successfully set to " + amount_str;
|
||||
}
|
||||
CHECK_NONFATAL(result.empty() != error.empty());
|
||||
|
||||
UniValue obj{UniValue::VOBJ};
|
||||
obj.pushKV("wallet_name", wallet.GetName());
|
||||
obj.pushKV("fee_rate", ValueFromFeeRate(wallet.m_pay_tx_fee));
|
||||
if (error.empty()) {
|
||||
obj.pushKV("result", result);
|
||||
} else {
|
||||
obj.pushKV("error", error);
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
RPCHelpMan settxfee()
|
||||
{
|
||||
return RPCHelpMan{"settxfee",
|
||||
|
@ -1075,6 +1075,7 @@ RPCHelpMan encryptwallet();
|
||||
// spend
|
||||
RPCHelpMan sendtoaddress();
|
||||
RPCHelpMan sendmany();
|
||||
RPCHelpMan setfeerate();
|
||||
RPCHelpMan settxfee();
|
||||
RPCHelpMan fundrawtransaction();
|
||||
RPCHelpMan bumpfee();
|
||||
@ -1156,6 +1157,7 @@ Span<const CRPCCommand> GetWalletRPCCommands()
|
||||
{"wallet", &sendtoaddress},
|
||||
{"wallet", &sethdseed},
|
||||
{"wallet", &setlabel},
|
||||
{"wallet", &setfeerate},
|
||||
{"wallet", &settxfee},
|
||||
{"wallet", &setwalletflag},
|
||||
{"wallet", &signmessage},
|
||||
|
@ -19,10 +19,12 @@ from test_framework.blocktools import (
|
||||
COINBASE_MATURITY,
|
||||
)
|
||||
from test_framework.messages import (
|
||||
COIN,
|
||||
MAX_BIP125_RBF_SEQUENCE,
|
||||
)
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_approx,
|
||||
assert_equal,
|
||||
assert_fee_amount,
|
||||
assert_greater_than,
|
||||
@ -62,6 +64,7 @@ class BumpFeeTest(BitcoinTestFramework):
|
||||
"-mintxfee=0.00002",
|
||||
"-addresstype=bech32",
|
||||
] for i in range(self.num_nodes)]
|
||||
self.wallet_names = [self.default_wallet_name, "RBF wallet"]
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
self.skip_if_no_wallet()
|
||||
@ -106,6 +109,7 @@ class BumpFeeTest(BitcoinTestFramework):
|
||||
test_bumpfee_metadata(self, rbf_node, dest_address)
|
||||
test_locked_wallet_fails(self, rbf_node, dest_address)
|
||||
test_change_script_match(self, rbf_node, dest_address)
|
||||
test_setfeerate(self, rbf_node, dest_address)
|
||||
test_settxfee(self, rbf_node, dest_address)
|
||||
test_maxtxfee_fails(self, rbf_node, dest_address)
|
||||
# These tests wipe out a number of utxos that are expected in other tests
|
||||
@ -532,6 +536,44 @@ def test_dust_to_fee(self, rbf_node, dest_address):
|
||||
self.clear_mempool()
|
||||
|
||||
|
||||
def test_setfeerate(self, rbf_node, dest_address):
|
||||
self.log.info("Test setfeerate")
|
||||
|
||||
def test_response(*, wallet="RBF wallet", requested=0, expected=0, error=None, msg):
|
||||
assert_equal(rbf_node.setfeerate(requested), {"wallet_name": wallet, "fee_rate": expected, ("error" if error else "result"): msg})
|
||||
|
||||
# Test setfeerate with too high/low values returns expected errors
|
||||
new = Decimal("10000.001")
|
||||
test_response(requested=new, error=True, msg=f"The requested fee rate of {new} sat/vB cannot be greater than the wallet max fee rate of 10000.000 sat/vB. The current setting of 0 (unset) for this wallet remains unchanged.")
|
||||
new = Decimal("0.999")
|
||||
test_response(requested=new, error=True, msg=f"The requested fee rate of {new} sat/vB cannot be less than the minimum relay fee rate of 1.000 sat/vB. The current setting of 0 (unset) for this wallet remains unchanged.")
|
||||
fee_rate = Decimal("2.001")
|
||||
test_response(requested=fee_rate, expected=fee_rate, msg=f"Fee rate for transactions with this wallet successfully set to {fee_rate} sat/vB")
|
||||
new = Decimal("1.999")
|
||||
test_response(requested=new, expected=fee_rate, error=True, msg=f"The requested fee rate of {new} sat/vB cannot be less than the wallet min fee rate of 2.000 sat/vB. The current setting of {fee_rate} sat/vB for this wallet remains unchanged.")
|
||||
|
||||
# Test setfeerate with valid values returns expected results
|
||||
rbfid = spend_one_input(rbf_node, dest_address)
|
||||
fee_rate = 25
|
||||
test_response(requested=fee_rate, expected=fee_rate, msg="Fee rate for transactions with this wallet successfully set to 25.000 sat/vB")
|
||||
bumped_tx = rbf_node.bumpfee(rbfid)
|
||||
bumped_txdetails = rbf_node.getrawtransaction(bumped_tx["txid"], True)
|
||||
allow_for_bytes_offset = len(bumped_txdetails['vout']) * 2 # potentially up to 2 bytes per output
|
||||
actual_fee = bumped_tx["fee"] * COIN
|
||||
assert_approx(actual_fee, fee_rate * bumped_txdetails['vsize'], fee_rate * allow_for_bytes_offset)
|
||||
test_response(msg="Fee rate for transactions with this wallet successfully unset. By default, automatic fee selection will be used.")
|
||||
|
||||
# Test setfeerate with a different -maxtxfee
|
||||
self.restart_node(1, ["-maxtxfee=0.000025"] + self.extra_args[1])
|
||||
new = "2.501"
|
||||
test_response(requested=new, error=True, msg=f"The requested fee rate of {new} sat/vB cannot be greater than the wallet max fee rate of 2.500 sat/vB. The current setting of 0 (unset) for this wallet remains unchanged.")
|
||||
|
||||
self.restart_node(1, self.extra_args[1])
|
||||
rbf_node.walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT)
|
||||
self.connect_nodes(1, 0)
|
||||
self.clear_mempool()
|
||||
|
||||
|
||||
def test_settxfee(self, rbf_node, dest_address):
|
||||
self.log.info('Test settxfee')
|
||||
assert_raises_rpc_error(-8, "txfee cannot be less than min relay tx fee", rbf_node.settxfee, Decimal('0.000005'))
|
||||
|
@ -3,6 +3,8 @@
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
from test_framework.messages import (
|
||||
tx_from_hex,
|
||||
)
|
||||
@ -37,6 +39,7 @@ class CreateTxWalletTest(BitcoinTestFramework):
|
||||
self.test_tx_size_too_large()
|
||||
self.test_create_too_long_mempool_chain()
|
||||
self.test_version3()
|
||||
self.test_setfeerate()
|
||||
|
||||
def test_anti_fee_sniping(self):
|
||||
self.log.info('Check that we have some (old) blocks and that anti-fee-sniping is disabled')
|
||||
@ -55,6 +58,7 @@ class CreateTxWalletTest(BitcoinTestFramework):
|
||||
# More than 10kB of outputs, so that we hit -maxtxfee with a high feerate
|
||||
outputs = {self.nodes[0].getnewaddress(address_type='bech32'): 0.000025 for _ in range(400)}
|
||||
raw_tx = self.nodes[0].createrawtransaction(inputs=[], outputs=outputs)
|
||||
msg = "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)"
|
||||
|
||||
for fee_setting in ['-minrelaytxfee=0.01', '-mintxfee=0.01', '-paytxfee=0.01']:
|
||||
self.log.info('Check maxtxfee in combination with {}'.format(fee_setting))
|
||||
@ -85,6 +89,12 @@ class CreateTxWalletTest(BitcoinTestFramework):
|
||||
)
|
||||
self.nodes[0].settxfee(0)
|
||||
|
||||
self.log.info('Check maxtxfee in combination with setfeerate (sat/vB)')
|
||||
self.nodes[0].setfeerate(1000)
|
||||
assert_raises_rpc_error(-6, msg, self.nodes[0].sendmany, dummy="", amounts=outputs)
|
||||
assert_raises_rpc_error(-4, msg, self.nodes[0].fundrawtransaction, hexstring=raw_tx)
|
||||
self.nodes[0].setfeerate(0)
|
||||
|
||||
def test_create_too_long_mempool_chain(self):
|
||||
self.log.info('Check too-long mempool chain error')
|
||||
df_wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
|
||||
@ -127,6 +137,51 @@ class CreateTxWalletTest(BitcoinTestFramework):
|
||||
assert_equal(tx_current_version.version, 2)
|
||||
wallet_v3.unloadwallet()
|
||||
|
||||
def test_setfeerate(self):
|
||||
self.log.info("Test setfeerate")
|
||||
self.restart_node(0, extra_args=["-mintxfee=0.00003141"]) # 3.141 sat/vB
|
||||
node = self.nodes[0]
|
||||
|
||||
def test_response(*, requested=0, expected=0, error=None, msg):
|
||||
assert_equal(node.setfeerate(requested), {"wallet_name": self.default_wallet_name, "fee_rate": expected, ("error" if error else "result"): msg})
|
||||
|
||||
# Test setfeerate with 10.0001 (CFeeRate rounding), "10.001" and "4" sat/vB
|
||||
test_response(requested=10.0001, expected=10, msg="Fee rate for transactions with this wallet successfully set to 10.000 sat/vB")
|
||||
assert_equal(node.getwalletinfo()["paytxfee"], Decimal("0.00010000"))
|
||||
test_response(requested="10.001", expected=Decimal("10.001"), msg="Fee rate for transactions with this wallet successfully set to 10.001 sat/vB")
|
||||
assert_equal(node.getwalletinfo()["paytxfee"], Decimal("0.00010001"))
|
||||
test_response(requested="4", expected=4, msg="Fee rate for transactions with this wallet successfully set to 4.000 sat/vB")
|
||||
assert_equal(node.getwalletinfo()["paytxfee"], Decimal("0.00004000"))
|
||||
|
||||
# Test setfeerate with too-high/low values returns expected errors
|
||||
test_response(requested=Decimal("10000.001"), expected=4, error=True, msg="The requested fee rate of 10000.001 sat/vB cannot be greater than the wallet max fee rate of 10000.000 sat/vB. The current setting of 4.000 sat/vB for this wallet remains unchanged.")
|
||||
test_response(requested=Decimal("0.999"), expected=4, error=True, msg="The requested fee rate of 0.999 sat/vB cannot be less than the minimum relay fee rate of 1.000 sat/vB. The current setting of 4.000 sat/vB for this wallet remains unchanged.")
|
||||
test_response(requested=Decimal("3.140"), expected=4, error=True, msg="The requested fee rate of 3.140 sat/vB cannot be less than the wallet min fee rate of 3.141 sat/vB. The current setting of 4.000 sat/vB for this wallet remains unchanged.")
|
||||
assert_equal(node.getwalletinfo()["paytxfee"], Decimal("0.00004000"))
|
||||
|
||||
# Test setfeerate to 3.141 sat/vB
|
||||
test_response(requested=3.141, expected=Decimal("3.141"), msg="Fee rate for transactions with this wallet successfully set to 3.141 sat/vB")
|
||||
assert_equal(node.getwalletinfo()["paytxfee"], Decimal("0.00003141"))
|
||||
|
||||
# Test setfeerate with values non-representable by CFeeRate
|
||||
for invalid_value in [0.00000001, 0.0009, 0.00099999]:
|
||||
assert_raises_rpc_error(-3, "Invalid amount", node.setfeerate, amount=invalid_value)
|
||||
|
||||
# Test setfeerate with values rejected by ParseFixedPoint() called in AmountFromValue()
|
||||
for invalid_value in ["", 0.000000001, "1.111111111", 11111111111]:
|
||||
assert_raises_rpc_error(-3, "Invalid amount", node.setfeerate, amount=invalid_value)
|
||||
|
||||
# Test deactivating setfeerate
|
||||
test_response(msg="Fee rate for transactions with this wallet successfully unset. By default, automatic fee selection will be used.")
|
||||
assert_equal(node.getwalletinfo()["paytxfee"], 0)
|
||||
|
||||
# Test currently-unset setfeerate with too-high/low values returns expected errors
|
||||
test_response(requested=Decimal("10000.001"), error=True, msg="The requested fee rate of 10000.001 sat/vB cannot be greater than the wallet max fee rate of 10000.000 sat/vB. The current setting of 0 (unset) for this wallet remains unchanged.")
|
||||
assert_equal(node.getwalletinfo()["paytxfee"], 0)
|
||||
test_response(requested=Decimal("0.999"), error=True, msg="The requested fee rate of 0.999 sat/vB cannot be less than the minimum relay fee rate of 1.000 sat/vB. The current setting of 0 (unset) for this wallet remains unchanged.")
|
||||
test_response(requested=Decimal("3.140"), error=True, msg="The requested fee rate of 3.140 sat/vB cannot be less than the wallet min fee rate of 3.141 sat/vB. The current setting of 0 (unset) for this wallet remains unchanged.")
|
||||
assert_equal(node.getwalletinfo()["paytxfee"], 0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
CreateTxWalletTest(__file__).main()
|
||||
|
@ -250,12 +250,18 @@ class MultiWalletTest(BitcoinTestFramework):
|
||||
assert_equal(batch[0]["result"]["chain"], self.chain)
|
||||
assert_equal(batch[1]["result"]["walletname"], "w1")
|
||||
|
||||
self.log.info('Check for per-wallet settxfee call')
|
||||
self.log.info('Test per-wallet setfeerate and settxfee calls')
|
||||
assert_equal(w1.getwalletinfo()['paytxfee'], 0)
|
||||
assert_equal(w2.getwalletinfo()['paytxfee'], 0)
|
||||
w2.setfeerate(200)
|
||||
assert_equal(w1.getwalletinfo()['paytxfee'], 0)
|
||||
assert_equal(w2.getwalletinfo()['paytxfee'], Decimal('0.00200000'))
|
||||
w2.settxfee(0.001)
|
||||
assert_equal(w1.getwalletinfo()['paytxfee'], 0)
|
||||
assert_equal(w2.getwalletinfo()['paytxfee'], Decimal('0.00100000'))
|
||||
w1.setfeerate(30)
|
||||
assert_equal(w1.getwalletinfo()['paytxfee'], Decimal('0.00030000'))
|
||||
assert_equal(w2.getwalletinfo()['paytxfee'], Decimal('0.00100000'))
|
||||
|
||||
self.log.info("Test dynamic wallet loading")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user