Changeset View
Changeset View
Standalone View
Standalone View
test/functional/wallet_address_types.py
#!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||
# Copyright (c) 2017 The Bitcoin Core developers | # Copyright (c) 2017 The Bitcoin Core developers | ||||
# Distributed under the MIT software license, see the accompanying | # Distributed under the MIT software license, see the accompanying | ||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | # file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
"""Test that the wallet can send and receive using all combinations of address types. | """Test that the wallet can send and receive using all combinations of address types. | ||||
There are 4 nodes-under-test: | There are 4 nodes-under-test: | ||||
- node0 uses legacy addresses | - node0 uses legacy addresses | ||||
- node1 uses legacy addresses | - node1 uses legacy addresses | ||||
- node2 uses legacy addresses | - node2 uses legacy addresses | ||||
- node3 uses legacy addresses | - node3 uses legacy addresses | ||||
node4 exists to generate new blocks. | node4 exists to generate new blocks. | ||||
The script is a series of tests, iterating over the 4 nodes. In each iteration | ## Multisig address test | ||||
of the test, one node sends: | |||||
Test that adding a multisig address with: | |||||
- an uncompressed pubkey always gives a legacy address | |||||
- only compressed pubkeys gives the an `-addresstype` address | |||||
## Sending to address types test | |||||
A series of tests, iterating over node0-node3. In each iteration of the test, one node sends: | |||||
- 10/101th of its balance to itself (using getrawchangeaddress for single key addresses) | - 10/101th of its balance to itself (using getrawchangeaddress for single key addresses) | ||||
- 20/101th to the next node | - 20/101th to the next node | ||||
- 30/101th to the node after that | - 30/101th to the node after that | ||||
- 40/101th to the remaining node | - 40/101th to the remaining node | ||||
- 1/101th remains as fee+change | - 1/101th remains as fee+change | ||||
Iterate over each node for single key addresses, and then over each node for | Iterate over each node for single key addresses, and then over each node for | ||||
multisig addresses. In a second iteration, the same is done. As every node | multisig addresses. Repeat test. As every node sends coins after receiving, | ||||
sends coins after receiving, this also verifies that spending coins sent to | this also verifies that spending coins sent to all these address types works. | ||||
all these address works.""" | """ | ||||
from decimal import Decimal | from decimal import Decimal | ||||
import itertools | import itertools | ||||
from test_framework.test_framework import BitcoinTestFramework | from test_framework.test_framework import BitcoinTestFramework | ||||
from test_framework.util import assert_equal, assert_greater_than, connect_nodes_bi, sync_blocks, sync_mempools | from test_framework.util import ( | ||||
assert_equal, | |||||
assert_greater_than, | |||||
connect_nodes_bi, | |||||
sync_blocks, | |||||
sync_mempools, | |||||
) | |||||
class AddressTypeTest(BitcoinTestFramework): | class AddressTypeTest(BitcoinTestFramework): | ||||
def set_test_params(self): | def set_test_params(self): | ||||
self.num_nodes = 5 | self.num_nodes = 5 | ||||
# whitelist all peers to speed up tx relay / mempool sync | # whitelist all peers to speed up tx relay / mempool sync | ||||
self.extra_args = [["-whitelist=127.0.0.1"]] * self.num_nodes | self.extra_args = [["-whitelist=127.0.0.1"]] * self.num_nodes | ||||
Show All 29 Lines | def test_address(self, node, address, multisig, typ): | ||||
# P2SH-multisig | # P2SH-multisig | ||||
assert(info['isscript']) | assert(info['isscript']) | ||||
assert_equal(info['script'], 'multisig') | assert_equal(info['script'], 'multisig') | ||||
assert('pubkeys' in info) | assert('pubkeys' in info) | ||||
else: | else: | ||||
# Unknown type | # Unknown type | ||||
assert(False) | assert(False) | ||||
def test_change_output_type( | |||||
self, node_sender, destinations, expected_type): | |||||
txid = self.nodes[node_sender].sendmany( | |||||
dummy="", amounts=dict.fromkeys( | |||||
destinations, 0.001)) | |||||
raw_tx = self.nodes[node_sender].getrawtransaction(txid) | |||||
tx = self.nodes[node_sender].decoderawtransaction(raw_tx) | |||||
# Make sure the transaction has change: | |||||
assert_equal(len(tx["vout"]), len(destinations) + 1) | |||||
# Make sure the destinations are included, and remove them: | |||||
output_addresses = [vout['scriptPubKey']['addresses'][0] | |||||
for vout in tx["vout"]] | |||||
change_addresses = [ | |||||
d for d in output_addresses if d not in destinations] | |||||
assert_equal(len(change_addresses), 1) | |||||
self.log.debug( | |||||
"Check if change address " + | |||||
change_addresses[0] + | |||||
" is " + | |||||
expected_type) | |||||
self.test_address( | |||||
node_sender, | |||||
change_addresses[0], | |||||
multisig=False, | |||||
typ=expected_type) | |||||
def run_test(self): | def run_test(self): | ||||
# Mine 101 blocks on node4 to bring nodes out of IBD and make sure that | # Mine 101 blocks on node4 to bring nodes out of IBD and make sure that | ||||
# no coinbases are maturing for the nodes-under-test during the test | # no coinbases are maturing for the nodes-under-test during the test | ||||
self.nodes[4].generate(101) | self.nodes[4].generate(101) | ||||
sync_blocks(self.nodes) | sync_blocks(self.nodes) | ||||
uncompressed_1 = "0496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858ee" | uncompressed_1 = "0496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858ee" | ||||
uncompressed_2 = "047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77" | uncompressed_2 = "047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77" | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
# the balance of the sending node | # the balance of the sending node | ||||
assert_greater_than(new_balances[from_node], to_send * 10) | assert_greater_than(new_balances[from_node], to_send * 10) | ||||
assert_greater_than(to_send * 11, new_balances[from_node]) | assert_greater_than(to_send * 11, new_balances[from_node]) | ||||
for n, to_node in enumerate(range(from_node + 1, from_node + 4)): | for n, to_node in enumerate(range(from_node + 1, from_node + 4)): | ||||
to_node %= 4 | to_node %= 4 | ||||
assert_equal( | assert_equal( | ||||
new_balances[to_node], old_balances[to_node] + to_send * 10 * (2 + n)) | new_balances[to_node], old_balances[to_node] + to_send * 10 * (2 + n)) | ||||
# Get addresses from node2 and node3: | |||||
to_address_2 = self.nodes[2].getnewaddress() | |||||
to_address_3_1 = self.nodes[3].getnewaddress() | |||||
to_address_3_2 = self.nodes[3].getnewaddress() | |||||
self.log.info("Various change output tests") | |||||
self.test_change_output_type(0, [to_address_3_1], 'legacy') | |||||
self.test_change_output_type(1, [to_address_2], 'legacy') | |||||
self.test_change_output_type(1, [to_address_3_1], 'legacy') | |||||
self.test_change_output_type( | |||||
1, [to_address_2, to_address_3_1], 'legacy') | |||||
self.test_change_output_type( | |||||
1, [to_address_3_1, to_address_3_2], 'legacy') | |||||
self.test_change_output_type(2, [to_address_3_1], 'legacy') | |||||
self.log.info('Test getrawchangeaddress') | |||||
self.test_address( | |||||
3, | |||||
self.nodes[3].getrawchangeaddress(), | |||||
multisig=False, | |||||
typ='legacy') | |||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
AddressTypeTest().main() | AddressTypeTest().main() |