aboutsummaryrefslogtreecommitdiff
path: root/test/functional
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional')
-rwxr-xr-xtest/functional/wallet_avoidreuse.py85
-rwxr-xr-xtest/functional/wallet_bumpfee.py10
-rwxr-xr-xtest/functional/wallet_multiwallet.py5
3 files changed, 86 insertions, 14 deletions
diff --git a/test/functional/wallet_avoidreuse.py b/test/functional/wallet_avoidreuse.py
index 2ce8d459c6..78a51a1d5f 100755
--- a/test/functional/wallet_avoidreuse.py
+++ b/test/functional/wallet_avoidreuse.py
@@ -85,15 +85,19 @@ class AvoidReuseTest(BitcoinTestFramework):
self.sync_all()
self.test_change_remains_change(self.nodes[1])
reset_balance(self.nodes[1], self.nodes[0].getnewaddress())
- self.test_fund_send_fund_senddirty()
+ self.test_sending_from_reused_address_without_avoid_reuse()
reset_balance(self.nodes[1], self.nodes[0].getnewaddress())
- self.test_fund_send_fund_send("legacy")
+ self.test_sending_from_reused_address_fails("legacy")
reset_balance(self.nodes[1], self.nodes[0].getnewaddress())
- self.test_fund_send_fund_send("p2sh-segwit")
+ self.test_sending_from_reused_address_fails("p2sh-segwit")
reset_balance(self.nodes[1], self.nodes[0].getnewaddress())
- self.test_fund_send_fund_send("bech32")
+ self.test_sending_from_reused_address_fails("bech32")
reset_balance(self.nodes[1], self.nodes[0].getnewaddress())
self.test_getbalances_used()
+ reset_balance(self.nodes[1], self.nodes[0].getnewaddress())
+ self.test_full_destination_group_is_preferred()
+ reset_balance(self.nodes[1], self.nodes[0].getnewaddress())
+ self.test_all_destination_groups_are_used()
def test_persistence(self):
'''Test that wallet files persist the avoid_reuse flag.'''
@@ -162,13 +166,13 @@ class AvoidReuseTest(BitcoinTestFramework):
for logical_tx in node.listtransactions():
assert logical_tx.get('address') != changeaddr
- def test_fund_send_fund_senddirty(self):
+ def test_sending_from_reused_address_without_avoid_reuse(self):
'''
- Test the same as test_fund_send_fund_send, except send the 10 BTC with
+ Test the same as test_sending_from_reused_address_fails, except send the 10 BTC with
the avoid_reuse flag set to false. This means the 10 BTC send should succeed,
- where it fails in test_fund_send_fund_send.
+ where it fails in test_sending_from_reused_address_fails.
'''
- self.log.info("Test fund send fund send dirty")
+ self.log.info("Test sending from reused address with avoid_reuse=false")
fundaddr = self.nodes[1].getnewaddress()
retaddr = self.nodes[0].getnewaddress()
@@ -213,7 +217,7 @@ class AvoidReuseTest(BitcoinTestFramework):
assert_approx(self.nodes[1].getbalance(), 5, 0.001)
assert_approx(self.nodes[1].getbalance(avoid_reuse=False), 5, 0.001)
- def test_fund_send_fund_send(self, second_addr_type):
+ def test_sending_from_reused_address_fails(self, second_addr_type):
'''
Test the simple case where [1] generates a new address A, then
[0] sends 10 BTC to A.
@@ -222,7 +226,7 @@ class AvoidReuseTest(BitcoinTestFramework):
[1] tries to spend 10 BTC (fails; dirty).
[1] tries to spend 4 BTC (succeeds; change address sufficient)
'''
- self.log.info("Test fund send fund send")
+ self.log.info("Test sending from reused {} address fails".format(second_addr_type))
fundaddr = self.nodes[1].getnewaddress(label="", address_type="legacy")
retaddr = self.nodes[0].getnewaddress()
@@ -313,5 +317,66 @@ class AvoidReuseTest(BitcoinTestFramework):
assert_unspent(self.nodes[1], total_count=2, total_sum=6, reused_count=1, reused_sum=1)
assert_balances(self.nodes[1], mine={"used": 1, "trusted": 5})
+ def test_full_destination_group_is_preferred(self):
+ '''
+ Test the case where [1] only has 11 outputs of 1 BTC in the same reused
+ address and tries to send a small payment of 0.5 BTC. The wallet
+ should use 10 outputs from the reused address as inputs and not a
+ single 1 BTC input, in order to join several outputs from the reused
+ address.
+ '''
+ self.log.info("Test that full destination groups are preferred in coin selection")
+
+ # Node under test should be empty
+ assert_equal(self.nodes[1].getbalance(avoid_reuse=False), 0)
+
+ new_addr = self.nodes[1].getnewaddress()
+ ret_addr = self.nodes[0].getnewaddress()
+
+ # Send 11 outputs of 1 BTC to the same, reused address in the wallet
+ for _ in range(11):
+ self.nodes[0].sendtoaddress(new_addr, 1)
+
+ self.nodes[0].generate(1)
+ self.sync_all()
+
+ # Sending a transaction that is smaller than each one of the
+ # available outputs
+ txid = self.nodes[1].sendtoaddress(address=ret_addr, amount=0.5)
+ inputs = self.nodes[1].getrawtransaction(txid, 1)["vin"]
+
+ # The transaction should use 10 inputs exactly
+ assert_equal(len(inputs), 10)
+
+ def test_all_destination_groups_are_used(self):
+ '''
+ Test the case where [1] only has 22 outputs of 1 BTC in the same reused
+ address and tries to send a payment of 20.5 BTC. The wallet
+ should use all 22 outputs from the reused address as inputs.
+ '''
+ self.log.info("Test that all destination groups are used")
+
+ # Node under test should be empty
+ assert_equal(self.nodes[1].getbalance(avoid_reuse=False), 0)
+
+ new_addr = self.nodes[1].getnewaddress()
+ ret_addr = self.nodes[0].getnewaddress()
+
+ # Send 22 outputs of 1 BTC to the same, reused address in the wallet
+ for _ in range(22):
+ self.nodes[0].sendtoaddress(new_addr, 1)
+
+ self.nodes[0].generate(1)
+ self.sync_all()
+
+ # Sending a transaction that needs to use the full groups
+ # of 10 inputs but also the incomplete group of 2 inputs.
+ txid = self.nodes[1].sendtoaddress(address=ret_addr, amount=20.5)
+ inputs = self.nodes[1].getrawtransaction(txid, 1)["vin"]
+
+ # The transaction should use 22 inputs exactly
+ assert_equal(len(inputs), 22)
+
+
if __name__ == '__main__':
AvoidReuseTest().main()
diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py
index 1c9a050464..c09ca8854f 100755
--- a/test/functional/wallet_bumpfee.py
+++ b/test/functional/wallet_bumpfee.py
@@ -82,7 +82,6 @@ class BumpFeeTest(BitcoinTestFramework):
test_notmine_bumpfee_fails(self, rbf_node, peer_node, dest_address)
test_bumpfee_with_descendant_fails(self, rbf_node, rbf_node_address, dest_address)
test_dust_to_fee(self, rbf_node, dest_address)
- test_settxfee(self, rbf_node, dest_address)
test_watchonly_psbt(self, peer_node, rbf_node, dest_address)
test_rebumping(self, rbf_node, dest_address)
test_rebumping_not_replaceable(self, rbf_node, dest_address)
@@ -90,6 +89,7 @@ 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)
@@ -286,9 +286,15 @@ def test_settxfee(self, rbf_node, dest_address):
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)
+
def test_maxtxfee_fails(self, rbf_node, dest_address):
- self.log.info('Test that bumpfee fails when it hits -matxfee')
+ self.log.info('Test that bumpfee fails when it hits -maxtxfee')
# size of bumped transaction (p2wpkh, 1 input, 2 outputs): 141 vbytes
# expected bump fee of 141 vbytes * 0.00200000 BTC / 1000 vbytes = 0.00002820 BTC
# which exceeds maxtxfee and is expected to raise
diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py
index f4093015ac..0171b594c1 100755
--- a/test/functional/wallet_multiwallet.py
+++ b/test/functional/wallet_multiwallet.py
@@ -6,6 +6,7 @@
Verify that a bitcoind node can load multiple wallet files
"""
+from decimal import Decimal
import os
import shutil
import time
@@ -193,9 +194,9 @@ class MultiWalletTest(BitcoinTestFramework):
self.log.info('Check for per-wallet settxfee call')
assert_equal(w1.getwalletinfo()['paytxfee'], 0)
assert_equal(w2.getwalletinfo()['paytxfee'], 0)
- w2.settxfee(4.0)
+ w2.settxfee(0.001)
assert_equal(w1.getwalletinfo()['paytxfee'], 0)
- assert_equal(w2.getwalletinfo()['paytxfee'], 4.0)
+ assert_equal(w2.getwalletinfo()['paytxfee'], Decimal('0.00100000'))
self.log.info("Test dynamic wallet loading")