wallet, rpc:remove settxfee and paytxfee
What changed, and why it matters
This commit removes two old Bitcoin Core fee-setting mechanisms: the command-line option `-paytxfee` and the RPC command `settxfee`. These had already been marked as deprecated. Users must now set fees per transaction using explicit options like `fee_rate` instead of a global default. There is no security vulnerability here; it is a planned API cleanup that may break old scripts or workflows that still rely on the removed options.
No security action required. Operators and integrators should update automation, configuration files, and user documentation to remove `-paytxfee` and `settxfee`, replacing them with per-transaction `fee_rate` parameters or fee-estimation targets. Test suites relying on these removed options will need the same migration shown in the diff.
Security signals we found
Removal of deprecated wallet fee configuration options
Simplification of fee-rate precedence logic in wallet fee calculation
Test-only changes: functional tests migrated from global settxfee/paytxfee to per-call fee_rate
No new cryptographic, network, or consensus code introduced
Evidence from the diff
The patch deletes the -paytxfee startup option, the settxfee RPC, the CWallet::m_pay_tx_fee member, and the FeeReason::PAYTXFEE enum value. Fee selection precedence in GetMinimumFeeRate is simplified to: coin-control feerate, then coin-control/smart estimation target. All functional tests are updated to pass explicit fee_rate arguments instead of relying on the removed global fee settings. The change is a hard removal (not merely another deprecation step) and will cause nodes/scripts using these options to fail at startup or RPC time.
Changed components
src/wallet/fees.cppsrc/wallet/wallet.cppsrc/wallet/wallet.hsrc/wallet/rpc/spend.cppsrc/wallet/rpc/wallet.cppsrc/wallet/init.cppsrc/qt/sendcoinsdialog.cppsrc/bitcoin-cli.cppsrc/common/messages.cppsrc/policy/fees/block_policy_estimator.htest/functional/wallet_basic.pytest/functional/wallet_bumpfee.pytest/functional/wallet_create_tx.pytest/functional/wallet_fundrawtransaction.pytest/functional/wallet_groups.pytest/functional/wallet_multiwallet.pytest/functional/wallet_txn_clone.pyInspect captured patch +118 / −255
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index 724620aa..909ed09f 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -367,7 +367,6 @@ struct GetinfoRequestHandler : BaseRequestHandler {
if (!batch[ID_WALLETINFO]["result"]["unlocked_until"].isNull()) {
result.pushKV("unlocked_until", batch[ID_WALLETINFO]["result"]["unlocked_until"]);
}
- result.pushKV("paytxfee", batch[ID_WALLETINFO]["result"]["paytxfee"]);
}
if (!batch[ID_BALANCES]["result"].isNull()) {
result.pushKV("balance", batch[ID_BALANCES]["result"]["mine"]["trusted"]);
@@ -1152,7 +1151,6 @@ static void ParseGetInfoResult(UniValue& result)
if (!result["unlocked_until"].isNull()) {
result_string += strprintf("Unlocked until: %s\n", result["unlocked_until"].getValStr());
}
- result_string += strprintf("Transaction fee rate (-paytxfee) (%s/kvB): %s\n\n", CURRENCY_UNIT, result["paytxfee"].getValStr());
}
if (!result["balance"].isNull()) {
result_string += strprintf("%sBalance:%s %s\n\n", CYAN, RESET, result["balance"].getValStr());
diff --git a/src/common/messages.cpp b/src/common/messages.cpp
index 123db93c..ec20eeb2 100644
--- a/src/common/messages.cpp
+++ b/src/common/messages.cpp
@@ -33,7 +33,6 @@ std::string StringForFeeReason(FeeReason reason)
{FeeReason::DOUBLE_ESTIMATE, "Double Target 95% Threshold"},
{FeeReason::CONSERVATIVE, "Conservative Double Target longer horizon"},
{FeeReason::MEMPOOL_MIN, "Mempool Min Fee"},
- {FeeReason::PAYTXFEE, "PayTxFee set"},
{FeeReason::FALLBACK, "Fallback fee"},
{FeeReason::REQUIRED, "Minimum Required Fee"},
};
diff --git a/src/dummywallet.cpp b/src/dummywallet.cpp
index 85fb1ed1..24952fea 100644
--- a/src/dummywallet.cpp
+++ b/src/dummywallet.cpp
@@ -38,7 +38,6 @@ void DummyWalletInit::AddWalletOptions(ArgsManager& argsman) const
"-maxapsfee=<n>",
"-maxtxfee=<amt>",
"-mintxfee=<amt>",
- "-paytxfee=<amt>",
"-signer=<cmd>",
"-spendzeroconfchange",
"-txconfirmtarget=<n>",
diff --git a/src/policy/fees/block_policy_estimator.h b/src/policy/fees/block_policy_estimator.h
index 505eed08..ae7b4406 100644
--- a/src/policy/fees/block_policy_estimator.h
+++ b/src/policy/fees/block_policy_estimator.h
@@ -64,7 +64,6 @@ enum class FeeReason {
DOUBLE_ESTIMATE,
CONSERVATIVE,
MEMPOOL_MIN,
- PAYTXFEE,
FALLBACK,
REQUIRED,
};
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index c475c6b7..3560ed22 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -40,7 +40,6 @@
using common::PSBTError;
using wallet::CCoinControl;
-using wallet::DEFAULT_PAY_TX_FEE;
static constexpr std::array confTargets{2, 4, 6, 12, 24, 48, 144, 504, 1008};
int getConfTargetForIndex(int index) {
@@ -125,8 +124,6 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *_platformStyle, QWidget *p
settings.setValue("nFeeRadio", 0); // recommended
if (!settings.contains("nSmartFeeSliderPosition"))
settings.setValue("nSmartFeeSliderPosition", 0);
- if (!settings.contains("nTransactionFee"))
- settings.setValue("nTransactionFee", (qint64)DEFAULT_PAY_TX_FEE);
ui->groupFee->setId(ui->radioSmartFee, 0);
ui->groupFee->setId(ui->radioCustomFee, 1);
ui->groupFee->button((int)std::max(0, std::min(1, settings.value("nFeeRadio").toInt())))->setChecked(true);
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index 77e5ec08..7398a8ed 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -79,7 +79,6 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "sendtoaddress", 8, "avoid_reuse" },
{ "sendtoaddress", 9, "fee_rate"},
{ "sendtoaddress", 10, "verbose"},
- { "settxfee", 0, "amount" },
{ "getreceivedbyaddress", 1, "minconf" },
{ "getreceivedbyaddress", 2, "include_immature_coinbase" },
{ "getreceivedbylabel", 0, "label", ParamFormat::STRING },
diff --git a/src/test/fuzz/fees.cpp b/src/test/fuzz/fees.cpp
index f295dd12..1bd5c67a 100644
--- a/src/test/fuzz/fees.cpp
+++ b/src/test/fuzz/fees.cpp
@@ -26,6 +26,6 @@ FUZZ_TARGET(fees)
const CAmount rounded_fee = fee_filter_rounder.round(current_minimum_fee);
assert(MoneyRange(rounded_fee));
}
- const FeeReason fee_reason = fuzzed_data_provider.PickValueInArray({FeeReason::NONE, FeeReason::HALF_ESTIMATE, FeeReason::FULL_ESTIMATE, FeeReason::DOUBLE_ESTIMATE, FeeReason::CONSERVATIVE, FeeReason::MEMPOOL_MIN, FeeReason::PAYTXFEE, FeeReason::FALLBACK, FeeReason::REQUIRED});
+ const FeeReason fee_reason = fuzzed_data_provider.PickValueInArray({FeeReason::NONE, FeeReason::HALF_ESTIMATE, FeeReason::FULL_ESTIMATE, FeeReason::DOUBLE_ESTIMATE, FeeReason::CONSERVATIVE, FeeReason::MEMPOOL_MIN, FeeReason::FALLBACK, FeeReason::REQUIRED});
(void)StringForFeeReason(fee_reason);
}
diff --git a/src/wallet/coincontrol.h b/src/wallet/coincontrol.h
index ead3307a..3d4fc2c0 100644
--- a/src/wallet/coincontrol.h
+++ b/src/wallet/coincontrol.h
@@ -93,7 +93,7 @@ public:
bool m_allow_other_inputs = true;
//! Override automatic min/max checks on fee, m_feerate must be set if true
bool fOverrideFeeRate = false;
- //! Override the wallet's m_pay_tx_fee if set
+ //! Override the wallet's fee rate if set
std::optional<CFeeRate> m_feerate;
//! Override the default confirmation target if set
std::optional<unsigned int> m_confirm_target;
diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp
index e63b9ae1..ff7a9f5a 100644
--- a/src/wallet/feebumper.cpp
+++ b/src/wallet/feebumper.cpp
@@ -61,7 +61,7 @@ static feebumper::Result CheckFeeRate(const CWallet& wallet, const CMutableTrans
{
// check that fee rate is higher than mempool's minimum fee
// (no point in bumping fee if we know that the new tx won't be accepted to the mempool)
- // This may occur if the user set fee_rate or paytxfee too low, if fallbackfee is too low, or, perhaps,
+ // This may occur if fallbackfee is too low, or, perhaps,
// in a rare situation where the mempool minimum fee increased significantly since the fee estimation just a
// moment earlier. In this case, we report an error to the user, who may adjust the fee.
CFeeRate minMempoolFeeRate = wallet.chain().mempoolMinFee();
diff --git a/src/wallet/fees.cpp b/src/wallet/fees.cpp
index a786062a..e2bb2227 100644
--- a/src/wallet/fees.cpp
+++ b/src/wallet/fees.cpp
@@ -31,22 +31,16 @@ CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_contr
/* User control of how to calculate fee uses the following parameter precedence:
1. coin_control.m_feerate
2. coin_control.m_confirm_target
- 3. m_pay_tx_fee (user-set member variable of wallet)
- 4. m_confirm_target (user-set member variable of wallet)
+ 3. m_confirm_target (user-set member variable of wallet)
The first parameter that is set is used.
*/
CFeeRate feerate_needed;
if (coin_control.m_feerate) { // 1.
feerate_needed = *(coin_control.m_feerate);
- if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE;
// Allow to override automatic min/max check over coin control instance
if (coin_control.fOverrideFeeRate) return feerate_needed;
}
- else if (!coin_control.m_confirm_target && wallet.m_pay_tx_fee != CFeeRate(0)) { // 3. TODO: remove magic value of 0 for wallet member m_pay_tx_fee
- feerate_needed = wallet.m_pay_tx_fee;
- if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE;
- }
- else { // 2. or 4.
+ else { // 2. or 3.
// We will use smart fee estimation
unsigned int target = coin_control.m_confirm_target ? *coin_control.m_confirm_target : wallet.m_confirm_target;
// By default estimates are economical iff we are signaling opt-in-RBF
diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp
index e2d47fb3..ccd82e7a 100644
--- a/src/wallet/init.cpp
+++ b/src/wallet/init.cpp
@@ -63,13 +63,11 @@ void WalletInit::AddWalletOptions(ArgsManager& argsman) const
CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MAXFEE)), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-mintxfee=<amt>", strprintf("Fee rates (in %s/kvB) smaller than this are considered zero fee for transaction creation (default: %s)",
CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE)), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
- argsman.AddArg("-paytxfee=<amt>", strprintf("(DEPRECATED) Fee rate (in %s/kvB) to add to transactions you send (default: %s)",
- CURRENCY_UNIT, FormatMoney(CFeeRate{DEFAULT_PAY_TX_FEE}.GetFeePerK())), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
#ifdef ENABLE_EXTERNAL_SIGNER
argsman.AddArg("-signer=<cmd>", "External signing tool, see doc/external-signer.md", ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
#endif
argsman.AddArg("-spendzeroconfchange", strprintf("Spend unconfirmed change when sending transactions (default: %u)", DEFAULT_SPEND_ZEROCONF_CHANGE), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
- argsman.AddArg("-txconfirmtarget=<n>", strprintf("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)", DEFAULT_TX_CONFIRM_TARGET), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
+ argsman.AddArg("-txconfirmtarget=<n>", strprintf("Include enough fee so transactions begin confirmation on average within n blocks (default: %u)", DEFAULT_TX_CONFIRM_TARGET), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
argsman.AddArg("-wallet=<path>", "Specify wallet path to load at startup. Can be used multiple times to load multiple wallets. Path is to a directory containing wallet data and log files. If the path is not absolute, it is interpreted relative to <walletdir>. This only loads existing wallets and does not create new ones. For backwards compatibility this also accepts names of existing top-level data files in <walletdir>.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::WALLET);
argsman.AddArg("-walletbroadcast", strprintf("Make the wallet broadcast transactions (default: %u)", DEFAULT_WALLETBROADCAST), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
argsman.AddArg("-walletdir=<dir>", "Specify directory to hold wallets (default: <datadir>/wallets if it exists, otherwise <datadir>)", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::WALLET);
diff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp
index 64cf95a4..3b67d7d4 100644
--- a/src/wallet/rpc/spend.cpp
+++ b/src/wallet/rpc/spend.cpp
@@ -427,54 +427,6 @@ RPCHelpMan sendmany()
};
}
-RPCHelpMan settxfee()
-{
- return RPCHelpMan{
- "settxfee",
- "(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"},
- },
- RPCResult{
- RPCResult::Type::BOOL, "", "Returns true if successful"
- },
- RPCExamples{
- HelpExampleCli("settxfee", "0.00001")
- + HelpExampleRpc("settxfee", "0.00001")
- },
- [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
-{
- std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
-
- LOCK(pwallet->cs_wallet);
-
- if (!pwallet->chain().rpcEnableDeprecated("settxfee")) {
- throw JSONRPCError(RPC_METHOD_DEPRECATED, "settxfee is deprecated and will be fully removed in v31.0."
- "\nTo use settxfee restart bitcoind with -deprecatedrpc=settxfee.");
- }
-
- CAmount nAmount = AmountFromValue(request.params[0]);
- 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()));
- } 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()));
- } 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()));
- }
-
- 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)
{
diff --git a/src/wallet/rpc/wallet.cpp b/src/wallet/rpc/wallet.cpp
index fc84b951..9ce27497 100644
--- a/src/wallet/rpc/wallet.cpp
+++ b/src/wallet/rpc/wallet.cpp
@@ -47,7 +47,6 @@ static RPCHelpMan getwalletinfo()
{RPCResult::Type::NUM, "keypoolsize", "how many new keys are pre-generated (only counts external keys)"},
{RPCResult::Type::NUM, "keypoolsize_hd_internal", /*optional=*/true, "how many new keys are pre-generated for internal use (used for change outputs, only appears if the wallet is using this feature, otherwise external keys are used)"},
{RPCResult::Type::NUM_TIME, "unlocked_until", /*optional=*/true, "the " + UNIX_EPOCH_TIME + " until which the wallet is unlocked for transfers, or 0 if the wallet is locked (only present for passphrase-encrypted wallets)"},
- {RPCResult::Type::STR_AMOUNT, "paytxfee", "the transaction fee configuration, set in " + CURRENCY_UNIT + "/kvB"},
{RPCResult::Type::BOOL, "private_keys_enabled", "false if privatekeys are disabled for this wallet (enforced watch-only wallet)"},
{RPCResult::Type::BOOL, "avoid_reuse", "whether this wallet tracks clean/dirty coins in terms of reuse"},
{RPCResult::Type::OBJ, "scanning", "current scanning details, or false if no scan is in progress",
@@ -96,7 +95,6 @@ static RPCHelpMan getwalletinfo()
if (pwallet->HasEncryptionKeys()) {
obj.pushKV("unlocked_until", pwallet->nRelockTime);
}
- obj.pushKV("paytxfee", ValueFromAmount(pwallet->m_pay_tx_fee.GetFeePerK()));
obj.pushKV("private_keys_enabled", !pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));
obj.pushKV("avoid_reuse", pwallet->IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE));
if (pwallet->IsScanning()) {
@@ -881,7 +879,6 @@ RPCHelpMan encryptwallet();
// spend
RPCHelpMan sendtoaddress();
RPCHelpMan sendmany();
-RPCHelpMan settxfee();
RPCHelpMan fundrawtransaction();
RPCHelpMan bumpfee();
RPCHelpMan psbtbumpfee();
@@ -951,7 +948,6 @@ std::span<const CRPCCommand> GetWalletRPCCommands()
{"wallet", &sendmany},
{"wallet", &sendtoaddress},
{"wallet", &setlabel},
- {"wallet", &settxfee},
{"wallet", &setwalletflag},
{"wallet", &signmessage},
{"wallet", &signrawtransactionwithwallet},
diff --git a/src/wallet/test/fuzz/fees.cpp b/src/wallet/test/fuzz/fees.cpp
index 6d9de0cc..5d6c67b7 100644
--- a/src/wallet/test/fuzz/fees.cpp
+++ b/src/wallet/test/fuzz/fees.cpp
@@ -98,7 +98,6 @@ FUZZ_TARGET(wallet_fees, .init = initialize_setup)
const auto tx_bytes{fuzzed_data_provider.ConsumeIntegralInRange(0, std::numeric_limits<int32_t>::max())};
if (fuzzed_data_provider.ConsumeBool()) {
- wallet.m_pay_tx_fee = CFeeRate{ConsumeMoney(fuzzed_data_provider, /*max=*/COIN)};
wallet.m_min_fee = CFeeRate{ConsumeMoney(fuzzed_data_provider, /*max=*/COIN)};
}
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index b1562952..63dab299 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -3027,27 +3027,6 @@ bool CWallet::LoadWalletArgs(std::shared_ptr<CWallet> wallet, const WalletContex
wallet->m_discard_rate = CFeeRate{discard_fee.value()};
}
- if (const auto arg{args.GetArg("-paytxfee")}) {
- warnings.push_back(_("-paytxfee is deprecated and will be fully removed in v31.0."));
-
- std::optional<CAmount> pay_tx_fee = ParseMoney(*arg);
- if (!pay_tx_fee) {
- error = AmountErrMsg("paytxfee", *arg);
- return false;
- } 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."));
- }
-
- wallet->m_pay_tx_fee = CFeeRate{pay_tx_fee.value(), 1000};
-
- if (chain && wallet->m_pay_tx_fee < chain->relayMinFee()) {
- error = strprintf(_("Invalid amount for %s=<amount>: '%s' (must be at least %s)"),
- "-paytxfee", *arg, chain->relayMinFee().ToString());
- return false;
- }
- }
-
if (const auto arg{args.GetArg("-maxtxfee")}) {
std::optional<CAmount> max_fee = ParseMoney(*arg);
if (!max_fee) {
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index ef5efa71..e3d36236 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -102,8 +102,6 @@ std::unique_ptr<interfaces::Handler> HandleLoadWallet(WalletContext& context, Lo
void NotifyWalletLoaded(WalletContext& context, const std::shared_ptr<CWallet>& wallet);
std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
-//! -paytxfee default
-constexpr CAmount DEFAULT_PAY_TX_FEE = 0;
//! -fallbackfee default
static const CAmount DEFAULT_FALLBACK_FEE = 0;
//! -discardfee default
@@ -705,14 +703,13 @@ public:
/** Updates wallet birth time if 'time' is below it */
void MaybeUpdateBirthTime(int64_t time);
- CFeeRate m_pay_tx_fee{DEFAULT_PAY_TX_FEE};
unsigned int m_confirm_target{DEFAULT_TX_CONFIRM_TARGET};
/** Allow Coin Selection to pick unconfirmed UTXOs that were sent from our own wallet if it
* cannot fund the transaction otherwise. */
bool m_spend_zero_conf_change{DEFAULT_SPEND_ZEROCONF_CHANGE};
bool m_signal_rbf{DEFAULT_WALLET_RBF};
bool m_allow_fallback_fee{true}; //!< will be false if -fallbackfee=0
- CFeeRate m_min_fee{DEFAULT_TRANSACTION_MINFEE}; //!< Override with -mintxfee
+ CFeeRate m_min_fee{DEFAULT_TRANSACTION_MINFEE};
/**
* If fee estimation does not have enough data to provide estimates, use this fee instead.
* Has no effect if not using fee estimation
diff --git a/test/functional/interface_bitcoin_cli.py b/test/functional/interface_bitcoin_cli.py
index 8b7c8616..f626ee51 100755
--- a/test/functional/interface_bitcoin_cli.py
+++ b/test/functional/interface_bitcoin_cli.py
@@ -249,7 +249,6 @@ class TestBitcoinCli(BitcoinTestFramework):
wallet_info = self.nodes[0].getwalletinfo()
assert_equal(int(cli_get_info['Keypool size']), wallet_info['keypoolsize'])
assert_equal(int(cli_get_info['Unlocked until']), wallet_info['unlocked_until'])
- assert_equal(Decimal(cli_get_info['Transaction fee rate (-paytxfee) (BTC/kvB)']), wallet_info['paytxfee'])
assert_equal(Decimal(cli_get_info['Min tx relay fee rate (BTC/kvB)']), network_info['relayfee'])
assert_equal(self.nodes[0].cli.getwalletinfo(), wallet_info)
diff --git a/test/functional/rpc_deprecated.py b/test/functional/rpc_deprecated.py
index acc3a05f..2f86954f 100755
--- a/test/functional/rpc_deprecated.py
+++ b/test/functional/rpc_deprecated.py
@@ -4,7 +4,6 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test deprecation of RPC calls."""
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import assert_raises_rpc_error
class DeprecatedRpcTest(BitcoinTestFramework):
def set_test_params(self):
@@ -27,12 +26,8 @@ class DeprecatedRpcTest(BitcoinTestFramework):
# Please don't delete nor modify this comment
self.log.info("Tests for deprecated RPC methods (if any)")
+ self.log.info("Currently no tests for deprecated RPC methods")
- if self.is_wallet_compiled():
- self.log.info("Tests for deprecated wallet-related RPC methods (if any)")
- self.log.info("Test settxfee RPC deprecation")
- self.nodes[0].createwallet("settxfeerpc")
- assert_raises_rpc_error(-32, 'settxfee is deprecated and will be fully removed in v31.0.', self.nodes[0].settxfee, 0.01)
if __name__ == '__main__':
DeprecatedRpcTest(__file__).main()
diff --git a/test/functional/rpc_getblockstats.py b/test/functional/rpc_getblockstats.py
index 29d70a05..35d43c4c 100755
--- a/test/functional/rpc_getblockstats.py
+++ b/test/functional/rpc_getblockstats.py
@@ -55,10 +55,10 @@ class GetblockstatsTest(BitcoinTestFramework):
self.nodes[0].sendtoaddress(address=address, amount=10, subtractfeefromamount=True)
self.nodes[0].sendtoaddress(address=address, amount=10, subtractfeefromamount=False)
- self.nodes[0].settxfee(amount=0.003)
- self.nodes[0].sendtoaddress(address=address, amount=1, subtractfeefromamount=True)
+ self.fee_rate=300
+ self.nodes[0].sendtoaddress(address=address, amount=1, subtractfeefromamount=True, fee_rate=self.fee_rate)
# Send to OP_RETURN output to test its exclusion from statistics
- self.nodes[0].send(outputs={"data": "21"})
+ self.nodes[0].send(outputs={"data": "21"}, fee_rate=self.fee_rate)
self.sync_all()
self.generate(self.nodes[0], 1)
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index 6039e308..e7a333ba 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -32,7 +32,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", "-deprecatedrpc=settxfee"
+ "-dustrelayfee=0", "-walletrejectlongchains=0"
]] * self.num_nodes
self.setup_clean_chain = True
self.supports_cli = False
@@ -240,14 +240,14 @@ class WalletTest(BitcoinTestFramework):
# Send 10 BTC normal
address = self.nodes[0].getnewaddress("test")
fee_per_byte = Decimal('0.001') / 1000
- self.nodes[2].settxfee(fee_per_byte * 1000)
- txid = self.nodes[2].sendtoaddress(address, 10, "", "", False)
+ fee_rate_sat_vb = fee_per_byte * Decimal(1e8)
+ txid = self.nodes[2].sendtoaddress(address, 10, "", "", False, fee_rate=fee_rate_sat_vb)
self.generate(self.nodes[2], 1, sync_fun=lambda: self.sync_all(self.nodes[0:3]))
node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), Decimal('84'), fee_per_byte, self.get_vsize(self.nodes[2].gettransaction(txid)['hex']))
assert_equal(self.nodes[0].getbalance(), Decimal('10'))
# Send 10 BTC with subtract fee from amount
- txid = self.nodes[2].sendtoaddress(address, 10, "", "", True)
+ txid = self.nodes[2].sendtoaddress(address, 10, "", "", True, fee_rate=fee_rate_sat_vb)
self.generate(self.nodes[2], 1, sync_fun=lambda: self.sync_all(self.nodes[0:3]))
node_2_bal -= Decimal('10')
assert_equal(self.nodes[2].getbalance(), node_2_bal)
@@ -256,14 +256,14 @@ class WalletTest(BitcoinTestFramework):
self.log.info("Test sendmany")
# Sendmany 10 BTC
- txid = self.nodes[2].sendmany('', {address: 10}, 0, "", [])
+ txid = self.nodes[2].sendmany('', {address: 10}, 0, "", [], fee_rate=fee_rate_sat_vb)
self.generate(self.nodes[2], 1, sync_fun=lambda: self.sync_all(self.nodes[0:3]))
node_0_bal += Decimal('10')
node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), node_2_bal - Decimal('10'), fee_per_byte, self.get_vsize(self.nodes[2].gettransaction(txid)['hex']))
assert_equal(self.nodes[0].getbalance(), node_0_bal)
# Sendmany 10 BTC with subtract fee from amount
- txid = self.nodes[2].sendmany('', {address: 10}, 0, "", [address])
+ txid = self.nodes[2].sendmany('', {address: 10}, 0, "", [address], fee_rate=fee_rate_sat_vb)
self.generate(self.nodes[2], 1, sync_fun=lambda: self.sync_all(self.nodes[0:3]))
node_2_bal -= Decimal('10')
assert_equal(self.nodes[2].getbalance(), node_2_bal)
@@ -272,7 +272,7 @@ class WalletTest(BitcoinTestFramework):
# Sendmany 5 BTC to two addresses with subtracting fee from both addresses
a0 = self.nodes[0].getnewaddress()
a1 = self.nodes[0].getnewaddress()
- txid = self.nodes[2].sendmany(dummy='', amounts={a0: 5, a1: 5}, subtractfeefrom=[a0, a1])
+ txid = self.nodes[2].sendmany(dummy='', amounts={a0: 5, a1: 5}, subtractfeefrom=[a0, a1], fee_rate=fee_rate_sat_vb)
self.generate(self.nodes[2], 1, sync_fun=lambda: self.sync_all(self.nodes[0:3]))
node_2_bal -= Decimal('10')
assert_equal(self.nodes[2].getbalance(), node_2_bal)
diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py
index 044ddc96..cc287430 100755
--- a/test/functional/wallet_bumpfee.py
+++ b/test/functional/wallet_bumpfee.py
@@ -59,7 +59,6 @@ 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):
@@ -105,7 +104,6 @@ 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_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
test_small_output_with_feerate_succeeds(self, rbf_node, dest_address)
@@ -532,31 +530,6 @@ def test_dust_to_fee(self, rbf_node, dest_address):
assert_equal(full_bumped_tx["vout"][0]['value'], Decimal("0.00050000"))
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.0000005'))
- assert_raises_rpc_error(-8, "txfee cannot be less than wallet min fee", rbf_node.settxfee, Decimal('0.000015'))
- # check that bumpfee reacts correctly to the use of settxfee (paytxfee)
- rbfid = spend_one_input(rbf_node, dest_address)
- requested_feerate = Decimal("0.00025000")
- rbf_node.settxfee(requested_feerate)
- bumped_tx = rbf_node.bumpfee(rbfid)
- actual_feerate = bumped_tx["fee"] * 1000 / rbf_node.getrawtransaction(bumped_tx["txid"], True)["vsize"]
- # Assert that the difference between the requested feerate and the actual
- # feerate of the bumped transaction is small.
- assert_greater_than(Decimal("0.00001000"), abs(requested_feerate - actual_feerate))
- rbf_node.settxfee(Decimal("0.00000000")) # unset paytxfee
-
- # check that settxfee respects -maxtxfee
- self.restart_node(1, ['-maxtxfee=0.000025'] + self.extra_args[1])
- assert_raises_rpc_error(-8, "txfee cannot be more than wallet max tx fee", rbf_node.settxfee, Decimal('0.00003'))
- 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_maxtxfee_fails(self, rbf_node, dest_address):
self.log.info('Test that bumpfee fails when it hits -maxtxfee')
# size of bumped transaction (p2wpkh, 1 input, 2 outputs): 141 vbytes
diff --git a/test/functional/wallet_create_tx.py b/test/functional/wallet_create_tx.py
index 03bc6046..a6275976 100755
--- a/test/functional/wallet_create_tx.py
+++ b/test/functional/wallet_create_tx.py
@@ -15,12 +15,13 @@ from test_framework.blocktools import (
TIME_GENESIS_BLOCK,
)
+from decimal import Decimal
class CreateTxWalletTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
- self.extra_args = [["-deprecatedrpc=settxfee"]]
+ self.extra_args = [[]]
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
@@ -54,7 +55,7 @@ class CreateTxWalletTest(BitcoinTestFramework):
outputs = {self.nodes[0].getnewaddress(address_type='bech32'): 0.000025 for _ in range(400)}
raw_tx = self.nodes[0].createrawtransaction(inputs=[], outputs=outputs)
- for fee_setting in ['-minrelaytxfee=0.01', '-mintxfee=0.01', '-paytxfee=0.01']:
+ for fee_setting in ['-minrelaytxfee=0.01', '-mintxfee=0.01']:
self.log.info('Check maxtxfee in combination with {}'.format(fee_setting))
self.restart_node(0, extra_args=[fee_setting])
assert_raises_rpc_error(
@@ -68,20 +69,21 @@ class CreateTxWalletTest(BitcoinTestFramework):
lambda: self.nodes[0].fundrawtransaction(hexstring=raw_tx),
)
- self.log.info('Check maxtxfee in combination with settxfee')
- self.restart_node(0, expected_stderr='Warning: -paytxfee is deprecated and will be fully removed in v31.0.')
- self.nodes[0].settxfee(0.01)
+ # Hit maxtxfee with explicit fee rate
+ self.log.info('Check maxtxfee in combination with explicit fee_rate=1000 sat/vB')
+
+ fee_rate_sats_per_vb = Decimal('0.01') * Decimal(1e8) / 1000 # Convert 0.01 BTC/kvB to sat/vB
+
assert_raises_rpc_error(
-6,
"Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)",
- lambda: self.nodes[0].sendmany(dummy="", amounts=outputs),
+ lambda: self.nodes[0].sendmany(dummy="", amounts=outputs, fee_rate=fee_rate_sats_per_vb),
)
assert_raises_rpc_error(
-4,
"Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)",
- lambda: self.nodes[0].fundrawtransaction(hexstring=raw_tx),
+ lambda: self.nodes[0].fundrawtransaction(hexstring=raw_tx, options={'fee_rate': fee_rate_sats_per_vb}),
)
- self.nodes[0].settxfee(0)
def test_create_too_long_mempool_chain(self):
self.log.info('Check too-long mempool chain error')
diff --git a/test/functional/wallet_fundrawtransaction.py b/test/functional/wallet_fundrawtransaction.py
index 3577a2f4..1fb14800 100755
--- a/test/functional/wallet_fundrawtransaction.py
+++ b/test/functional/wallet_fundrawtransaction.py
@@ -43,9 +43,9 @@ class RawTransactionsTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 4
self.extra_args = [[
- "-deprecatedrpc=settxfee",
"-minrelaytxfee=0.00001000",
] 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
@@ -100,8 +100,7 @@ class RawTransactionsTest(BitcoinTestFramework):
self.min_relay_tx_fee = self.nodes[0].getnetworkinfo()['relayfee']
# This test is not meant to test fee estimation and we'd like
# to be sure all txs are sent at a consistent desired feerate
- for node in self.nodes:
- node.settxfee(self.min_relay_tx_fee)
+ self.fee_rate_sats_per_vb = self.min_relay_tx_fee * Decimal(1e8) / 1000
# if the fee's positive delta is higher than this value tests will fail,
# neg. delta always fail the tests.
@@ -162,7 +161,7 @@ class RawTransactionsTest(BitcoinTestFramework):
w = self.nodes[1].get_wallet_rpc("fundtx_duplicate_outputs")
addr = w.getnewaddress(address_type="bech32")
- self.nodes[0].sendtoaddress(addr, 5)
+ self.nodes[0].sendtoaddress(addr, 5, fee_rate=self.fee_rate_sats_per_vb)
self.generate(self.nodes[0], 1)
address = self.nodes[0].getnewaddress("bech32")
@@ -171,14 +170,14 @@ class RawTransactionsTest(BitcoinTestFramework):
tx.vout = [CTxOut(1 * COIN, bytearray(address_to_scriptpubkey(address)))] * 2
tx.nLockTime = 0
tx_hex = tx.serialize().hex()
- res = w.fundrawtransaction(tx_hex, add_inputs=True)
+ res = w.fundrawtransaction(tx_hex, add_inputs=True, fee_rate=self.fee_rate_sats_per_vb)
signed_res = w.signrawtransactionwithwallet(res["hex"])
txid = w.sendrawtransaction(signed_res["hex"])
assert self.nodes[1].getrawtransaction(txid)
self.log.info("Test SFFO with duplicate outputs")
- res_sffo = w.fundrawtransaction(tx_hex, add_inputs=True, subtractFeeFromOutputs=[0,1])
+ res_sffo = w.fundrawtransaction(tx_hex, add_inputs=True, subtractFeeFromOutputs=[0,1], fee_rate=self.fee_rate_sats_per_vb)
signed_res_sffo = w.signrawtransactionwithwallet(res_sffo["hex"])
txid_sffo = w.sendrawtransaction(signed_res_sffo["hex"])
assert self.nodes[1].getrawtransaction(txid_sffo)
@@ -187,7 +186,7 @@ class RawTransactionsTest(BitcoinTestFramework):
"""Ensure setting changePosition in fundraw with an exact match is handled properly."""
self.log.info("Test fundrawtxn changePosition option")
rawmatch = self.nodes[2].createrawtransaction([], {self.nodes[2].getnewaddress():50})
- rawmatch = self.nodes[2].fundrawtransaction(rawmatch, changePosition=1, subtractFeeFromOutputs=[0])
+ rawmatch = self.nodes[2].fundrawtransaction(rawmatch, changePosition=1, subtractFeeFromOutputs=[0], fee_rate=self.fee_rate_sats_per_vb)
assert_equal(rawmatch["changepos"], -1)
self.nodes[3].createwallet(wallet_name="wwatch", disable_private_keys=True)
@@ -201,11 +200,11 @@ class RawTransactionsTest(BitcoinTestFramework):
# Lock UTXO so nodes[0] doesn't accidentally spend it
self.nodes[0].lockunspent(False, [self.watchonly_utxo])
- self.nodes[0].sendtoaddress(self.nodes[3].get_wallet_rpc(self.default_wallet_name).getnewaddress(), self.watchonly_amount / 10)
+ self.nodes[0].sendtoaddress(self.nodes[3].get_wallet_rpc(self.default_wallet_name).getnewaddress(), self.watchonly_amount / 10, fee_rate=self.fee_rate_sats_per_vb)
- self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.5)
- self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0)
- self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 5.0)
+ self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.5, fee_rate=self.fee_rate_sats_per_vb)
+ self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0, fee_rate=self.fee_rate_sats_per_vb)
+ self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 5.0, fee_rate=self.fee_rate_sats_per_vb)
self.generate(self.nodes[0], 1)
@@ -216,7 +215,7 @@ class RawTransactionsTest(BitcoinTestFramework):
inputs = [ ]
outputs = { self.nodes[0].getnewaddress() : 1.0 }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
- rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
+ rawtxfund = self.nodes[2].fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb)
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
assert len(dec_tx['vin']) > 0 #test that we have enough inputs
@@ -225,7 +224,7 @@ class RawTransactionsTest(BitcoinTestFramework):
inputs = [ ]
outputs = { self.nodes[0].getnewaddress() : 2.2 }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
- rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
+ rawtxfund = self.nodes[2].fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb)
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
assert len(dec_tx['vin']) > 0 #test if we have enough inputs
assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '')
@@ -237,7 +236,7 @@ class RawTransactionsTest(BitcoinTestFramework):
outputs = { self.nodes[0].getnewaddress() : 2.6, self.nodes[1].getnewaddress() : 2.5 }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
- rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
+ rawtxfund = self.nodes[2].fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb)
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
assert len(dec_tx['vin']) > 0
@@ -253,7 +252,7 @@ class RawTransactionsTest(BitcoinTestFramework):
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
- rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
+ rawtxfund = self.nodes[2].fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb)
fee = rawtxfund['fee']
self.test_no_change_fee = fee # Use the same fee for the next tx
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
@@ -273,7 +272,7 @@ class RawTransactionsTest(BitcoinTestFramework):
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
- rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
+ rawtxfund = self.nodes[2].fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb)
fee = rawtxfund['fee']
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
totalOut = 0
@@ -322,7 +321,7 @@ class RawTransactionsTest(BitcoinTestFramework):
change = self.nodes[2].getnewaddress()
assert_raises_rpc_error(-8, "changePosition out of bounds", self.nodes[2].fundrawtransaction, rawtx, changeAddress=change, changePosition=2)
- rawtxfund = self.nodes[2].fundrawtransaction(rawtx, changeAddress=change, changePosition=0)
+ rawtxfund = self.nodes[2].fundrawtransaction(rawtx, changeAddress=change, changePosition=0, fee_rate=self.fee_rate_sats_per_vb)
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
out = dec_tx['vout'][0]
assert_equal(change, out['scriptPubKey']['address'])
@@ -336,7 +335,7 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
assert_raises_rpc_error(-3, "JSON value of type null is not of expected type string", self.nodes[2].fundrawtransaction, rawtx, change_type=None)
assert_raises_rpc_error(-5, "Unknown change type ''", self.nodes[2].fundrawtransaction, rawtx, change_type='')
- rawtx = self.nodes[2].fundrawtransaction(rawtx, change_type='bech32')
+ rawtx = self.nodes[2].fundrawtransaction(rawtx, change_type='bech32', fee_rate=self.fee_rate_sats_per_vb)
dec_tx = self.nodes[2].decoderawtransaction(rawtx['hex'])
assert_equal('witness_v0_keyhash', dec_tx['vout'][rawtx['changepos']]['scriptPubKey']['type'])
@@ -358,7 +357,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# Should fail without add_inputs:
assert_raises_rpc_error(-4, ERR_NOT_ENOUGH_PRESET_INPUTS, self.nodes[2].fundrawtransaction, rawtx, add_inputs=False)
# add_inputs is enabled by default
- rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
+ rawtxfund = self.nodes[2].fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb)
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
matchingOuts = 0
@@ -387,7 +386,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# Should fail without add_inputs:
assert_raises_rpc_error(-4, ERR_NOT_ENOUGH_PRESET_INPUTS, self.nodes[2].fundrawtransaction, rawtx, add_inputs=False)
- rawtxfund = self.nodes[2].fundrawtransaction(rawtx, add_inputs=True)
+ rawtxfund = self.nodes[2].fundrawtransaction(rawtx, add_inputs=True, fee_rate=self.fee_rate_sats_per_vb)
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
matchingOuts = 0
for out in dec_tx['vout']:
@@ -418,7 +417,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# Should fail without add_inputs:
assert_raises_rpc_error(-4, ERR_NOT_ENOUGH_PRESET_INPUTS, self.nodes[2].fundrawtransaction, rawtx, add_inputs=False)
- rawtxfund = self.nodes[2].fundrawtransaction(rawtx, add_inputs=True)
+ rawtxfund = self.nodes[2].fundrawtransaction(rawtx, add_inputs=True, fee_rate=self.fee_rate_sats_per_vb)
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
matchingOuts = 0
@@ -445,10 +444,10 @@ class RawTransactionsTest(BitcoinTestFramework):
inputs = []
outputs = {self.nodes[1].getnewaddress():1.1}
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
- fundedTx = self.nodes[0].fundrawtransaction(rawtx)
+ fundedTx = self.nodes[0].fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb)
# Create same transaction over sendtoaddress.
- txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1.1)
+ txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1.1, fee_rate=self.fee_rate_sats_per_vb)
signedFee = self.nodes[0].getmempoolentry(txId)['fees']['base']
# Compare fee.
@@ -471,10 +470,10 @@ class RawTransactionsTest(BitcoinTestFramework):
self.nodes[1].getnewaddress():0.3,
}
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
- fundedTx = self.nodes[0].fundrawtransaction(rawtx)
+ fundedTx = self.nodes[0].fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb)
# Create same transaction over sendtoaddress.
- txId = self.nodes[0].sendmany("", outputs)
+ txId = self.nodes[0].sendmany("", outputs, fee_rate=self.fee_rate_sats_per_vb)
signedFee = self.nodes[0].getmempoolentry(txId)['fees']['base']
# Compare fee.
@@ -498,10 +497,10 @@ class RawTransactionsTest(BitcoinTestFramework):
inputs = []
outputs = {mSigObj:1.1}
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
- fundedTx = self.nodes[0].fundrawtransaction(rawtx)
+ fundedTx = self.nodes[0].fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb)
# Create same transaction over sendtoaddress.
- txId = self.nodes[0].sendtoaddress(mSigObj, 1.1)
+ txId = self.nodes[0].sendtoaddress(mSigObj, 1.1, fee_rate=self.fee_rate_sats_per_vb)
signedFee = self.nodes[0].getmempoolentry(txId)['fees']['base']
# Compare fee.
@@ -542,10 +541,10 @@ class RawTransactionsTest(BitcoinTestFramework):
inputs = []
outputs = {mSigObj:1.1}
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
- fundedTx = self.nodes[0].fundrawtransaction(rawtx)
+ fundedTx = self.nodes[0].fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb)
# Create same transaction over sendtoaddress.
- txId = self.nodes[0].sendtoaddress(mSigObj, 1.1)
+ txId = self.nodes[0].sendtoaddress(mSigObj, 1.1, fee_rate=self.fee_rate_sats_per_vb)
signedFee = self.nodes[0].getmempoolentry(txId)['fees']['base']
# Compare fee.
@@ -579,7 +578,7 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(import_res[0]["success"], True)
# Send 1.2 BTC to msig addr.
- self.nodes[0].sendtoaddress(mSigObj["address"], 1.2)
+ self.nodes[0].sendtoaddress(mSigObj["address"], 1.2, fee_rate=self.fee_rate_sats_per_vb)
self.generate(self.nodes[0], 1)
oldBalance = self.nodes[1].getbalance()
@@ -602,8 +601,6 @@ class RawTransactionsTest(BitcoinTestFramework):
df_wallet = self.nodes[1].get_wallet_rpc(self.default_wallet_name)
self.nodes[1].createwallet(wallet_name="locked_wallet")
wallet = self.nodes[1].get_wallet_rpc("locked_wallet")
- # This test is not meant to exercise fee estimation. Making sure all txs are sent at a consistent fee rate.
- wallet.settxfee(self.min_relay_tx_fee)
# Add some balance to the wallet (this will be reverted at the end of the test)
df_wallet.sendall(recipients=[wallet.getnewaddress()])
@@ -639,7 +636,7 @@ class RawTransactionsTest(BitcoinTestFramework):
outputs = {self.nodes[0].getnewaddress():value}
rawtx = wallet.createrawtransaction(inputs, outputs)
# fund a transaction that does not require a new key for the change output
- funded_tx = wallet.fundrawtransaction(rawtx)
+ funded_tx = wallet.fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb)
assert_equal(funded_tx["changepos"], -1)
# fund a transaction that requires a new key for the change output
@@ -659,7 +656,8 @@ class RawTransactionsTest(BitcoinTestFramework):
inputs = []
outputs = {self.nodes[0].getnewaddress():1.1}
rawtx = wallet.createrawtransaction(inputs, outputs)
- fundedTx = wallet.fundrawtransaction(rawtx)
+
+ fundedTx = wallet.fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb)
assert_not_equal(fundedTx["changepos"], -1)
# Now we need to unlock.
@@ -672,7 +670,7 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(oldBalance+Decimal('51.10000000'), self.nodes[0].getbalance())
# Restore pre-test wallet state
- wallet.sendall(recipients=[df_wallet.getnewaddress(), df_wallet.getnewaddress(), df_wallet.getnewaddress()])
+ wallet.sendall(recipients=[df_wallet.getnewaddress(), df_wallet.getnewaddress(), df_wallet.getnewaddress()], fee_rate=self.fee_rate_sats_per_vb)
wallet.unloadwallet()
self.generate(self.nodes[1], 1)
@@ -681,21 +679,21 @@ class RawTransactionsTest(BitcoinTestFramework):
self.log.info("Test fundrawtxn fee with many inputs")
# Empty node1, send some small coins from node0 to node1.
- self.nodes[1].sendall(recipients=[self.nodes[0].getnewaddress()])
+ self.nodes[1].sendall(recipients=[self.nodes[0].getnewaddress()], fee_rate=self.fee_rate_sats_per_vb)
self.generate(self.nodes[1], 1)
for _ in range(20):
- self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01)
+ self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01, fee_rate=self.fee_rate_sats_per_vb)
self.generate(self.nodes[0], 1)
# Fund a tx with ~20 small inputs.
inputs = []
outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04}
rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
- fundedTx = self.nodes[1].fundrawtransaction(rawtx)
+ fundedTx = self.nodes[1].fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb)
# Create same transaction over sendtoaddress.
- txId = self.nodes[1].sendmany("", outputs)
+ txId = self.nodes[1].sendmany("", outputs, fee_rate=self.fee_rate_sats_per_vb)
signedFee = self.nodes[1].getmempoolentry(txId)['fees']['base']
# Compare fee.
@@ -707,11 +705,11 @@ class RawTransactionsTest(BitcoinTestFramework):
self.log.info("Test fundrawtxn sign+send with many inputs")
# Again, empty node1, send some small coins from node0 to node1.
- self.nodes[1].sendall(recipients=[self.nodes[0].getnewaddress()])
+ self.nodes[1].sendall(recipients=[self.nodes[0].getnewaddress()], fee_rate=self.fee_rate_sats_per_vb)
self.generate(self.nodes[1], 1)
for _ in range(20):
- self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01)
+ self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01, fee_rate=self.fee_rate_sats_per_vb)
self.generate(self.nodes[0], 1)
# Fund a tx with ~20 small inputs.
@@ -720,7 +718,7 @@ class RawTransactionsTest(BitcoinTestFramework):
inputs = []
outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04}
rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
- fundedTx = self.nodes[1].fundrawtransaction(rawtx)
+ fundedTx = self.nodes[1].fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb)
fundedAndSignedTx = self.nodes[1].signrawtransactionwithwallet(fundedTx['hex'])
self.nodes[1].sendrawtransaction(fundedAndSignedTx['hex'])
self.generate(self.nodes[1], 1)
@@ -735,7 +733,7 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(len(dec_tx['vin']), 0)
assert_equal(len(dec_tx['vout']), 1)
- rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
+ rawtxfund = self.nodes[2].fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb)
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
assert_greater_than(len(dec_tx['vin']), 0) # at least one vin
@@ -810,7 +808,7 @@ class RawTransactionsTest(BitcoinTestFramework):
outputs = {node.getnewaddress() : 1}
rawtx = node.createrawtransaction(inputs, outputs)
- result = node.fundrawtransaction(rawtx) # uses self.min_relay_tx_fee (set by settxfee)
+ result = node.fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb) # uses self.min_relay_tx_fee (set by fee_rate in sat/vB)
btc_kvb_to_sat_vb = 100000 # (1e5)
result1 = node.fundrawtransaction(rawtx, fee_rate=str(2 * btc_kvb_to_sat_vb * self.min_relay_tx_fee))
result2 = node.fundrawtransaction(rawtx, feeRate=2 * self.min_relay_tx_fee)
@@ -828,7 +826,7 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(self.nodes[3].fundrawtransaction(rawtx, {param: zero_value})["fee"], 0)
# With no arguments passed, expect fee of 141 satoshis.
- assert_approx(node.fundrawtransaction(rawtx)["fee"], vexp=0.00000141, vspan=0.00000001)
+ assert_approx(node.fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb)["fee"], vexp=0.00000141, vspan=0.00000001)
# Expect fee to be 10,000x higher when an explicit fee rate 10,000x greater is specified.
result = node.fundrawtransaction(rawtx, fee_rate=10000)
assert_approx(result["fee"], vexp=0.0141, vspan=0.0001)
@@ -916,9 +914,9 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
# Test subtract fee from outputs with feeRate (BTC/kvB)
- result = [self.nodes[3].fundrawtransaction(rawtx), # uses self.min_relay_tx_fee (set by settxfee)
- self.nodes[3].fundrawtransaction(rawtx, subtractFeeFromOutputs=[]), # empty subtraction list
- self.nodes[3].fundrawtransaction(rawtx, subtractFeeFromOutputs=[0]), # uses self.min_relay_tx_fee (set by settxfee)
+ result = [self.nodes[3].fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb),
+ self.nodes[3].fundrawtransaction(rawtx, subtractFeeFromOutputs=[], fee_rate=self.fee_rate_sats_per_vb), # empty subtraction list
+ self.nodes[3].fundrawtransaction(rawtx, subtractFeeFromOutputs=[0], fee_rate=self.fee_rate_sats_per_vb), # uses self.min_relay_tx_fee (set by fee_rate in sat/vB)
self.nodes[3].fundrawtransaction(rawtx, feeRate=2 * self.min_relay_tx_fee),
self.nodes[3].fundrawtransaction(rawtx, feeRate=2 * self.min_relay_tx_fee, subtractFeeFromOutputs=[0]),]
dec_tx = [self.nodes[3].decoderawtransaction(tx_['hex']) for tx_ in result]
@@ -936,9 +934,9 @@ class RawTransactionsTest(BitcoinTestFramework):
# Test subtract fee from outputs with fee_rate (sat/vB)
btc_kvb_to_sat_vb = 100000 # (1e5)
- result = [self.nodes[3].fundrawtransaction(rawtx), # uses self.min_relay_tx_fee (set by settxfee)
- self.nodes[3].fundrawtransaction(rawtx, subtractFeeFromOutputs=[]), # empty subtraction list
- self.nodes[3].fundrawtransaction(rawtx, subtractFeeFromOutputs=[0]), # uses self.min_relay_tx_fee (set by settxfee)
+ result = [self.nodes[3].fundrawtransaction(rawtx, fee_rate=self.fee_rate_sats_per_vb), # uses self.min_relay_tx_fee (set by fee_rate in sat/vB)
+ self.nodes[3].fundrawtransaction(rawtx, subtractFeeFromOutputs=[], fee_rate=self.fee_rate_sats_per_vb), # empty subtraction list
+ self.nodes[3].fundrawtransaction(rawtx, subtractFeeFromOutputs=[0], fee_rate=self.fee_rate_sats_per_vb), # uses self.min_relay_tx_fee (set by fee_rate in sat/vB)
self.nodes[3].fundrawtransaction(rawtx, fee_rate=2 * btc_kvb_to_sat_vb * self.min_relay_tx_fee),
self.nodes[3].fundrawtransaction(rawtx, fee_rate=2 * btc_kvb_to_sat_vb * self.min_relay_tx_fee, subtractFeeFromOutputs=[0]),]
dec_tx = [self.nodes[3].decoderawtransaction(tx_['hex']) for tx_ in result]
@@ -1001,7 +999,7 @@ class RawTransactionsTest(BitcoinTestFramework):
utxo = self.create_outpoints(self.nodes[0], outputs=[{addr: 10}])[0]
rawtx = self.nodes[0].createrawtransaction([utxo], [{self.nodes[0].getnewaddress(): 5}])
- fundedtx = self.nodes[0].fundrawtransaction(rawtx, subtractFeeFromOutputs=[0])
+ fundedtx = self.nodes[0].fundrawtransaction(rawtx, subtractFeeFromOutputs=[0], fee_rate=self.fee_rate_sats_per_vb)
signedtx = self.nodes[0].signrawtransactionwithwallet(fundedtx['hex'])
self.nodes[0].sendrawtransaction(signedtx['hex'])
@@ -1022,7 +1020,7 @@ class RawTransactionsTest(BitcoinTestFramework):
recipient.keypoolrefill(1500)
for _ in range(1500):
outputs[recipient.getnewaddress()] = 0.1
- wallet.sendmany("", outputs)
+ wallet.sendmany("", outputs, fee_rate=self.fee_rate_sats_per_vb)
self.generate(self.nodes[0], 10)
assert_raises_rpc_error(-4, "The inputs size exceeds the maximum weight. "
"Please try sending a smaller amount or manually consolidating your wallet's UTXOs",
@@ -1042,8 +1040,8 @@ class RawTransactionsTest(BitcoinTestFramework):
addr = self.nodes[0].deriveaddresses(desc)[0]
addr_info = self.nodes[0].getaddressinfo(addr)
- self.nodes[0].sendtoaddress(addr, 10)
- self.nodes[0].sendtoaddress(wallet.getnewaddress(), 10)
+ self.nodes[0].sendtoaddress(addr, 10, fee_rate=self.fee_rate_sats_per_vb)
+ self.nodes[0].sendtoaddress(wallet.getnewaddress(), 10, fee_rate=self.fee_rate_sats_per_vb)
self.generate(self.nodes[0], 6)
ext_utxo = self.nodes[0].listunspent(addresses=[addr])[0]
@@ -1070,7 +1068,7 @@ class RawTransactionsTest(BitcoinTestFramework):
signed_tx = self.nodes[0].signrawtransactionwithwallet(signed_tx['hex'])
assert signed_tx['complete']
- funded_tx = wallet.fundrawtransaction(raw_tx, solving_data={"descriptors": [desc]})
+ funded_tx = wallet.fundrawtransaction(raw_tx, solving_data={"descriptors": [desc]}, fee_rate=self.fee_rate_sats_per_vb)
signed_tx1 = wallet.signrawtransactionwithwallet(funded_tx['hex'])
assert not signed_tx1['complete']
signed_tx2 = self.nodes[0].signrawtransactionwithwallet(signed_tx1['hex'])
@@ -1119,7 +1117,7 @@ class RawTransactionsTest(BitcoinTestFramework):
self.nodes[2].createwallet("test_preset_inputs")
wallet = self.nodes[2].get_wallet_rpc("test_preset_inputs")
addr1 = wallet.getnewaddress(address_type="bech32")
- self.nodes[0].sendtoaddress(addr1, 5)
+ self.nodes[0].sendtoaddress(addr1, 5, fee_rate=self.fee_rate_sats_per_vb)
self.generate(self.nodes[0], 1)
# Covered cases:
@@ -1139,7 +1137,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# Case (1), 'send' command
# 'add_inputs' value is true unless "inputs" are specified, in such case, add_inputs=false.
# So, the wallet will automatically select coins and create the transaction if only the outputs are provided.
- tx = wallet.send(outputs=[{addr1: 3}])
+ tx = wallet.send(outputs=[{addr1: 3}], fee_rate=self.fee_rate_sats_per_vb)
assert tx["complete"]
# Case (2), 'send' command
@@ -1148,7 +1146,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# Fund wallet with 2 outputs, 5 BTC each.
addr2 = wallet.getnewaddress(address_type="bech32")
- source_tx = self.nodes[0].send(outputs=[{addr1: 5}, {addr2: 5}], change_position=0)
+ source_tx = self.nodes[0].send(outputs=[{addr1: 5}, {addr2: 5}], change_position=0, fee_rate=self.fee_rate_sats_per_vb)
self.generate(self.nodes[0], 1)
# Select only one input.
@@ -1165,6 +1163,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# Case (3), Explicit add_inputs=true and preset inputs (with preset inputs not-covering the target amount)
options["add_inputs"] = True
options["add_to_wallet"] = False
+ options["fee_rate"] = self.fee_rate_sats_per_vb
tx = wallet.send(outputs=[{addr1: 8}], **options)
assert tx["complete"]
@@ -1196,7 +1195,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# Default add_inputs value with no preset inputs (add_inputs=true)
inputs = []
outputs = {self.nodes[1].getnewaddress(): 8}
- assert "psbt" in wallet.walletcreatefundedpsbt(inputs=inputs, outputs=outputs)
+ assert "psbt" in wallet.walletcreatefundedpsbt(inputs=inputs, outputs=outputs, options={'fee_rate': self.fee_rate_sats_per_vb})
# Case (2), 'walletcreatefundedpsbt' command
# Default add_inputs value with preset inputs (add_inputs=false).
@@ -1205,7 +1204,7 @@ class RawTransactionsTest(BitcoinTestFramework):
"vout": 1 # change position was hardcoded to index 0
}]
outputs = {self.nodes[1].getnewaddress(): 8}
- assert_raises_rpc_error(-4, ERR_NOT_ENOUGH_PRESET_INPUTS, wallet.walletcreatefundedpsbt, inputs=inputs, outputs=outputs)
+ assert_raises_rpc_error(-4, ERR_NOT_ENOUGH_PRESET_INPUTS, wallet.walletcreatefundedpsbt, inputs=inputs, outputs=outputs, options={'fee_rate': self.fee_rate_sats_per_vb})
# Case (3), Explicit add_inputs=true and preset inputs (with preset inputs not-covering the target amount)
options["add_inputs"] = True
@@ -1226,7 +1225,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# Case (5), 'walletcreatefundedpsbt' command
# Explicit add_inputs=true, no preset inputs
options = {
- "add_inputs": True
+ "add_inputs": True,
}
assert "psbt" in wallet.walletcreatefundedpsbt(inputs=[], outputs=outputs, **options)
@@ -1245,7 +1244,7 @@ class RawTransactionsTest(BitcoinTestFramework):
outputs = {}
for _ in range(4):
outputs[wallet.getnewaddress(address_type="bech32")] = 5
- self.nodes[0].sendmany("", outputs)
+ self.nodes[0].sendmany("", outputs, fee_rate=self.fee_rate_sats_per_vb)
self.generate(self.nodes[0], 1)
# Select the preset inputs
@@ -1257,7 +1256,8 @@ class RawTransactionsTest(BitcoinTestFramework):
"inputs": preset_inputs,
"add_inputs": True, # automatically add coins from the wallet to fulfill the target
"subtract_fee_from_outputs": [0], # deduct fee from first output
- "add_to_wallet": False
+ "add_to_wallet": False,
+ "fee_rate": self.fee_rate_sats_per_vb
}
# Attempt to send 29 BTC from a wallet that only has 20 BTC. The wallet should exclude
@@ -1290,7 +1290,7 @@ class RawTransactionsTest(BitcoinTestFramework):
ext_addr = self.nodes[0].getnewaddress(address_type="bech32")
utxo, ext_utxo = self.create_outpoints(self.nodes[0], outputs=[{addr: 5}, {ext_addr: 5}])
- self.nodes[0].sendtoaddress(wallet.getnewaddress(address_type="bech32"), 5)
+ self.nodes[0].sendtoaddress(wallet.getnewaddress(address_type="bech32"), 5, fee_rate=self.fee_rate_sats_per_vb)
self.generate(self.nodes[0], 1)
rawtx = wallet.createrawtransaction([utxo], [{self.nodes[0].getnewaddress(address_type="bech32"): 8}])
@@ -1319,7 +1319,7 @@ class RawTransactionsTest(BitcoinTestFramework):
outputs = []
for _ in range(1472):
outputs.append({wallet.getnewaddress(address_type="legacy"): 0.1})
- txid = self.nodes[0].send(outputs=outputs, change_position=0)["txid"]
+ txid = self.nodes[0].send(outputs=outputs, change_position=0, fee_rate=self.fee_rate_sats_per_vb)["txid"]
self.generate(self.nodes[0], 1)
# 272 WU per input (273 when high-s); picking 1471 inputs will exceed the max standard tx weight.
@@ -1361,7 +1361,7 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_raises_rpc_error(-4, "Insufficient funds", wallet.fundrawtransaction, rawtx)
# But we can opt-in to use them for funding.
- fundedtx = wallet.fundrawtransaction(rawtx, include_unsafe=True)
+ fundedtx = wallet.fundrawtransaction(rawtx, include_unsafe=True, fee_rate=self.fee_rate_sats_per_vb)
tx_dec = wallet.decoderawtransaction(fundedtx['hex'])
assert all((txin["txid"], txin["vout"]) in inputs for txin in tx_dec["vin"])
signedtx = wallet.signrawtransactionwithwallet(fundedtx['hex'])
@@ -1369,7 +1369,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# And we can also use them once they're confirmed.
self.generate(self.nodes[0], 1)
- fundedtx = wallet.fundrawtransaction(rawtx, include_unsafe=False)
+ fundedtx = wallet.fundrawtransaction(rawtx, include_unsafe=False, fee_rate=self.fee_rate_sats_per_vb)
tx_dec = wallet.decoderawtransaction(fundedtx['hex'])
assert all((txin["txid"], txin["vout"]) in inputs for txin in tx_dec["vin"])
signedtx = wallet.signrawtransactionwithwallet(fundedtx['hex'])
@@ -1443,7 +1443,7 @@ class RawTransactionsTest(BitcoinTestFramework):
w = self.nodes[1].get_wallet_rpc("roundtest")
addr = w.getnewaddress(address_type="bech32")
- self.nodes[0].sendtoaddress(addr, 1)
+ self.nodes[0].sendtoaddress(addr, 1, fee_rate=self.fee_rate_sats_per_vb)
self.generate(self.nodes[0], 1)
# A P2WPKH input costs 68 vbytes; With a single P2WPKH output, the rest of the tx is 42 vbytes for a total of 110 vbytes.
@@ -1464,10 +1464,10 @@ class RawTransactionsTest(BitcoinTestFramework):
# Fund the wallet with different chain heights
for _ in range(2):
- self.nodes[2].sendmany("", {wallet.getnewaddress():1, wallet.getnewaddress():1})
+ self.nodes[2].sendmany("", {wallet.getnewaddress():1, wallet.getnewaddress():1}, fee_rate=self.fee_rate_sats_per_vb)
self.generate(self.nodes[2], 1)
- unconfirmed_txid = wallet.sendtoaddress(wallet.getnewaddress(), 0.5)
+ unconfirmed_txid = wallet.sendtoaddress(wallet.getnewaddress(), 0.5, fee_rate=self.fee_rate_sats_per_vb)
self.log.info("Crafting TX using an unconfirmed input")
target_address = self.nodes[2].getnewaddress()
diff --git a/test/functional/wallet_groups.py b/test/functional/wallet_groups.py
index 0bc8838a..b47fc3a2 100755
--- a/test/functional/wallet_groups.py
+++ b/test/functional/wallet_groups.py
@@ -29,8 +29,7 @@ class WalletGroupTest(BitcoinTestFramework):
["-maxapsfee=0.00002720"],
]
- for args in self.extra_args:
- args.append(f"-paytxfee={20 * 1e3 / 1e8}") # apply feerate of 20 sats/vB across all nodes
+ self.fee_rate = 20 # apply feerate of 20 sats/vB across all nodes
self.rpc_timeout = 480
@@ -48,8 +47,8 @@ class WalletGroupTest(BitcoinTestFramework):
addrs = addr1 + addr2
# Send 1 + 0.5 coin to each address
- [self.nodes[0].sendtoaddress(addr, 1.0) for addr in addrs]
- [self.nodes[0].sendtoaddress(addr, 0.5) for addr in addrs]
+ [self.nodes[0].sendtoaddress(addr, 1.0, fee_rate=self.fee_rate) for addr in addrs]
+ [self.nodes[0].sendtoaddress(addr, 0.5, fee_rate=self.fee_rate) for addr in addrs]
self.generate(self.nodes[0], 1)
@@ -58,7 +57,7 @@ class WalletGroupTest(BitcoinTestFramework):
# - node[2] should pick one (1.0 + 0.5) UTXO group corresponding to a
# given address, and leave the rest
self.log.info("Test sending transactions picks one UTXO group and leaves the rest")
- txid1 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 0.2)
+ txid1 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 0.2, fee_rate=self.fee_rate)
tx1 = self.nodes[1].getrawtransaction(txid1, True)
# txid1 should have 1 input and 2 outputs
assert_equal(1, len(tx1["vin"]))
@@ -69,7 +68,7 @@ class WalletGroupTest(BitcoinTestFramework):
assert_approx(v[0], vexp=0.2, vspan=0.0001)
assert_approx(v[1], vexp=0.3, vspan=0.0001)
- txid2 = self.nodes[2].sendtoaddress(self.nodes[0].getnewaddress(), 0.2)
+ txid2 = self.nodes[2].sendtoaddress(self.nodes[0].getnewaddress(), 0.2, fee_rate=self.fee_rate)
tx2 = self.nodes[2].getrawtransaction(txid2, True)
# txid2 should have 2 inputs and 2 outputs
assert_equal(2, len(tx2["vin"]))
@@ -97,7 +96,7 @@ class WalletGroupTest(BitcoinTestFramework):
# this could be (A / B0 / C0) + (B1 / C1 / D). We ensure that it is
# B0 + B1 or C0 + C1, because this avoids partial spends while not being
# detrimental to transaction cost
- txid3 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.4)
+ txid3 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.4, fee_rate=self.fee_rate)
tx3 = self.nodes[1].getrawtransaction(txid3, True)
# tx3 should have 2 inputs and 2 outputs
assert_equal(2, len(tx3["vin"]))
@@ -121,11 +120,11 @@ class WalletGroupTest(BitcoinTestFramework):
self.log.info("Test wallet option maxapsfee")
addr_aps = self.nodes[3].getnewaddress()
- self.nodes[0].sendtoaddress(addr_aps, 1.0)
- self.nodes[0].sendtoaddress(addr_aps, 1.0)
+ self.nodes[0].sendtoaddress(addr_aps, 1.0, fee_rate=self.fee_rate)
+ self.nodes[0].sendtoaddress(addr_aps, 1.0, fee_rate=self.fee_rate)
self.generate(self.nodes[0], 1)
with self.nodes[3].assert_debug_log([f'Fee non-grouped = {tx4_ungrouped_fee}, grouped = {tx4_grouped_fee}, using grouped']):
- txid4 = self.nodes[3].sendtoaddress(self.nodes[0].getnewaddress(), 0.1)
+ txid4 = self.nodes[3].sendtoaddress(self.nodes[0].getnewaddress(), 0.1, fee_rate=self.fee_rate)
tx4 = self.nodes[3].getrawtransaction(txid4, True)
# tx4 should have 2 inputs and 2 outputs although one output would
# have been enough and the transaction caused higher fees
@@ -133,10 +132,10 @@ class WalletGroupTest(BitcoinTestFramework):
assert_equal(2, len(tx4["vout"]))
addr_aps2 = self.nodes[3].getnewaddress()
- [self.nodes[0].sendtoaddress(addr_aps2, 1.0) for _ in range(5)]
+ [self.nodes[0].sendtoaddress(addr_aps2, 1.0, fee_rate=self.fee_rate) for _ in range(5)]
self.generate(self.nodes[0], 1)
with self.nodes[3].assert_debug_log([f'Fee non-grouped = {tx5_6_ungrouped_fee}, grouped = {tx5_6_grouped_fee}, using non-grouped']):
- txid5 = self.nodes[3].sendtoaddress(self.nodes[0].getnewaddress(), 2.95)
+ txid5 = self.nodes[3].sendtoaddress(self.nodes[0].getnewaddress(), 2.95, fee_rate=self.fee_rate)
tx5 = self.nodes[3].getrawtransaction(txid5, True)
# tx5 should have 3 inputs (1.0, 1.0, 1.0) and 2 outputs
assert_equal(3, len(tx5["vin"]))
@@ -146,10 +145,10 @@ class WalletGroupTest(BitcoinTestFramework):
# 1 sat higher, crossing the threshold from non-grouped to grouped.
self.log.info("Test wallet option maxapsfee threshold from non-grouped to grouped")
addr_aps3 = self.nodes[4].getnewaddress()
- [self.nodes[0].sendtoaddress(addr_aps3, 1.0) for _ in range(5)]
+ [self.nodes[0].sendtoaddress(addr_aps3, 1.0, fee_rate=self.fee_rate) for _ in range(5)]
self.generate(self.nodes[0], 1)
with self.nodes[4].assert_debug_log([f'Fee non-grouped = {tx5_6_ungrouped_fee}, grouped = {tx5_6_grouped_fee}, using grouped']):
- txid6 = self.nodes[4].sendtoaddress(self.nodes[0].getnewaddress(), 2.95)
+ txid6 = self.nodes[4].sendtoaddress(self.nodes[0].getnewaddress(), 2.95, fee_rate=self.fee_rate)
tx6 = self.nodes[4].getrawtransaction(txid6, True)
# tx6 should have 5 inputs and 2 outputs
assert_equal(5, len(tx6["vin"]))
@@ -166,7 +165,7 @@ class WalletGroupTest(BitcoinTestFramework):
tx = tx_from_hex(raw_tx)
tx.vin = []
tx.vout = [tx.vout[0]] * 2000
- funded_tx = self.nodes[0].fundrawtransaction(tx.serialize().hex())
+ funded_tx = self.nodes[0].fundrawtransaction(tx.serialize().hex(), options={'fee_rate': self.fee_rate})
signed_tx = self.nodes[0].signrawtransactionwithwallet(funded_tx['hex'])
self.nodes[0].sendrawtransaction(signed_tx['hex'])
self.generate(self.nodes[0], 1)
@@ -175,7 +174,7 @@ class WalletGroupTest(BitcoinTestFramework):
# utxos, without pulling in all outputs and creating a transaction that
# is way too big.
self.log.info("Test creating txn that only requires ~100 of our UTXOs without pulling in all outputs")
- assert self.nodes[2].sendtoaddress(address=addr2[0], amount=5)
+ assert self.nodes[2].sendtoaddress(address=addr2[0], amount=5, fee_rate=self.fee_rate)
if __name__ == '__main__':
diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py
index 83de8e09..07bd7cb2 100755
--- a/test/functional/wallet_multiwallet.py
+++ b/test/functional/wallet_multiwallet.py
@@ -6,7 +6,6 @@
Verify that a bitcoind node can load multiple wallet files
"""
-from decimal import Decimal
from threading import Thread
import os
import platform
@@ -46,7 +45,7 @@ class MultiWalletTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 2
self.rpc_timeout = 120
- self.extra_args = [["-nowallet", "-deprecatedrpc=settxfee"], []]
+ self.extra_args = [["-nowallet"], []]
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
@@ -250,13 +249,6 @@ 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')
- assert_equal(w1.getwalletinfo()['paytxfee'], 0)
- assert_equal(w2.getwalletinfo()['paytxfee'], 0)
- w2.settxfee(0.001)
- assert_equal(w1.getwalletinfo()['paytxfee'], 0)
- assert_equal(w2.getwalletinfo()['paytxfee'], Decimal('0.00100000'))
-
self.log.info("Test dynamic wallet loading")
self.restart_node(0, ['-nowallet'])
diff --git a/test/functional/wallet_txn_clone.py b/test/functional/wallet_txn_clone.py
index befd66ff..de9fe17f 100755
--- a/test/functional/wallet_txn_clone.py
+++ b/test/functional/wallet_txn_clone.py
@@ -17,9 +17,8 @@ from test_framework.messages import (
class TxnMallTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 3
- self.extra_args = [[
- "-deprecatedrpc=settxfee"
- ] for i in range(self.num_nodes)]
+ self.supports_cli = False
+ self.extra_args = [[] for i in range(self.num_nodes)]
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
@@ -38,7 +37,7 @@ class TxnMallTest(BitcoinTestFramework):
def spend_utxo(self, utxo, outputs):
inputs = [utxo]
tx = self.nodes[0].createrawtransaction(inputs, outputs)
- tx = self.nodes[0].fundrawtransaction(tx)
+ tx = self.nodes[0].fundrawtransaction(tx, fee_rate=100)
tx = self.nodes[0].signrawtransactionwithwallet(tx['hex'])
return self.nodes[0].sendrawtransaction(tx['hex'])
@@ -53,8 +52,6 @@ class TxnMallTest(BitcoinTestFramework):
for i in range(3):
assert_equal(self.nodes[i].getbalance(), starting_balance)
- self.nodes[0].settxfee(.001)
-
node0_address1 = self.nodes[0].getnewaddress(address_type=output_type)
node0_utxo1 = self.create_outpoints(self.nodes[0], outputs=[{node0_address1: 1219}])[0]
node0_tx1 = self.nodes[0].gettransaction(node0_utxo1['txid'])
Why this scored 21/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.