Merge #11121: TestNode tidyups
[bitcoinplatinum.git] / test / functional / importmulti.py
blob32f555c79befc3e0f6ee5eb7a6f0af40f7946578
1 #!/usr/bin/env python3
2 # Copyright (c) 2014-2016 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 """Test the importmulti RPC."""
6 from test_framework.test_framework import BitcoinTestFramework
7 from test_framework.util import *
9 class ImportMultiTest (BitcoinTestFramework):
10 def set_test_params(self):
11 self.num_nodes = 2
12 self.setup_clean_chain = True
14 def setup_network(self):
15 self.setup_nodes()
17 def run_test (self):
18 self.log.info("Mining blocks...")
19 self.nodes[0].generate(1)
20 self.nodes[1].generate(1)
21 timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
23 node0_address1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
25 #Check only one address
26 assert_equal(node0_address1['ismine'], True)
28 #Node 1 sync test
29 assert_equal(self.nodes[1].getblockcount(),1)
31 #Address Test - before import
32 address_info = self.nodes[1].validateaddress(node0_address1['address'])
33 assert_equal(address_info['iswatchonly'], False)
34 assert_equal(address_info['ismine'], False)
37 # RPC importmulti -----------------------------------------------
39 # Bitcoin Address
40 self.log.info("Should import an address")
41 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
42 result = self.nodes[1].importmulti([{
43 "scriptPubKey": {
44 "address": address['address']
46 "timestamp": "now",
47 }])
48 assert_equal(result[0]['success'], True)
49 address_assert = self.nodes[1].validateaddress(address['address'])
50 assert_equal(address_assert['iswatchonly'], True)
51 assert_equal(address_assert['ismine'], False)
52 assert_equal(address_assert['timestamp'], timestamp)
53 watchonly_address = address['address']
54 watchonly_timestamp = timestamp
56 self.log.info("Should not import an invalid address")
57 result = self.nodes[1].importmulti([{
58 "scriptPubKey": {
59 "address": "not valid address",
61 "timestamp": "now",
62 }])
63 assert_equal(result[0]['success'], False)
64 assert_equal(result[0]['error']['code'], -5)
65 assert_equal(result[0]['error']['message'], 'Invalid address')
67 # ScriptPubKey + internal
68 self.log.info("Should import a scriptPubKey with internal flag")
69 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
70 result = self.nodes[1].importmulti([{
71 "scriptPubKey": address['scriptPubKey'],
72 "timestamp": "now",
73 "internal": True
74 }])
75 assert_equal(result[0]['success'], True)
76 address_assert = self.nodes[1].validateaddress(address['address'])
77 assert_equal(address_assert['iswatchonly'], True)
78 assert_equal(address_assert['ismine'], False)
79 assert_equal(address_assert['timestamp'], timestamp)
81 # ScriptPubKey + !internal
82 self.log.info("Should not import a scriptPubKey without internal flag")
83 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
84 result = self.nodes[1].importmulti([{
85 "scriptPubKey": address['scriptPubKey'],
86 "timestamp": "now",
87 }])
88 assert_equal(result[0]['success'], False)
89 assert_equal(result[0]['error']['code'], -8)
90 assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey')
91 address_assert = self.nodes[1].validateaddress(address['address'])
92 assert_equal(address_assert['iswatchonly'], False)
93 assert_equal(address_assert['ismine'], False)
94 assert_equal('timestamp' in address_assert, False)
97 # Address + Public key + !Internal
98 self.log.info("Should import an address with public key")
99 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
100 result = self.nodes[1].importmulti([{
101 "scriptPubKey": {
102 "address": address['address']
104 "timestamp": "now",
105 "pubkeys": [ address['pubkey'] ]
107 assert_equal(result[0]['success'], True)
108 address_assert = self.nodes[1].validateaddress(address['address'])
109 assert_equal(address_assert['iswatchonly'], True)
110 assert_equal(address_assert['ismine'], False)
111 assert_equal(address_assert['timestamp'], timestamp)
114 # ScriptPubKey + Public key + internal
115 self.log.info("Should import a scriptPubKey with internal and with public key")
116 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
117 request = [{
118 "scriptPubKey": address['scriptPubKey'],
119 "timestamp": "now",
120 "pubkeys": [ address['pubkey'] ],
121 "internal": True
123 result = self.nodes[1].importmulti(request)
124 assert_equal(result[0]['success'], True)
125 address_assert = self.nodes[1].validateaddress(address['address'])
126 assert_equal(address_assert['iswatchonly'], True)
127 assert_equal(address_assert['ismine'], False)
128 assert_equal(address_assert['timestamp'], timestamp)
130 # ScriptPubKey + Public key + !internal
131 self.log.info("Should not import a scriptPubKey without internal and with public key")
132 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
133 request = [{
134 "scriptPubKey": address['scriptPubKey'],
135 "timestamp": "now",
136 "pubkeys": [ address['pubkey'] ]
138 result = self.nodes[1].importmulti(request)
139 assert_equal(result[0]['success'], False)
140 assert_equal(result[0]['error']['code'], -8)
141 assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey')
142 address_assert = self.nodes[1].validateaddress(address['address'])
143 assert_equal(address_assert['iswatchonly'], False)
144 assert_equal(address_assert['ismine'], False)
145 assert_equal('timestamp' in address_assert, False)
147 # Address + Private key + !watchonly
148 self.log.info("Should import an address with private key")
149 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
150 result = self.nodes[1].importmulti([{
151 "scriptPubKey": {
152 "address": address['address']
154 "timestamp": "now",
155 "keys": [ self.nodes[0].dumpprivkey(address['address']) ]
157 assert_equal(result[0]['success'], True)
158 address_assert = self.nodes[1].validateaddress(address['address'])
159 assert_equal(address_assert['iswatchonly'], False)
160 assert_equal(address_assert['ismine'], True)
161 assert_equal(address_assert['timestamp'], timestamp)
163 # Address + Private key + watchonly
164 self.log.info("Should not import an address with private key and with watchonly")
165 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
166 result = self.nodes[1].importmulti([{
167 "scriptPubKey": {
168 "address": address['address']
170 "timestamp": "now",
171 "keys": [ self.nodes[0].dumpprivkey(address['address']) ],
172 "watchonly": True
174 assert_equal(result[0]['success'], False)
175 assert_equal(result[0]['error']['code'], -8)
176 assert_equal(result[0]['error']['message'], 'Incompatibility found between watchonly and keys')
177 address_assert = self.nodes[1].validateaddress(address['address'])
178 assert_equal(address_assert['iswatchonly'], False)
179 assert_equal(address_assert['ismine'], False)
180 assert_equal('timestamp' in address_assert, False)
182 # ScriptPubKey + Private key + internal
183 self.log.info("Should import a scriptPubKey with internal and with private key")
184 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
185 result = self.nodes[1].importmulti([{
186 "scriptPubKey": address['scriptPubKey'],
187 "timestamp": "now",
188 "keys": [ self.nodes[0].dumpprivkey(address['address']) ],
189 "internal": True
191 assert_equal(result[0]['success'], True)
192 address_assert = self.nodes[1].validateaddress(address['address'])
193 assert_equal(address_assert['iswatchonly'], False)
194 assert_equal(address_assert['ismine'], True)
195 assert_equal(address_assert['timestamp'], timestamp)
197 # ScriptPubKey + Private key + !internal
198 self.log.info("Should not import a scriptPubKey without internal and with private key")
199 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
200 result = self.nodes[1].importmulti([{
201 "scriptPubKey": address['scriptPubKey'],
202 "timestamp": "now",
203 "keys": [ self.nodes[0].dumpprivkey(address['address']) ]
205 assert_equal(result[0]['success'], False)
206 assert_equal(result[0]['error']['code'], -8)
207 assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey')
208 address_assert = self.nodes[1].validateaddress(address['address'])
209 assert_equal(address_assert['iswatchonly'], False)
210 assert_equal(address_assert['ismine'], False)
211 assert_equal('timestamp' in address_assert, False)
214 # P2SH address
215 sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
216 sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
217 sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
218 multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['address'], sig_address_2['address'], sig_address_3['pubkey']])
219 self.nodes[1].generate(100)
220 transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
221 self.nodes[1].generate(1)
222 timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
224 self.log.info("Should import a p2sh")
225 result = self.nodes[1].importmulti([{
226 "scriptPubKey": {
227 "address": multi_sig_script['address']
229 "timestamp": "now",
231 assert_equal(result[0]['success'], True)
232 address_assert = self.nodes[1].validateaddress(multi_sig_script['address'])
233 assert_equal(address_assert['isscript'], True)
234 assert_equal(address_assert['iswatchonly'], True)
235 assert_equal(address_assert['timestamp'], timestamp)
236 p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0]
237 assert_equal(p2shunspent['spendable'], False)
238 assert_equal(p2shunspent['solvable'], False)
241 # P2SH + Redeem script
242 sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
243 sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
244 sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
245 multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['address'], sig_address_2['address'], sig_address_3['pubkey']])
246 self.nodes[1].generate(100)
247 transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
248 self.nodes[1].generate(1)
249 timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
251 self.log.info("Should import a p2sh with respective redeem script")
252 result = self.nodes[1].importmulti([{
253 "scriptPubKey": {
254 "address": multi_sig_script['address']
256 "timestamp": "now",
257 "redeemscript": multi_sig_script['redeemScript']
259 assert_equal(result[0]['success'], True)
260 address_assert = self.nodes[1].validateaddress(multi_sig_script['address'])
261 assert_equal(address_assert['timestamp'], timestamp)
263 p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0]
264 assert_equal(p2shunspent['spendable'], False)
265 assert_equal(p2shunspent['solvable'], True)
268 # P2SH + Redeem script + Private Keys + !Watchonly
269 sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
270 sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
271 sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
272 multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['address'], sig_address_2['address'], sig_address_3['pubkey']])
273 self.nodes[1].generate(100)
274 transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
275 self.nodes[1].generate(1)
276 timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
278 self.log.info("Should import a p2sh with respective redeem script and private keys")
279 result = self.nodes[1].importmulti([{
280 "scriptPubKey": {
281 "address": multi_sig_script['address']
283 "timestamp": "now",
284 "redeemscript": multi_sig_script['redeemScript'],
285 "keys": [ self.nodes[0].dumpprivkey(sig_address_1['address']), self.nodes[0].dumpprivkey(sig_address_2['address'])]
287 assert_equal(result[0]['success'], True)
288 address_assert = self.nodes[1].validateaddress(multi_sig_script['address'])
289 assert_equal(address_assert['timestamp'], timestamp)
291 p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0]
292 assert_equal(p2shunspent['spendable'], False)
293 assert_equal(p2shunspent['solvable'], True)
295 # P2SH + Redeem script + Private Keys + Watchonly
296 sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
297 sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
298 sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
299 multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['address'], sig_address_2['address'], sig_address_3['pubkey']])
300 self.nodes[1].generate(100)
301 transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
302 self.nodes[1].generate(1)
303 timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
305 self.log.info("Should import a p2sh with respective redeem script and private keys")
306 result = self.nodes[1].importmulti([{
307 "scriptPubKey": {
308 "address": multi_sig_script['address']
310 "timestamp": "now",
311 "redeemscript": multi_sig_script['redeemScript'],
312 "keys": [ self.nodes[0].dumpprivkey(sig_address_1['address']), self.nodes[0].dumpprivkey(sig_address_2['address'])],
313 "watchonly": True
315 assert_equal(result[0]['success'], False)
316 assert_equal(result[0]['error']['code'], -8)
317 assert_equal(result[0]['error']['message'], 'Incompatibility found between watchonly and keys')
320 # Address + Public key + !Internal + Wrong pubkey
321 self.log.info("Should not import an address with a wrong public key")
322 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
323 address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
324 result = self.nodes[1].importmulti([{
325 "scriptPubKey": {
326 "address": address['address']
328 "timestamp": "now",
329 "pubkeys": [ address2['pubkey'] ]
331 assert_equal(result[0]['success'], False)
332 assert_equal(result[0]['error']['code'], -5)
333 assert_equal(result[0]['error']['message'], 'Consistency check failed')
334 address_assert = self.nodes[1].validateaddress(address['address'])
335 assert_equal(address_assert['iswatchonly'], False)
336 assert_equal(address_assert['ismine'], False)
337 assert_equal('timestamp' in address_assert, False)
340 # ScriptPubKey + Public key + internal + Wrong pubkey
341 self.log.info("Should not import a scriptPubKey with internal and with a wrong public key")
342 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
343 address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
344 request = [{
345 "scriptPubKey": address['scriptPubKey'],
346 "timestamp": "now",
347 "pubkeys": [ address2['pubkey'] ],
348 "internal": True
350 result = self.nodes[1].importmulti(request)
351 assert_equal(result[0]['success'], False)
352 assert_equal(result[0]['error']['code'], -5)
353 assert_equal(result[0]['error']['message'], 'Consistency check failed')
354 address_assert = self.nodes[1].validateaddress(address['address'])
355 assert_equal(address_assert['iswatchonly'], False)
356 assert_equal(address_assert['ismine'], False)
357 assert_equal('timestamp' in address_assert, False)
360 # Address + Private key + !watchonly + Wrong private key
361 self.log.info("Should not import an address with a wrong private key")
362 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
363 address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
364 result = self.nodes[1].importmulti([{
365 "scriptPubKey": {
366 "address": address['address']
368 "timestamp": "now",
369 "keys": [ self.nodes[0].dumpprivkey(address2['address']) ]
371 assert_equal(result[0]['success'], False)
372 assert_equal(result[0]['error']['code'], -5)
373 assert_equal(result[0]['error']['message'], 'Consistency check failed')
374 address_assert = self.nodes[1].validateaddress(address['address'])
375 assert_equal(address_assert['iswatchonly'], False)
376 assert_equal(address_assert['ismine'], False)
377 assert_equal('timestamp' in address_assert, False)
380 # ScriptPubKey + Private key + internal + Wrong private key
381 self.log.info("Should not import a scriptPubKey with internal and with a wrong private key")
382 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
383 address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
384 result = self.nodes[1].importmulti([{
385 "scriptPubKey": address['scriptPubKey'],
386 "timestamp": "now",
387 "keys": [ self.nodes[0].dumpprivkey(address2['address']) ],
388 "internal": True
390 assert_equal(result[0]['success'], False)
391 assert_equal(result[0]['error']['code'], -5)
392 assert_equal(result[0]['error']['message'], 'Consistency check failed')
393 address_assert = self.nodes[1].validateaddress(address['address'])
394 assert_equal(address_assert['iswatchonly'], False)
395 assert_equal(address_assert['ismine'], False)
396 assert_equal('timestamp' in address_assert, False)
399 # Importing existing watch only address with new timestamp should replace saved timestamp.
400 assert_greater_than(timestamp, watchonly_timestamp)
401 self.log.info("Should replace previously saved watch only timestamp.")
402 result = self.nodes[1].importmulti([{
403 "scriptPubKey": {
404 "address": watchonly_address,
406 "timestamp": "now",
408 assert_equal(result[0]['success'], True)
409 address_assert = self.nodes[1].validateaddress(watchonly_address)
410 assert_equal(address_assert['iswatchonly'], True)
411 assert_equal(address_assert['ismine'], False)
412 assert_equal(address_assert['timestamp'], timestamp)
413 watchonly_timestamp = timestamp
416 # restart nodes to check for proper serialization/deserialization of watch only address
417 self.stop_nodes()
418 self.start_nodes()
419 address_assert = self.nodes[1].validateaddress(watchonly_address)
420 assert_equal(address_assert['iswatchonly'], True)
421 assert_equal(address_assert['ismine'], False)
422 assert_equal(address_assert['timestamp'], watchonly_timestamp)
424 # Bad or missing timestamps
425 self.log.info("Should throw on invalid or missing timestamp values")
426 assert_raises_message(JSONRPCException, 'Missing required timestamp field for key',
427 self.nodes[1].importmulti, [{
428 "scriptPubKey": address['scriptPubKey'],
430 assert_raises_message(JSONRPCException, 'Expected number or "now" timestamp value for key. got type string',
431 self.nodes[1].importmulti, [{
432 "scriptPubKey": address['scriptPubKey'],
433 "timestamp": "",
437 if __name__ == '__main__':
438 ImportMultiTest ().main ()