Skip to content

Commit 6e2d879

Browse files
authored
Merge pull request #1333 from delta1/mintxfee
wallet: allow mintxfee=0
2 parents 2eb5b08 + ab5777e commit 6e2d879

File tree

5 files changed

+72
-8
lines changed

5 files changed

+72
-8
lines changed

src/confidential_validation.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ bool HasValidFee(const CTransaction& tx) {
3030
CAmount fee = 0;
3131
if (tx.vout[i].IsFee()) {
3232
fee = tx.vout[i].nValue.GetAmount();
33-
if (fee == 0 || !MoneyRange(fee))
33+
if (fee == 0 || !MoneyRange(fee)) {
3434
return false;
35+
}
3536
totalFee[tx.vout[i].nAsset.GetAsset()] += fee;
3637
if (!MoneyRange(totalFee)) {
3738
return false;

src/wallet/spend.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,11 +1322,14 @@ static bool CreateTransactionInternal(
13221322

13231323
// Add fee output.
13241324
if (g_con_elementsmode) {
1325-
CTxOut fee(::policyAsset, 0, CScript());
1326-
assert(fee.IsFee());
1327-
txNew.vout.push_back(fee);
1328-
if (blind_details) {
1329-
blind_details->o_pubkeys.push_back(CPubKey());
1325+
// only create fee output if non-zero fee
1326+
if (coin_selection_params.m_effective_feerate > CFeeRate()) {
1327+
CTxOut fee(::policyAsset, 0, CScript());
1328+
assert(fee.IsFee());
1329+
txNew.vout.push_back(fee);
1330+
if (blind_details) {
1331+
blind_details->o_pubkeys.push_back(CPubKey());
1332+
}
13301333
}
13311334
}
13321335
assert(nChangePosInOut != -1);
@@ -1448,7 +1451,6 @@ static bool CreateTransactionInternal(
14481451
txNew = tx_blinded; // sigh, `fillBlindDetails` may have modified txNew
14491452
// Update the change position to the new tx
14501453
change_position = txNew.vout.begin() + nChangePosInOut;
1451-
14521454
int ret = BlindTransaction(blind_details->i_amount_blinds, blind_details->i_asset_blinds, blind_details->i_assets, blind_details->i_amounts, blind_details->o_amount_blinds, blind_details->o_asset_blinds, blind_details->o_pubkeys, issuance_asset_keys, issuance_token_keys, tx_blinded);
14531455
assert(ret != -1);
14541456
if (ret != blind_details->num_to_blind) {

src/wallet/wallet.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3024,7 +3024,7 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
30243024

30253025
if (args.IsArgSet("-mintxfee")) {
30263026
std::optional<CAmount> min_tx_fee = ParseMoney(args.GetArg("-mintxfee", ""));
3027-
if (!min_tx_fee || min_tx_fee.value() == 0) {
3027+
if (!min_tx_fee) {
30283028
error = AmountErrMsg("mintxfee", args.GetArg("-mintxfee", ""));
30293029
return nullptr;
30303030
} else if (min_tx_fee.value() > HIGH_TX_FEE_PER_KB) {

test/functional/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@
356356
'feature_coinstatsindex.py --legacy-wallet',
357357
'feature_coinstatsindex.py --descriptors',
358358
'wallet_orphanedreward.py',
359+
'wallet_send_zero_fee.py',
359360
'wallet_timelock.py',
360361
'p2p_node_network_limited.py',
361362
'p2p_permissions.py',
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2017-2020 The Bitcoin Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
from decimal import Decimal
6+
7+
from test_framework.test_framework import BitcoinTestFramework
8+
from test_framework.util import (
9+
assert_equal,
10+
)
11+
12+
class WalletTest(BitcoinTestFramework):
13+
def set_test_params(self):
14+
self.num_nodes = 3
15+
self.extra_args = [[
16+
"-blindedaddresses=1",
17+
"-minrelaytxfee=0",
18+
"-blockmintxfee=0",
19+
"-mintxfee=0",
20+
]] * self.num_nodes
21+
22+
def skip_test_if_missing_module(self):
23+
self.skip_if_no_wallet()
24+
25+
def run_test(self):
26+
# initial state when setup_clean_chain is False
27+
assert_equal(self.nodes[0].getbalance(), {'bitcoin': Decimal('1250')})
28+
assert_equal(self.nodes[1].getbalance(), {'bitcoin': Decimal('1250')})
29+
assert_equal(self.nodes[2].getbalance(), {'bitcoin': Decimal('1250')})
30+
assert_equal(self.nodes[0].getblockchaininfo()["blocks"], 200)
31+
32+
self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 10)
33+
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 20)
34+
self.generate(self.nodes[0], 1)
35+
assert_equal(self.nodes[0].getblockchaininfo()["blocks"], 201)
36+
assert_equal(self.nodes[0].getbalance(), {'bitcoin': Decimal('1269.99897200')})
37+
assert_equal(self.nodes[1].getbalance(), {'bitcoin': Decimal('1260')})
38+
assert_equal(self.nodes[2].getbalance(), {'bitcoin': Decimal('1270')})
39+
40+
# send a zero fee_rate transaction, which should not add a fee output
41+
addr = self.nodes[1].getnewaddress()
42+
txid = self.nodes[0].sendtoaddress(address=addr, amount=1, fee_rate=0)
43+
tx = self.nodes[0].getrawtransaction(txid, 2)
44+
# there should be no fees
45+
assert "bitcoin" not in tx["fee"]
46+
assert_equal(tx["fee"], {})
47+
# and no fee output
48+
assert_equal(len(tx["vout"]),2)
49+
for output in tx["vout"]:
50+
assert output["scriptPubKey"]["type"] != "fee"
51+
52+
self.generate(self.nodes[0], 1)
53+
assert_equal(self.nodes[0].getblockchaininfo()["blocks"], 202)
54+
55+
assert_equal(self.nodes[0].getbalance(), {'bitcoin': Decimal('1318.99897200')})
56+
assert_equal(self.nodes[1].getbalance(), {'bitcoin': Decimal('1261')})
57+
assert_equal(self.nodes[2].getbalance(), {'bitcoin': Decimal('1270')})
58+
59+
if __name__ == '__main__':
60+
WalletTest().main()

0 commit comments

Comments
 (0)