Merge #11726: Cleanups + nit fixes for walletdir PR
[bitcoinplatinum.git] / test / functional / importmulti.py
bloba691595f15116f94c635dbc1b519b7f60a4b9433
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 self.log.info("Should not import an address with private key if is already imported")
164 result = self.nodes[1].importmulti([{
165 "scriptPubKey": {
166 "address": address['address']
168 "timestamp": "now",
169 "keys": [ self.nodes[0].dumpprivkey(address['address']) ]
171 assert_equal(result[0]['success'], False)
172 assert_equal(result[0]['error']['code'], -4)
173 assert_equal(result[0]['error']['message'], 'The wallet already contains the private key for this address or script')
175 # Address + Private key + watchonly
176 self.log.info("Should not import an address with private key and with watchonly")
177 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
178 result = self.nodes[1].importmulti([{
179 "scriptPubKey": {
180 "address": address['address']
182 "timestamp": "now",
183 "keys": [ self.nodes[0].dumpprivkey(address['address']) ],
184 "watchonly": True
186 assert_equal(result[0]['success'], False)
187 assert_equal(result[0]['error']['code'], -8)
188 assert_equal(result[0]['error']['message'], 'Incompatibility found between watchonly and keys')
189 address_assert = self.nodes[1].validateaddress(address['address'])
190 assert_equal(address_assert['iswatchonly'], False)
191 assert_equal(address_assert['ismine'], False)
192 assert_equal('timestamp' in address_assert, False)
194 # ScriptPubKey + Private key + internal
195 self.log.info("Should import a scriptPubKey with internal and with private key")
196 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
197 result = self.nodes[1].importmulti([{
198 "scriptPubKey": address['scriptPubKey'],
199 "timestamp": "now",
200 "keys": [ self.nodes[0].dumpprivkey(address['address']) ],
201 "internal": True
203 assert_equal(result[0]['success'], True)
204 address_assert = self.nodes[1].validateaddress(address['address'])
205 assert_equal(address_assert['iswatchonly'], False)
206 assert_equal(address_assert['ismine'], True)
207 assert_equal(address_assert['timestamp'], timestamp)
209 # ScriptPubKey + Private key + !internal
210 self.log.info("Should not import a scriptPubKey without internal and with private key")
211 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
212 result = self.nodes[1].importmulti([{
213 "scriptPubKey": address['scriptPubKey'],
214 "timestamp": "now",
215 "keys": [ self.nodes[0].dumpprivkey(address['address']) ]
217 assert_equal(result[0]['success'], False)
218 assert_equal(result[0]['error']['code'], -8)
219 assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey')
220 address_assert = self.nodes[1].validateaddress(address['address'])
221 assert_equal(address_assert['iswatchonly'], False)
222 assert_equal(address_assert['ismine'], False)
223 assert_equal('timestamp' in address_assert, False)
226 # P2SH address
227 sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
228 sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
229 sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
230 multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['address'], sig_address_2['address'], sig_address_3['pubkey']])
231 self.nodes[1].generate(100)
232 transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
233 self.nodes[1].generate(1)
234 timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
236 self.log.info("Should import a p2sh")
237 result = self.nodes[1].importmulti([{
238 "scriptPubKey": {
239 "address": multi_sig_script['address']
241 "timestamp": "now",
243 assert_equal(result[0]['success'], True)
244 address_assert = self.nodes[1].validateaddress(multi_sig_script['address'])
245 assert_equal(address_assert['isscript'], True)
246 assert_equal(address_assert['iswatchonly'], True)
247 assert_equal(address_assert['timestamp'], timestamp)
248 p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0]
249 assert_equal(p2shunspent['spendable'], False)
250 assert_equal(p2shunspent['solvable'], False)
253 # P2SH + Redeem script
254 sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
255 sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
256 sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
257 multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['address'], sig_address_2['address'], sig_address_3['pubkey']])
258 self.nodes[1].generate(100)
259 transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
260 self.nodes[1].generate(1)
261 timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
263 self.log.info("Should import a p2sh with respective redeem script")
264 result = self.nodes[1].importmulti([{
265 "scriptPubKey": {
266 "address": multi_sig_script['address']
268 "timestamp": "now",
269 "redeemscript": multi_sig_script['redeemScript']
271 assert_equal(result[0]['success'], True)
272 address_assert = self.nodes[1].validateaddress(multi_sig_script['address'])
273 assert_equal(address_assert['timestamp'], timestamp)
275 p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0]
276 assert_equal(p2shunspent['spendable'], False)
277 assert_equal(p2shunspent['solvable'], True)
280 # P2SH + Redeem script + Private Keys + !Watchonly
281 sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
282 sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
283 sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
284 multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['address'], sig_address_2['address'], sig_address_3['pubkey']])
285 self.nodes[1].generate(100)
286 transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
287 self.nodes[1].generate(1)
288 timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
290 self.log.info("Should import a p2sh with respective redeem script and private keys")
291 result = self.nodes[1].importmulti([{
292 "scriptPubKey": {
293 "address": multi_sig_script['address']
295 "timestamp": "now",
296 "redeemscript": multi_sig_script['redeemScript'],
297 "keys": [ self.nodes[0].dumpprivkey(sig_address_1['address']), self.nodes[0].dumpprivkey(sig_address_2['address'])]
299 assert_equal(result[0]['success'], True)
300 address_assert = self.nodes[1].validateaddress(multi_sig_script['address'])
301 assert_equal(address_assert['timestamp'], timestamp)
303 p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0]
304 assert_equal(p2shunspent['spendable'], False)
305 assert_equal(p2shunspent['solvable'], True)
307 # P2SH + Redeem script + Private Keys + Watchonly
308 sig_address_1 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
309 sig_address_2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
310 sig_address_3 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
311 multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['address'], sig_address_2['address'], sig_address_3['pubkey']])
312 self.nodes[1].generate(100)
313 transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
314 self.nodes[1].generate(1)
315 timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
317 self.log.info("Should import a p2sh with respective redeem script and private keys")
318 result = self.nodes[1].importmulti([{
319 "scriptPubKey": {
320 "address": multi_sig_script['address']
322 "timestamp": "now",
323 "redeemscript": multi_sig_script['redeemScript'],
324 "keys": [ self.nodes[0].dumpprivkey(sig_address_1['address']), self.nodes[0].dumpprivkey(sig_address_2['address'])],
325 "watchonly": True
327 assert_equal(result[0]['success'], False)
328 assert_equal(result[0]['error']['code'], -8)
329 assert_equal(result[0]['error']['message'], 'Incompatibility found between watchonly and keys')
332 # Address + Public key + !Internal + Wrong pubkey
333 self.log.info("Should not import an address with a wrong public key")
334 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
335 address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
336 result = self.nodes[1].importmulti([{
337 "scriptPubKey": {
338 "address": address['address']
340 "timestamp": "now",
341 "pubkeys": [ address2['pubkey'] ]
343 assert_equal(result[0]['success'], False)
344 assert_equal(result[0]['error']['code'], -5)
345 assert_equal(result[0]['error']['message'], 'Consistency check failed')
346 address_assert = self.nodes[1].validateaddress(address['address'])
347 assert_equal(address_assert['iswatchonly'], False)
348 assert_equal(address_assert['ismine'], False)
349 assert_equal('timestamp' in address_assert, False)
352 # ScriptPubKey + Public key + internal + Wrong pubkey
353 self.log.info("Should not import a scriptPubKey with internal and with a wrong public key")
354 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
355 address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
356 request = [{
357 "scriptPubKey": address['scriptPubKey'],
358 "timestamp": "now",
359 "pubkeys": [ address2['pubkey'] ],
360 "internal": True
362 result = self.nodes[1].importmulti(request)
363 assert_equal(result[0]['success'], False)
364 assert_equal(result[0]['error']['code'], -5)
365 assert_equal(result[0]['error']['message'], 'Consistency check failed')
366 address_assert = self.nodes[1].validateaddress(address['address'])
367 assert_equal(address_assert['iswatchonly'], False)
368 assert_equal(address_assert['ismine'], False)
369 assert_equal('timestamp' in address_assert, False)
372 # Address + Private key + !watchonly + Wrong private key
373 self.log.info("Should not import an address with a wrong private key")
374 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
375 address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
376 result = self.nodes[1].importmulti([{
377 "scriptPubKey": {
378 "address": address['address']
380 "timestamp": "now",
381 "keys": [ self.nodes[0].dumpprivkey(address2['address']) ]
383 assert_equal(result[0]['success'], False)
384 assert_equal(result[0]['error']['code'], -5)
385 assert_equal(result[0]['error']['message'], 'Consistency check failed')
386 address_assert = self.nodes[1].validateaddress(address['address'])
387 assert_equal(address_assert['iswatchonly'], False)
388 assert_equal(address_assert['ismine'], False)
389 assert_equal('timestamp' in address_assert, False)
392 # ScriptPubKey + Private key + internal + Wrong private key
393 self.log.info("Should not import a scriptPubKey with internal and with a wrong private key")
394 address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
395 address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
396 result = self.nodes[1].importmulti([{
397 "scriptPubKey": address['scriptPubKey'],
398 "timestamp": "now",
399 "keys": [ self.nodes[0].dumpprivkey(address2['address']) ],
400 "internal": True
402 assert_equal(result[0]['success'], False)
403 assert_equal(result[0]['error']['code'], -5)
404 assert_equal(result[0]['error']['message'], 'Consistency check failed')
405 address_assert = self.nodes[1].validateaddress(address['address'])
406 assert_equal(address_assert['iswatchonly'], False)
407 assert_equal(address_assert['ismine'], False)
408 assert_equal('timestamp' in address_assert, False)
411 # Importing existing watch only address with new timestamp should replace saved timestamp.
412 assert_greater_than(timestamp, watchonly_timestamp)
413 self.log.info("Should replace previously saved watch only timestamp.")
414 result = self.nodes[1].importmulti([{
415 "scriptPubKey": {
416 "address": watchonly_address,
418 "timestamp": "now",
420 assert_equal(result[0]['success'], True)
421 address_assert = self.nodes[1].validateaddress(watchonly_address)
422 assert_equal(address_assert['iswatchonly'], True)
423 assert_equal(address_assert['ismine'], False)
424 assert_equal(address_assert['timestamp'], timestamp)
425 watchonly_timestamp = timestamp
428 # restart nodes to check for proper serialization/deserialization of watch only address
429 self.stop_nodes()
430 self.start_nodes()
431 address_assert = self.nodes[1].validateaddress(watchonly_address)
432 assert_equal(address_assert['iswatchonly'], True)
433 assert_equal(address_assert['ismine'], False)
434 assert_equal(address_assert['timestamp'], watchonly_timestamp)
436 # Bad or missing timestamps
437 self.log.info("Should throw on invalid or missing timestamp values")
438 assert_raises_rpc_error(-3, 'Missing required timestamp field for key',
439 self.nodes[1].importmulti, [{
440 "scriptPubKey": address['scriptPubKey'],
442 assert_raises_rpc_error(-3, 'Expected number or "now" timestamp value for key. got type string',
443 self.nodes[1].importmulti, [{
444 "scriptPubKey": address['scriptPubKey'],
445 "timestamp": "",
449 if __name__ == '__main__':
450 ImportMultiTest ().main ()