From 640e4ae422260d6053a0a41beebee0ba51fbec7e Mon Sep 17 00:00:00 2001 From: Byron Hambly Date: Wed, 22 May 2024 10:46:06 +0200 Subject: [PATCH] wallet: allow mintxfee=0 This check for 0 feerate was inherited from upstream, and subsequently removed in this commit: https://github.com/bitcoin/bitcoin/commit/f11eb1fe279c4a92e1bfc2c139e8838c73459d12 --- src/confidential_validation.cpp | 3 +- src/wallet/wallet.cpp | 3 +- test/functional/test_runner.py | 1 + test/functional/wallet_send_zero_fee.py | 60 +++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100755 test/functional/wallet_send_zero_fee.py diff --git a/src/confidential_validation.cpp b/src/confidential_validation.cpp index efc7b753c4..c101852fbc 100644 --- a/src/confidential_validation.cpp +++ b/src/confidential_validation.cpp @@ -30,8 +30,9 @@ bool HasValidFee(const CTransaction& tx) { CAmount fee = 0; if (tx.vout[i].IsFee()) { fee = tx.vout[i].nValue.GetAmount(); - if (fee == 0 || !MoneyRange(fee)) + if (!MoneyRange(fee)) { return false; + } totalFee[tx.vout[i].nAsset.GetAsset()] += fee; if (!MoneyRange(totalFee)) { return false; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e7444556ea..39e83f5a6b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3012,7 +3012,8 @@ std::shared_ptr CWallet::Create(WalletContext& context, const std::stri if (args.IsArgSet("-mintxfee")) { std::optional min_tx_fee = ParseMoney(args.GetArg("-mintxfee", "")); - if (!min_tx_fee || min_tx_fee.value() == 0) { + // ELEMENTS: allow mintxfee=0 + if (!min_tx_fee) { error = AmountErrMsg("mintxfee", args.GetArg("-mintxfee", "")); return nullptr; } else if (min_tx_fee.value() > HIGH_TX_FEE_PER_KB) { diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 198a3eaeb1..6806b33fed 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -352,6 +352,7 @@ 'feature_coinstatsindex.py --legacy-wallet', 'feature_coinstatsindex.py --descriptors', 'wallet_orphanedreward.py', + 'wallet_send_zero_fee.py', 'wallet_timelock.py', 'p2p_node_network_limited.py', 'p2p_permissions.py', diff --git a/test/functional/wallet_send_zero_fee.py b/test/functional/wallet_send_zero_fee.py new file mode 100755 index 0000000000..49deea6585 --- /dev/null +++ b/test/functional/wallet_send_zero_fee.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017-2020 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +from decimal import Decimal + +from test_framework.blocktools import COINBASE_MATURITY +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, +) + +class WalletTest(BitcoinTestFramework): + def set_test_params(self): + self.setup_clean_chain = True + self.num_nodes = 3 + self.extra_args = [[ + "-blindedaddresses=1", + "-initialfreecoins=2100000000000000", + "-con_blocksubsidy=0", + "-con_connect_genesis_outputs=1", + "-txindex=1", + "-minrelaytxfee=0", + "-blockmintxfee=0", + "-mintxfee=0", + ]] * self.num_nodes + self.extra_args[0].append("-anyonecanspendaremine=1") + + def skip_test_if_missing_module(self): + self.skip_if_no_wallet() + + def run_test(self): + self.generate(self.nodes[0], COINBASE_MATURITY + 1) + self.sync_all() + + self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 10) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 20) + self.generate(self.nodes[0], 1) + assert_equal(self.nodes[0].getblockchaininfo()["blocks"], 102) + assert_equal(self.nodes[0].getbalance(), {'bitcoin': Decimal('20999969.99900900')}) + assert_equal(self.nodes[1].getbalance(), {'bitcoin': Decimal('10.00000000')}) + assert_equal(self.nodes[2].getbalance(), {'bitcoin': Decimal('20.00000000')}) + + addr = self.nodes[1].getnewaddress() + txid = self.nodes[0].sendtoaddress(addr, 1, None, None, None, None, None, None, None, None, None, 0, False) + tx = self.nodes[0].gettransaction(txid) + assert_equal(tx["fee"]["bitcoin"], 0) + hex = self.nodes[0].getrawtransaction(txid) + self.generate(self.nodes[0], 1) + assert_equal(self.nodes[0].getblockchaininfo()["blocks"], 103) + + decoded = self.nodes[0].decoderawtransaction(hex) + bitcoin = "b2e15d0d7a0c94e4e2ce0fe6e8691b9e451377f6e46e8045a86f7c4b5d4f0f23" + assert_equal(decoded["fee"][bitcoin], 0) + assert_equal(self.nodes[0].getbalance(), {'bitcoin': Decimal('20999968.99900900')}) + assert_equal(self.nodes[1].getbalance(), {'bitcoin': Decimal('11.00000000')}) + assert_equal(self.nodes[2].getbalance(), {'bitcoin': Decimal('20.00000000')}) + +if __name__ == '__main__': + WalletTest().main()