mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-25 02:33:24 -03:00
Merge ddcef3f18d
into 66aa6a47bd
This commit is contained in:
commit
4540cd4c61
11 changed files with 152 additions and 4 deletions
|
@ -48,6 +48,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
|||
{ "sendtoaddress", 9, "fee_rate"},
|
||||
{ "sendtoaddress", 10, "verbose"},
|
||||
{ "settxfee", 0, "amount" },
|
||||
{ "settxfeerate", 0, "amount" },
|
||||
{ "sethdseed", 0, "newkeypool" },
|
||||
{ "getreceivedbyaddress", 1, "minconf" },
|
||||
{ "getreceivedbyaddress", 2, "include_immature_coinbase" },
|
||||
|
|
|
@ -418,7 +418,7 @@ RPCHelpMan sendmany()
|
|||
RPCHelpMan settxfee()
|
||||
{
|
||||
return RPCHelpMan{"settxfee",
|
||||
"\nSet the transaction fee rate in " + CURRENCY_UNIT + "/kvB for this wallet. Overrides the global -paytxfee command line parameter.\n"
|
||||
"\n(DEPRECATED)Set the transaction fee rate in " + CURRENCY_UNIT + "/kvB for this wallet. Overrides the global -paytxfee command line parameter.\n"
|
||||
"Can be deactivated by passing 0 as the fee. In that case automatic fee selection will be used by default.\n",
|
||||
{
|
||||
{"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The transaction fee rate in " + CURRENCY_UNIT + "/kvB"},
|
||||
|
@ -437,6 +437,10 @@ RPCHelpMan settxfee()
|
|||
|
||||
LOCK(pwallet->cs_wallet);
|
||||
|
||||
if (!pwallet->chain().rpcEnableDeprecated("settxfee")) {
|
||||
throw JSONRPCError(RPC_METHOD_DEPRECATED, "Using settxfee is deprecated. Use settxfeerate instead or restart bitcoind with -deprecatedrpc=settxfee. This functionality will be removed in x.xx");
|
||||
}
|
||||
|
||||
CAmount nAmount = AmountFromValue(request.params[0]);
|
||||
CFeeRate tx_fee_rate(nAmount, 1000);
|
||||
CFeeRate max_tx_fee_rate(pwallet->m_default_max_tx_fee, 1000);
|
||||
|
@ -456,6 +460,53 @@ RPCHelpMan settxfee()
|
|||
};
|
||||
}
|
||||
|
||||
RPCHelpMan settxfeerate()
|
||||
{
|
||||
return RPCHelpMan{"settxfeerate",
|
||||
"\nSet the transaction fee rate in " + CURRENCY_ATOM + "/vB for this wallet. Overrides the global -paytxfee command line parameter.\n"
|
||||
"Can be deactivated by passing 0 as the fee. In that 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"},
|
||||
},
|
||||
RPCResult{
|
||||
RPCResult::Type::BOOL, "", "Returns true if successful"
|
||||
},
|
||||
RPCExamples{
|
||||
HelpExampleCli("settxfeerate", "1")
|
||||
+ HelpExampleRpc("settxfeerate", "1")
|
||||
},
|
||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||
{
|
||||
|
||||
CAmount test = AmountFromValue(request.params[0]);
|
||||
double conv_ammount = (static_cast<double>(test) / COIN) / 100000; // Convert to BTC/kvB
|
||||
CAmount nAmount = AmountFromValue(UniValue(conv_ammount));
|
||||
|
||||
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
|
||||
|
||||
if (!pwallet) return UniValue::VNULL;
|
||||
|
||||
LOCK(pwallet->cs_wallet);
|
||||
|
||||
CFeeRate tx_fee_rate(nAmount, 1000);
|
||||
CFeeRate max_tx_fee_rate(pwallet->m_default_max_tx_fee, 1000);
|
||||
if (tx_fee_rate == CFeeRate(0)) {
|
||||
// automatic selection
|
||||
} else if (tx_fee_rate < pwallet->chain().relayMinFee()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("txfee cannot be less than min relay tx fee (%s)", pwallet->chain().relayMinFee().ToString(FeeEstimateMode::SAT_VB)));
|
||||
} else if (tx_fee_rate < pwallet->m_min_fee) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("txfee cannot be less than wallet min fee (%s)", pwallet->m_min_fee.ToString(FeeEstimateMode::SAT_VB)));
|
||||
} else if (tx_fee_rate > max_tx_fee_rate) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("txfee cannot be more than wallet max tx fee (%s)", max_tx_fee_rate.ToString(FeeEstimateMode::SAT_VB)));
|
||||
}
|
||||
|
||||
pwallet->m_pay_tx_fee = tx_fee_rate;
|
||||
return true;
|
||||
|
||||
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Only includes key documentation where the key is snake_case in all RPC methods. MixedCase keys can be added later.
|
||||
static std::vector<RPCArg> FundTxDoc(bool solving_data = true)
|
||||
|
|
|
@ -1076,6 +1076,7 @@ RPCHelpMan encryptwallet();
|
|||
RPCHelpMan sendtoaddress();
|
||||
RPCHelpMan sendmany();
|
||||
RPCHelpMan settxfee();
|
||||
RPCHelpMan settxfeerate();
|
||||
RPCHelpMan fundrawtransaction();
|
||||
RPCHelpMan bumpfee();
|
||||
RPCHelpMan psbtbumpfee();
|
||||
|
@ -1156,7 +1157,8 @@ Span<const CRPCCommand> GetWalletRPCCommands()
|
|||
{"wallet", &sendtoaddress},
|
||||
{"wallet", &sethdseed},
|
||||
{"wallet", &setlabel},
|
||||
{"wallet", &settxfee},
|
||||
{"hidden", &settxfee},
|
||||
{"wallet", &settxfeerate},
|
||||
{"wallet", &setwalletflag},
|
||||
{"wallet", &signmessage},
|
||||
{"wallet", &signrawtransactionwithwallet},
|
||||
|
|
83
test/functional/rpc_settxfeerate.py
Executable file
83
test/functional/rpc_settxfeerate.py
Executable file
|
@ -0,0 +1,83 @@
|
|||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2024 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
"""Test the wallet changes the feerate configured properly when settxfee and settxfeerate is set."""
|
||||
|
||||
from decimal import Decimal
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
assert_raises_rpc_error
|
||||
)
|
||||
|
||||
|
||||
class RPCSetTxFeeTest(BitcoinTestFramework):
|
||||
def add_options(self, parser):
|
||||
self.add_wallet_options(parser)
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
self.skip_if_no_wallet()
|
||||
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 2
|
||||
self.extra_args = [["-deprecatedrpc=settxfee"], []]
|
||||
self.supports_cli = False
|
||||
|
||||
def run_test(self):
|
||||
node = self.nodes[0]
|
||||
|
||||
self.log.debug("Test that settxfee is a hidden RPC")
|
||||
# It is hidden from general help, but its detailed help may be called directly.
|
||||
assert "settxfee " not in node.help() # An empty space is left after settxfee as if not would return True because of settxfeerate
|
||||
assert "settxfeerate" in node.help()
|
||||
assert "unknown command: settxfeerate" not in node.help("settxfeerate")
|
||||
assert "unknown command: settxfee" not in node.help("settxfee")
|
||||
|
||||
self.log.debug("Test that settxfee set the feerate in B/kvB")
|
||||
assert_equal(node.settxfee(0.001), True)
|
||||
assert_equal(str(node.getwalletinfo()['paytxfee']), "0.00100000")
|
||||
|
||||
self.log.debug("Test that settxfeerate set the feerate in sat/vB")
|
||||
assert_equal(node.settxfeerate(6), True)
|
||||
assert_equal(str(node.getwalletinfo()['paytxfee']), "0.00006000")
|
||||
|
||||
self.log.debug("Test that settxfee limit (0.1 B/kvB) can not be surpassed")
|
||||
assert_raises_rpc_error(-8, "txfee cannot be more than wallet max tx fee (0.10000000 BTC/kvB)", node.settxfee, 1)
|
||||
|
||||
self.log.debug("Test that settxfeerate limit (10000 sat/vB) can not be surpassed")
|
||||
assert_raises_rpc_error(-8, "txfee cannot be more than wallet max tx fee (10000.000 sat/vB)", node.settxfeerate, 10001)
|
||||
|
||||
self.log.debug("Test that settxfee minimum (0.00001 B/kvB) can not be ignored")
|
||||
assert_raises_rpc_error(-8, "txfee cannot be less than min relay tx fee (0.00001000 BTC/kvB)", node.settxfee, 0.000009)
|
||||
|
||||
self.log.debug("Test that settxfeerate minimum (1 sat/vB) can not be ignored")
|
||||
assert_raises_rpc_error(-8, "txfee cannot be less than min relay tx fee (1.000 sat/vB)", node.settxfeerate, 0.99)
|
||||
|
||||
self.log.debug("Test that the feerate set using settxfee is used when creating transactions")
|
||||
expected_feerate = 0.001
|
||||
node.settxfee(expected_feerate)
|
||||
txid = node.sendtoaddress(node.getnewaddress(), 10)
|
||||
fee = Decimal(node.gettransaction(txid)['fee'] * -1)
|
||||
vsize = Decimal(node.getrawtransaction(txid, 1)['vsize']/1000)
|
||||
feerate = Decimal(fee/vsize)
|
||||
feerate = feerate.quantize(Decimal("0.00000001"))
|
||||
expected_feerate = Decimal(expected_feerate).quantize(Decimal("0.00000001"))
|
||||
assert_equal(feerate, expected_feerate)
|
||||
|
||||
self.log.debug("Test that the feerate set using settxfeerate is used when creating transactions")
|
||||
expected_feerate = 6
|
||||
node.settxfeerate(expected_feerate)
|
||||
txid = node.sendtoaddress(node.getnewaddress(), 10)
|
||||
fee = Decimal(node.gettransaction(txid)['fee'] * -100000000)
|
||||
vsize = Decimal(node.getrawtransaction(txid, 1)['vsize'])
|
||||
feerate = Decimal(fee/vsize)
|
||||
feerate = feerate.quantize(Decimal("0.00000001"))
|
||||
expected_feerate = Decimal(expected_feerate).quantize(Decimal("0.00000001"))
|
||||
|
||||
self.log.debug("Test that settxfee is deprecated")
|
||||
assert_raises_rpc_error(-32, "Using settxfee is deprecated. Use settxfeerate instead or restart bitcoind with -deprecatedrpc=settxfee. This functionality will be removed in x.xx", self.nodes[1].settxfee, 0.05)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
RPCSetTxFeeTest(__file__).main()
|
|
@ -166,6 +166,7 @@ BASE_SCRIPTS = [
|
|||
'mempool_limit.py',
|
||||
'rpc_txoutproof.py',
|
||||
'rpc_orphans.py',
|
||||
'rpc_settxfeerate.py',
|
||||
'wallet_listreceivedby.py --legacy-wallet',
|
||||
'wallet_listreceivedby.py --descriptors',
|
||||
'wallet_abandonconflict.py --legacy-wallet',
|
||||
|
|
|
@ -35,7 +35,7 @@ class WalletTest(BitcoinTestFramework):
|
|||
# whitelist peers to speed up tx relay / mempool sync
|
||||
self.noban_tx_relay = True
|
||||
self.extra_args = [[
|
||||
"-dustrelayfee=0", "-walletrejectlongchains=0"
|
||||
"-dustrelayfee=0", "-walletrejectlongchains=0", "-deprecatedrpc=settxfee"
|
||||
]] * self.num_nodes
|
||||
self.setup_clean_chain = True
|
||||
self.supports_cli = False
|
||||
|
|
|
@ -61,6 +61,7 @@ class BumpFeeTest(BitcoinTestFramework):
|
|||
"-walletrbf={}".format(i),
|
||||
"-mintxfee=0.00002",
|
||||
"-addresstype=bech32",
|
||||
"-deprecatedrpc=settxfee"
|
||||
] for i in range(self.num_nodes)]
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
|
|
|
@ -23,6 +23,9 @@ class CreateTxWalletTest(BitcoinTestFramework):
|
|||
def set_test_params(self):
|
||||
self.setup_clean_chain = True
|
||||
self.num_nodes = 1
|
||||
self.extra_args = [[
|
||||
"-deprecatedrpc=settxfee"
|
||||
] for i in range(self.num_nodes)]
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
self.skip_if_no_wallet()
|
||||
|
|
|
@ -44,6 +44,9 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 4
|
||||
self.extra_args = [[
|
||||
"-deprecatedrpc=settxfee"
|
||||
] for i in range(self.num_nodes)]
|
||||
self.setup_clean_chain = True
|
||||
# whitelist peers to speed up tx relay / mempool sync
|
||||
self.noban_tx_relay = True
|
||||
|
|
|
@ -46,7 +46,7 @@ class MultiWalletTest(BitcoinTestFramework):
|
|||
self.setup_clean_chain = True
|
||||
self.num_nodes = 2
|
||||
self.rpc_timeout = 120
|
||||
self.extra_args = [["-nowallet"], []]
|
||||
self.extra_args = [["-nowallet", "-deprecatedrpc=settxfee"], ["-deprecatedrpc=settxfee"]]
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
self.skip_if_no_wallet()
|
||||
|
|
|
@ -18,6 +18,9 @@ class TxnMallTest(BitcoinTestFramework):
|
|||
def set_test_params(self):
|
||||
self.num_nodes = 3
|
||||
self.supports_cli = False
|
||||
self.extra_args = [[
|
||||
"-deprecatedrpc=settxfee"
|
||||
] for i in range(self.num_nodes)]
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
self.skip_if_no_wallet()
|
||||
|
|
Loading…
Add table
Reference in a new issue