mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-03-02 01:36:13 +00:00
wallet, rpc:remove settxfee and paytxfee
This commit is contained in:
parent
4ae00e9a71
commit
331a5279d2
@ -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());
|
||||
|
||||
@ -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"},
|
||||
};
|
||||
|
||||
@ -38,7 +38,6 @@ void DummyWalletInit::AddWalletOptions(ArgsManager& argsman) const
|
||||
"-maxapsfee=<n>",
|
||||
"-maxtxfee=<amt>",
|
||||
"-mintxfee=<amt>",
|
||||
"-paytxfee=<amt>",
|
||||
"-signer=<cmd>",
|
||||
"-spendzeroconfchange",
|
||||
"-txconfirmtarget=<n>",
|
||||
|
||||
@ -64,7 +64,6 @@ enum class FeeReason {
|
||||
DOUBLE_ESTIMATE,
|
||||
CONSERVATIVE,
|
||||
MEMPOOL_MIN,
|
||||
PAYTXFEE,
|
||||
FALLBACK,
|
||||
REQUIRED,
|
||||
};
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 },
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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},
|
||||
|
||||
@ -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)};
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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__':
|
||||
|
||||
@ -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'])
|
||||
|
||||
@ -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'])
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user