4
4
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
5
"""Test that the wallet can send and receive using all combinations of address types.
6
6
7
- There are 4 nodes-under-test:
7
+ There are 5 nodes-under-test:
8
8
- node0 uses legacy addresses
9
9
- node1 uses p2sh/segwit addresses
10
10
- node2 uses p2sh/segwit addresses and bech32 addresses for change
11
11
- node3 uses bech32 addresses
12
+ - node4 uses a p2sh/segwit addresses for change
12
13
13
- node4 exists to generate new blocks.
14
+ node5 exists to generate new blocks.
14
15
15
- The script is a series of tests, iterating over the 4 nodes. In each iteration
16
- of the test, one node sends:
16
+ ## Multisig address test
17
+
18
+ Test that adding a multisig address with:
19
+ - an uncompressed pubkey always gives a legacy address
20
+ - only compressed pubkeys gives the an `-addresstype` address
21
+
22
+ ## Sending to address types test
23
+
24
+ A series of tests, iterating over node0-node4. In each iteration of the test, one node sends:
17
25
- 10/101th of its balance to itself (using getrawchangeaddress for single key addresses)
18
26
- 20/101th to the next node
19
27
- 30/101th to the node after that
20
28
- 40/101th to the remaining node
21
29
- 1/101th remains as fee+change
22
30
23
31
Iterate over each node for single key addresses, and then over each node for
24
- multisig addresses. In a second iteration, the same is done, but with explicit address_type
25
- parameters passed to getnewaddress and getrawchangeaddress. Node0 and node3 send to p2sh,
26
- node 1 sends to bech32, and node2 sends to legacy. As every node sends coins after receiving,
27
- this also verifies that spending coins sent to all these address types works."""
32
+ multisig addresses.
33
+
34
+ Repeat test, but with explicit address_type parameters passed to getnewaddress
35
+ and getrawchangeaddress:
36
+ - node0 and node3 send to p2sh.
37
+ - node1 sends to bech32.
38
+ - node2 sends to legacy.
39
+
40
+ As every node sends coins after receiving, this also
41
+ verifies that spending coins sent to all these address types works.
42
+
43
+ ## Change type test
44
+
45
+ Test that the nodes generate the correct change address type:
46
+ - node0 always uses a legacy change address.
47
+ - node1 uses a bech32 addresses for change if any destination address is bech32.
48
+ - node2 always uses a bech32 address for change
49
+ - node3 always uses a bech32 address for change
50
+ - node4 always uses p2sh/segwit output for change.
51
+ """
28
52
29
53
from decimal import Decimal
30
54
import itertools
31
55
32
56
from test_framework .test_framework import BitcoinTestFramework
33
- from test_framework .util import assert_equal , assert_greater_than , connect_nodes_bi , sync_blocks , sync_mempools
57
+ from test_framework .util import (
58
+ assert_equal ,
59
+ assert_greater_than ,
60
+ assert_raises_rpc_error ,
61
+ connect_nodes_bi ,
62
+ sync_blocks ,
63
+ sync_mempools ,
64
+ )
34
65
35
66
class AddressTypeTest (BitcoinTestFramework ):
36
67
def set_test_params (self ):
37
- self .num_nodes = 5
38
- self .extra_args = [["-addresstype=legacy" ], ["-addresstype=p2sh-segwit" ], ["-addresstype=p2sh-segwit" , "-changetype=bech32" ], ["-addresstype=bech32" ], []]
68
+ self .num_nodes = 6
69
+ self .extra_args = [
70
+ ["-addresstype=legacy" ],
71
+ ["-addresstype=p2sh-segwit" ],
72
+ ["-addresstype=p2sh-segwit" , "-changetype=bech32" ],
73
+ ["-addresstype=bech32" ],
74
+ ["-changetype=p2sh-segwit" ],
75
+ []
76
+ ]
39
77
40
78
def setup_network (self ):
41
79
self .setup_nodes ()
@@ -104,10 +142,26 @@ def test_address(self, node, address, multisig, typ):
104
142
# Unknown type
105
143
assert (False )
106
144
145
+ def test_change_output_type (self , node_sender , destinations , expected_type ):
146
+ txid = self .nodes [node_sender ].sendmany (fromaccount = "" , amounts = dict .fromkeys (destinations , 0.001 ))
147
+ raw_tx = self .nodes [node_sender ].getrawtransaction (txid )
148
+ tx = self .nodes [node_sender ].decoderawtransaction (raw_tx )
149
+
150
+ # Make sure the transaction has change:
151
+ assert_equal (len (tx ["vout" ]), len (destinations ) + 1 )
152
+
153
+ # Make sure the destinations are included, and remove them:
154
+ output_addresses = [vout ['scriptPubKey' ]['addresses' ][0 ] for vout in tx ["vout" ]]
155
+ change_addresses = [d for d in output_addresses if d not in destinations ]
156
+ assert_equal (len (change_addresses ), 1 )
157
+
158
+ self .log .debug ("Check if change address " + change_addresses [0 ] + " is " + expected_type )
159
+ self .test_address (node_sender , change_addresses [0 ], multisig = False , typ = expected_type )
160
+
107
161
def run_test (self ):
108
- # Mine 101 blocks on node4 to bring nodes out of IBD and make sure that
162
+ # Mine 101 blocks on node5 to bring nodes out of IBD and make sure that
109
163
# no coinbases are maturing for the nodes-under-test during the test
110
- self .nodes [4 ].generate (101 )
164
+ self .nodes [5 ].generate (101 )
111
165
sync_blocks (self .nodes )
112
166
113
167
uncompressed_1 = "0496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858ee"
@@ -182,8 +236,8 @@ def run_test(self):
182
236
to_node %= 4
183
237
assert_equal (unconf_balances [to_node ], to_send * 10 * (2 + n ))
184
238
185
- # node4 collects fee and block subsidy to keep accounting simple
186
- self .nodes [4 ].generate (1 )
239
+ # node5 collects fee and block subsidy to keep accounting simple
240
+ self .nodes [5 ].generate (1 )
187
241
sync_blocks (self .nodes )
188
242
189
243
new_balances = self .get_balances ()
@@ -195,5 +249,46 @@ def run_test(self):
195
249
to_node %= 4
196
250
assert_equal (new_balances [to_node ], old_balances [to_node ] + to_send * 10 * (2 + n ))
197
251
252
+ # Get one p2sh/segwit address from node2 and two bech32 addresses from node3:
253
+ to_address_p2sh = self .nodes [2 ].getnewaddress ()
254
+ to_address_bech32_1 = self .nodes [3 ].getnewaddress ()
255
+ to_address_bech32_2 = self .nodes [3 ].getnewaddress ()
256
+
257
+ # Fund node 4:
258
+ self .nodes [5 ].sendtoaddress (self .nodes [4 ].getnewaddress (), Decimal ("1" ))
259
+ self .nodes [5 ].generate (1 )
260
+ sync_blocks (self .nodes )
261
+ assert_equal (self .nodes [4 ].getbalance (), 1 )
262
+
263
+ self .log .info ("Nodes with addresstype=legacy never use a P2WPKH change output" )
264
+ self .test_change_output_type (0 , [to_address_bech32_1 ], 'legacy' )
265
+
266
+ self .log .info ("Nodes with addresstype=p2sh-segwit only use a P2WPKH change output if any destination address is bech32:" )
267
+ self .test_change_output_type (1 , [to_address_p2sh ], 'p2sh-segwit' )
268
+ self .test_change_output_type (1 , [to_address_bech32_1 ], 'bech32' )
269
+ self .test_change_output_type (1 , [to_address_p2sh , to_address_bech32_1 ], 'bech32' )
270
+ self .test_change_output_type (1 , [to_address_bech32_1 , to_address_bech32_2 ], 'bech32' )
271
+
272
+ self .log .info ("Nodes with change_type=bech32 always use a P2WPKH change output:" )
273
+ self .test_change_output_type (2 , [to_address_bech32_1 ], 'bech32' )
274
+ self .test_change_output_type (2 , [to_address_p2sh ], 'bech32' )
275
+
276
+ self .log .info ("Nodes with addresstype=bech32 always use a P2WPKH change output (unless changetype is set otherwise):" )
277
+ self .test_change_output_type (3 , [to_address_bech32_1 ], 'bech32' )
278
+ self .test_change_output_type (3 , [to_address_p2sh ], 'bech32' )
279
+
280
+ self .log .info ('getrawchangeaddress defaults to addresstype if -changetype is not set and argument is absent' )
281
+ self .test_address (3 , self .nodes [3 ].getrawchangeaddress (), multisig = False , typ = 'bech32' )
282
+
283
+ self .log .info ('getrawchangeaddress fails with invalid changetype argument' )
284
+ assert_raises_rpc_error (- 5 , "Unknown address type 'bech23'" , self .nodes [3 ].getrawchangeaddress , 'bech23' )
285
+
286
+ self .log .info ("Nodes with changetype=p2sh-segwit never use a P2WPKH change output" )
287
+ self .test_change_output_type (4 , [to_address_bech32_1 ], 'p2sh-segwit' )
288
+ self .test_address (4 , self .nodes [4 ].getrawchangeaddress (), multisig = False , typ = 'p2sh-segwit' )
289
+ self .log .info ("Except for getrawchangeaddress if specified:" )
290
+ self .test_address (4 , self .nodes [4 ].getrawchangeaddress (), multisig = False , typ = 'p2sh-segwit' )
291
+ self .test_address (4 , self .nodes [4 ].getrawchangeaddress ('bech32' ), multisig = False , typ = 'bech32' )
292
+
198
293
if __name__ == '__main__' :
199
294
AddressTypeTest ().main ()
0 commit comments