Changeset View
Changeset View
Standalone View
Standalone View
test/functional/wallet_avoidreuse.py
Show First 20 Lines • Show All 185 Lines • ▼ Show 20 Lines | def test_change_remains_change(self, node): | ||||
# It should still be change | # It should still be change | ||||
assert node.getaddressinfo(changeaddr)['ischange'] | assert node.getaddressinfo(changeaddr)['ischange'] | ||||
for logical_tx in node.listtransactions(): | for logical_tx in node.listtransactions(): | ||||
assert logical_tx.get('address') != changeaddr | assert logical_tx.get('address') != changeaddr | ||||
def test_sending_from_reused_address_without_avoid_reuse(self): | def test_sending_from_reused_address_without_avoid_reuse(self): | ||||
''' | ''' | ||||
Test the same as test_sending_from_reused_address_fails, except send the 10 BCH with | Test the same as test_sending_from_reused_address_fails, except send | ||||
the avoid_reuse flag set to false. This means the 10 BTC send should succeed, | the 10MM XEC with the avoid_reuse flag set to false. This means the | ||||
where it fails in test_sending_from_reused_address_fails. | 10MM XEC send should succeed, where it fails in | ||||
test_sending_from_reused_address_fails. | |||||
''' | ''' | ||||
self.log.info( | self.log.info( | ||||
"Test sending from reused address with avoid_reuse=false") | "Test sending from reused address with avoid_reuse=false") | ||||
fundaddr = self.nodes[1].getnewaddress() | fundaddr = self.nodes[1].getnewaddress() | ||||
retaddr = self.nodes[0].getnewaddress() | retaddr = self.nodes[0].getnewaddress() | ||||
self.nodes[0].sendtoaddress(fundaddr, 10000000) | self.nodes[0].sendtoaddress(fundaddr, 10000000) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
self.sync_all() | self.sync_all() | ||||
# listunspent should show 1 single, unused 10 BCH output | # listunspent should show 1 single, unused 10MM XEC output | ||||
assert_unspent( | assert_unspent( | ||||
self.nodes[1], | self.nodes[1], | ||||
total_count=1, | total_count=1, | ||||
total_sum=10000000, | total_sum=10000000, | ||||
reused_supported=True, | reused_supported=True, | ||||
reused_count=0) | reused_count=0) | ||||
# getbalances should show no used, 10 BCH trusted | # getbalances should show no used, 10MM XEC trusted | ||||
assert_balances(self.nodes[1], mine={"used": 0, "trusted": 10000000}) | assert_balances(self.nodes[1], mine={"used": 0, "trusted": 10000000}) | ||||
# node 0 should not show a used entry, as it does not enable | # node 0 should not show a used entry, as it does not enable | ||||
# avoid_reuse | # avoid_reuse | ||||
assert("used" not in self.nodes[0].getbalances()["mine"]) | assert("used" not in self.nodes[0].getbalances()["mine"]) | ||||
self.nodes[1].sendtoaddress(retaddr, 5000000) | self.nodes[1].sendtoaddress(retaddr, 5000000) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
self.sync_all() | self.sync_all() | ||||
# listunspent should show 1 single, unused 5 BCH output | # listunspent should show 1 single, unused 5MM XEC output | ||||
assert_unspent( | assert_unspent( | ||||
self.nodes[1], | self.nodes[1], | ||||
total_count=1, | total_count=1, | ||||
total_sum=5000000, | total_sum=5000000, | ||||
reused_supported=True, | reused_supported=True, | ||||
reused_count=0) | reused_count=0) | ||||
# getbalances should show no used, 5 BCH trusted | # getbalances should show no used, 5MM XEC trusted | ||||
assert_balances(self.nodes[1], mine={"used": 0, "trusted": 5000000}) | assert_balances(self.nodes[1], mine={"used": 0, "trusted": 5000000}) | ||||
self.nodes[0].sendtoaddress(fundaddr, 10000000) | self.nodes[0].sendtoaddress(fundaddr, 10000000) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
self.sync_all() | self.sync_all() | ||||
# listunspent should show 2 total outputs (5, 10 BCH), one unused (5), | # listunspent should show 2 total outputs (5MM, 10MM XEC), one unused | ||||
# one reused (10) | # (5MM), one reused (10MM) | ||||
assert_unspent( | assert_unspent( | ||||
self.nodes[1], | self.nodes[1], | ||||
total_count=2, | total_count=2, | ||||
total_sum=15000000, | total_sum=15000000, | ||||
reused_count=1, | reused_count=1, | ||||
reused_sum=10000000) | reused_sum=10000000) | ||||
# getbalances should show 10 used, 5 BCH trusted | # getbalances should show 10MM used, 5MM XEC trusted | ||||
assert_balances( | assert_balances( | ||||
self.nodes[1], | self.nodes[1], | ||||
mine={ | mine={ | ||||
"used": 10000000, | "used": 10000000, | ||||
"trusted": 5000000}) | "trusted": 5000000}) | ||||
self.nodes[1].sendtoaddress( | self.nodes[1].sendtoaddress( | ||||
address=retaddr, amount=10000000, avoid_reuse=False) | address=retaddr, amount=10000000, avoid_reuse=False) | ||||
# listunspent should show 1 total outputs (5 BCH), unused | # listunspent should show 1 total outputs (5MM XEC), unused | ||||
assert_unspent( | assert_unspent( | ||||
self.nodes[1], | self.nodes[1], | ||||
total_count=1, | total_count=1, | ||||
total_sum=5000000, | total_sum=5000000, | ||||
reused_count=0) | reused_count=0) | ||||
# getbalances should show no used, 5 BCH trusted | # getbalances should show no used, 5MM XEC trusted | ||||
assert_balances(self.nodes[1], mine={"used": 0, "trusted": 5000000}) | assert_balances(self.nodes[1], mine={"used": 0, "trusted": 5000000}) | ||||
# node 1 should now have about 5 BCH left (for both cases) | # node 1 should now have about 5MM XEC left (for both cases) | ||||
assert_approx(self.nodes[1].getbalance(), 5000000, 1000) | assert_approx(self.nodes[1].getbalance(), 5000000, 1000) | ||||
assert_approx( | assert_approx( | ||||
self.nodes[1].getbalance( | self.nodes[1].getbalance( | ||||
avoid_reuse=False), | avoid_reuse=False), | ||||
5000000, | 5000000, | ||||
1000) | 1000) | ||||
def test_sending_from_reused_address_fails(self): | def test_sending_from_reused_address_fails(self): | ||||
''' | ''' | ||||
Test the simple case where [1] generates a new address A, then | Test the simple case where [1] generates a new address A, then | ||||
[0] sends 10 BCH to A. | [0] sends 10MM XEC to A. | ||||
[1] spends 5 BCH from A. (leaving roughly 5 BCH useable) | [1] spends 5MM XEC from A. (leaving roughly 5MM XEC useable) | ||||
[0] sends 10 BCH to A again. | [0] sends 10MM XEC to A again. | ||||
[1] tries to spend 10 BCH (fails; dirty). | [1] tries to spend 10MM XEC (fails; dirty). | ||||
[1] tries to spend 4 BCH (succeeds; change address sufficient) | [1] tries to spend 4MM XEC (succeeds; change address sufficient) | ||||
''' | ''' | ||||
self.log.info("Test sending from reused address fails") | self.log.info("Test sending from reused address fails") | ||||
fundaddr = self.nodes[1].getnewaddress(label="", address_type="legacy") | fundaddr = self.nodes[1].getnewaddress(label="", address_type="legacy") | ||||
retaddr = self.nodes[0].getnewaddress() | retaddr = self.nodes[0].getnewaddress() | ||||
self.nodes[0].sendtoaddress(fundaddr, 10000000) | self.nodes[0].sendtoaddress(fundaddr, 10000000) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
self.sync_all() | self.sync_all() | ||||
# listunspent should show 1 single, unused 10 BCH output | # listunspent should show 1 single, unused 10MM XEC output | ||||
assert_unspent( | assert_unspent( | ||||
self.nodes[1], | self.nodes[1], | ||||
total_count=1, | total_count=1, | ||||
total_sum=10000000, | total_sum=10000000, | ||||
reused_supported=True, | reused_supported=True, | ||||
reused_count=0) | reused_count=0) | ||||
# getbalances should show no used, 10 BCH trusted | # getbalances should show no used, 10MM XEC trusted | ||||
assert_balances(self.nodes[1], mine={"used": 0, "trusted": 10000000}) | assert_balances(self.nodes[1], mine={"used": 0, "trusted": 10000000}) | ||||
self.nodes[1].sendtoaddress(retaddr, 5000000) | self.nodes[1].sendtoaddress(retaddr, 5000000) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
self.sync_all() | self.sync_all() | ||||
# listunspent should show 1 single, unused 5 BCH output | # listunspent should show 1 single, unused 5MM XEC output | ||||
assert_unspent( | assert_unspent( | ||||
self.nodes[1], | self.nodes[1], | ||||
total_count=1, | total_count=1, | ||||
total_sum=5000000, | total_sum=5000000, | ||||
reused_supported=True, | reused_supported=True, | ||||
reused_count=0) | reused_count=0) | ||||
# getbalances should show no used, 5 BCH trusted | # getbalances should show no used, 5MM XEC trusted | ||||
assert_balances(self.nodes[1], mine={"used": 0, "trusted": 5000000}) | assert_balances(self.nodes[1], mine={"used": 0, "trusted": 5000000}) | ||||
# For the second send, we transmute it to a related single-key address | # For the second send, we transmute it to a related single-key address | ||||
# to make sure it's also detected as re-use | # to make sure it's also detected as re-use | ||||
# NB: this is not very useful for ABC, but we keep the new variable | # NB: this is not very useful for ABC, but we keep the new variable | ||||
# name for consistency. | # name for consistency. | ||||
new_fundaddr = fundaddr | new_fundaddr = fundaddr | ||||
self.nodes[0].sendtoaddress(new_fundaddr, 10000000) | self.nodes[0].sendtoaddress(new_fundaddr, 10000000) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
self.sync_all() | self.sync_all() | ||||
# listunspent should show 2 total outputs (5, 10 BCH), one unused (5), | # listunspent should show 2 total outputs (5MM, 10MM XEC), one unused | ||||
# one reused (10) | # (5MM), one reused (10MM) | ||||
assert_unspent( | assert_unspent( | ||||
self.nodes[1], | self.nodes[1], | ||||
total_count=2, | total_count=2, | ||||
total_sum=15000000, | total_sum=15000000, | ||||
reused_count=1, | reused_count=1, | ||||
reused_sum=10000000) | reused_sum=10000000) | ||||
# getbalances should show 10 used, 5 BCH trusted | # getbalances should show 10MM used, 5MM XEC trusted | ||||
assert_balances( | assert_balances( | ||||
self.nodes[1], | self.nodes[1], | ||||
mine={ | mine={ | ||||
"used": 10000000, | "used": 10000000, | ||||
"trusted": 5000000}) | "trusted": 5000000}) | ||||
# node 1 should now have a balance of 5 (no dirty) or 15 (including | # node 1 should now have a balance of 5MM (no dirty) or 15MM (including | ||||
# dirty) | # dirty) | ||||
assert_approx(self.nodes[1].getbalance(), 5000000, 1000) | assert_approx(self.nodes[1].getbalance(), 5000000, 1000) | ||||
assert_approx( | assert_approx( | ||||
self.nodes[1].getbalance( | self.nodes[1].getbalance( | ||||
avoid_reuse=False), | avoid_reuse=False), | ||||
15000000, | 15000000, | ||||
1000) | 1000) | ||||
assert_raises_rpc_error(-6, "Insufficient funds", | assert_raises_rpc_error(-6, "Insufficient funds", | ||||
self.nodes[1].sendtoaddress, retaddr, 10000000) | self.nodes[1].sendtoaddress, retaddr, 10000000) | ||||
self.nodes[1].sendtoaddress(retaddr, 4000000) | self.nodes[1].sendtoaddress(retaddr, 4000000) | ||||
# listunspent should show 2 total outputs (1, 10 BCH), one unused (1), | # listunspent should show 2 total outputs (1MM, 10MM XEC), one unused | ||||
# one reused (10) | # (1MM), one reused (10MM) | ||||
assert_unspent( | assert_unspent( | ||||
self.nodes[1], | self.nodes[1], | ||||
total_count=2, | total_count=2, | ||||
total_sum=11000000, | total_sum=11000000, | ||||
reused_count=1, | reused_count=1, | ||||
reused_sum=10000000) | reused_sum=10000000) | ||||
# getbalances should show 10 used, 1 BCH trusted | # getbalances should show 10MM used, 1MM XEC trusted | ||||
assert_balances( | assert_balances( | ||||
self.nodes[1], | self.nodes[1], | ||||
mine={ | mine={ | ||||
"used": 10000000, | "used": 10000000, | ||||
"trusted": 1000000}) | "trusted": 1000000}) | ||||
# node 1 should now have about 1 BCH left (no dirty) and 11 (including | # node 1 should now have about 1MM XEC left (no dirty) and 11MM | ||||
# dirty) | # (including dirty) | ||||
assert_approx(self.nodes[1].getbalance(), 1000000, 1000) | assert_approx(self.nodes[1].getbalance(), 1000000, 1000) | ||||
assert_approx( | assert_approx( | ||||
self.nodes[1].getbalance( | self.nodes[1].getbalance( | ||||
avoid_reuse=False), | avoid_reuse=False), | ||||
11000000, | 11000000, | ||||
1000) | 1000) | ||||
def test_getbalances_used(self): | def test_getbalances_used(self): | ||||
Show All 32 Lines | def test_getbalances_used(self): | ||||
assert_balances( | assert_balances( | ||||
self.nodes[1], | self.nodes[1], | ||||
mine={ | mine={ | ||||
"used": 1000000, | "used": 1000000, | ||||
"trusted": 5000000}) | "trusted": 5000000}) | ||||
def test_full_destination_group_is_preferred(self): | def test_full_destination_group_is_preferred(self): | ||||
''' | ''' | ||||
Test the case where [1] only has 11 outputs of 1 BCH in the same reused | Test the case where [1] only has 11 outputs of 1MM XEC in the same | ||||
address and tries to send a small payment of 0.5 BCH. The wallet | reused address and tries to send a small payment of 500,000 XEC. | ||||
should use 10 outputs from the reused address as inputs and not a | The wallet should use 10 outputs from the reused address as inputs and | ||||
single 1 BCH input, in order to join several outputs from the reused | not a single 1MM XEC input, in order to join several outputs from | ||||
address. | the reused address. | ||||
''' | ''' | ||||
self.log.info( | self.log.info( | ||||
"Test that full destination groups are preferred in coin selection") | "Test that full destination groups are preferred in coin selection") | ||||
# Node under test should be empty | # Node under test should be empty | ||||
assert_equal(self.nodes[1].getbalance(avoid_reuse=False), 0) | assert_equal(self.nodes[1].getbalance(avoid_reuse=False), 0) | ||||
new_addr = self.nodes[1].getnewaddress() | new_addr = self.nodes[1].getnewaddress() | ||||
ret_addr = self.nodes[0].getnewaddress() | ret_addr = self.nodes[0].getnewaddress() | ||||
# Send 11 outputs of 1 BCH to the same, reused address in the wallet | # Send 11 outputs of 1MM XEC to the same, reused address in the wallet | ||||
for _ in range(11): | for _ in range(11): | ||||
self.nodes[0].sendtoaddress(new_addr, 1000000) | self.nodes[0].sendtoaddress(new_addr, 1000000) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
self.sync_all() | self.sync_all() | ||||
# Sending a transaction that is smaller than each one of the | # Sending a transaction that is smaller than each one of the | ||||
# available outputs | # available outputs | ||||
txid = self.nodes[1].sendtoaddress(address=ret_addr, amount=500000) | txid = self.nodes[1].sendtoaddress(address=ret_addr, amount=500000) | ||||
inputs = self.nodes[1].getrawtransaction(txid, 1)["vin"] | inputs = self.nodes[1].getrawtransaction(txid, 1)["vin"] | ||||
# The transaction should use 10 inputs exactly | # The transaction should use 10 inputs exactly | ||||
assert_equal(len(inputs), 10) | assert_equal(len(inputs), 10) | ||||
def test_all_destination_groups_are_used(self): | def test_all_destination_groups_are_used(self): | ||||
''' | ''' | ||||
Test the case where [1] only has 22 outputs of 1 BCH in the same reused | Test the case where [1] only has 22 outputs of 1MM XEC in the same | ||||
address and tries to send a payment of 20.5 BCH. The wallet | reused address and tries to send a payment of 20,5MM XEC. | ||||
should use all 22 outputs from the reused address as inputs. | The wallet should use all 22 outputs from the reused address as inputs. | ||||
''' | ''' | ||||
self.log.info("Test that all destination groups are used") | self.log.info("Test that all destination groups are used") | ||||
# Node under test should be empty | # Node under test should be empty | ||||
assert_equal(self.nodes[1].getbalance(avoid_reuse=False), 0) | assert_equal(self.nodes[1].getbalance(avoid_reuse=False), 0) | ||||
new_addr = self.nodes[1].getnewaddress() | new_addr = self.nodes[1].getnewaddress() | ||||
ret_addr = self.nodes[0].getnewaddress() | ret_addr = self.nodes[0].getnewaddress() | ||||
# Send 22 outputs of 1 BCH to the same, reused address in the wallet | # Send 22 outputs of 1MM XEC to the same, reused address in the wallet | ||||
for _ in range(22): | for _ in range(22): | ||||
self.nodes[0].sendtoaddress(new_addr, 1000000) | self.nodes[0].sendtoaddress(new_addr, 1000000) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
self.sync_all() | self.sync_all() | ||||
# Sending a transaction that needs to use the full groups | # Sending a transaction that needs to use the full groups | ||||
# of 10 inputs but also the incomplete group of 2 inputs. | # of 10 inputs but also the incomplete group of 2 inputs. | ||||
Show All 9 Lines |