diff --git a/doc/release-notes-32138.md b/doc/release-notes-32138.md new file mode 100644 index 00000000000..56699850880 --- /dev/null +++ b/doc/release-notes-32138.md @@ -0,0 +1,3 @@ +RPC and Startup Option +--- +The `-paytxfee` startup option and the `settxfee` RPC are now deleted after being deprecated in Bitcoin Core 30.0. They used to allow the user to set a static fee rate for wallet transactions, which could potentially lead to overpaying or underpaying. Users should instead rely on fee estimation or specify a fee rate per transaction using the `fee_rate` argument in RPCs such as `fundrawtransaction`, `sendtoaddress`, `send`, `sendall`, and `sendmany`. (#32138) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 724620aa730..909ed09faac 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 4dfee3a52e1..637ec62af89 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 85fb1ed1e52..24952fea197 100644 --- a/src/dummywallet.cpp +++ b/src/dummywallet.cpp @@ -38,7 +38,6 @@ void DummyWalletInit::AddWalletOptions(ArgsManager& argsman) const "-maxapsfee=", "-maxtxfee=", "-mintxfee=", - "-paytxfee=", "-signer=", "-spendzeroconfchange", "-txconfirmtarget=", diff --git a/src/policy/fees/block_policy_estimator.h b/src/policy/fees/block_policy_estimator.h index 505eed0867d..ae7b4406074 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 90e46c79815..d4a63987f47 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 77e5ec08052..7398a8ed617 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 f295dd12c8d..1bd5c67a204 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 27cbd3878d6..f329de688a7 100644 --- a/src/wallet/coincontrol.h +++ b/src/wallet/coincontrol.h @@ -94,7 +94,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 m_feerate; //! Override the default confirmation target if set std::optional m_confirm_target; diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp index e63b9ae1806..ff7a9f5a3ac 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 a786062a22f..e2bb2227919 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 e2d47fb382d..ccd82e7a7d7 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=", 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=", 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=", "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=", 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=", 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=", "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 . 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 .", 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=", "Specify directory to hold wallets (default: /wallets if it exists, otherwise )", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::WALLET); diff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp index 68e469d8606..d8424183a85 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 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 FundTxDoc(bool solving_data = true) { diff --git a/src/wallet/rpc/wallet.cpp b/src/wallet/rpc/wallet.cpp index fc84b951344..9ce274973a6 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 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 6d9de0cc0fd..5d6c67b7429 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::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 b1562952257..63dab29972d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3027,27 +3027,6 @@ bool CWallet::LoadWalletArgs(std::shared_ptr 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 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=: '%s' (must be at least %s)"), - "-paytxfee", *arg, chain->relayMinFee().ToString()); - return false; - } - } - if (const auto arg{args.GetArg("-maxtxfee")}) { std::optional max_fee = ParseMoney(*arg); if (!max_fee) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index ef5efa71828..e3d362360c4 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -102,8 +102,6 @@ std::unique_ptr HandleLoadWallet(WalletContext& context, Lo void NotifyWalletLoaded(WalletContext& context, const std::shared_ptr& wallet); std::unique_ptr 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 8b7c8616881..f626ee51761 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 acc3a05fea1..2f86954f22b 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 29d70a056e2..35d43c4c528 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 6039e3088d8..e7a333baf10 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 1a30f0c3cde..4a6c45e746f 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 03bc6046113..a62759761f5 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 de0aafc6047..0d435a35e91 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. @@ -163,7 +162,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") @@ -172,14 +171,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) @@ -188,7 +187,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) @@ -202,11 +201,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) @@ -217,7 +216,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 @@ -226,7 +225,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'], '') @@ -238,7 +237,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 @@ -254,7 +253,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']) @@ -274,7 +273,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 @@ -323,7 +322,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']) @@ -337,7 +336,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']) @@ -359,7 +358,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 @@ -388,7 +387,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']: @@ -419,7 +418,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 @@ -446,10 +445,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. @@ -472,10 +471,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. @@ -499,10 +498,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. @@ -543,10 +542,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. @@ -580,7 +579,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() @@ -603,8 +602,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()]) @@ -640,7 +637,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 @@ -660,7 +657,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. @@ -673,7 +671,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) @@ -682,21 +680,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. @@ -708,11 +706,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. @@ -721,7 +719,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) @@ -736,7 +734,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 @@ -811,7 +809,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) @@ -829,7 +827,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) @@ -917,9 +915,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] @@ -937,9 +935,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] @@ -1002,7 +1000,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']) @@ -1023,7 +1021,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", @@ -1043,8 +1041,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] @@ -1071,7 +1069,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']) @@ -1120,7 +1118,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: @@ -1140,7 +1138,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 @@ -1149,7 +1147,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. @@ -1166,6 +1164,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"] @@ -1197,7 +1196,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). @@ -1206,7 +1205,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 @@ -1227,7 +1226,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) @@ -1246,7 +1245,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 @@ -1258,7 +1257,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 @@ -1291,7 +1291,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}]) @@ -1320,7 +1320,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. @@ -1362,7 +1362,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']) @@ -1370,7 +1370,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']) @@ -1444,7 +1444,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. @@ -1466,10 +1466,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 0bc8838a07a..b47fc3a2ead 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 83de8e09fa9..07bd7cb204c 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 befd66ffac8..de9fe17ff23 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'])