2016-06-16 16:57:48 +02:00
#!/usr/bin/env python3
2018-07-27 00:36:45 +02:00
# Copyright (c) 2014-2018 The Bitcoin Core developers
2016-06-16 16:57:48 +02:00
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
2018-12-06 19:29:32 +01:00
""" Test the importmulti RPC.
Test importmulti by generating keys on node0 , importing the scriptPubKeys and
addresses on node1 and then testing the address info for the different address
variants .
- ` get_key ( ) ` and ` get_multisig ( ) ` are called to generate keys on node0 and
return the privkeys , pubkeys and all variants of scriptPubKey and address .
- ` test_importmulti ( ) ` is called to send an importmulti call to node1 , test
success , and ( if unsuccessful ) test the error code and error message returned .
- ` test_address ( ) ` is called to call getaddressinfo for an address on node1
and test the values returned . """
2018-12-06 00:28:32 +01:00
from collections import namedtuple
2016-11-28 23:19:27 +01:00
2018-12-06 00:28:32 +01:00
from test_framework . address import (
key_to_p2pkh ,
key_to_p2sh_p2wpkh ,
key_to_p2wpkh ,
2018-12-06 00:28:32 +01:00
script_to_p2sh ,
script_to_p2sh_p2wsh ,
script_to_p2wsh ,
2018-12-06 00:28:32 +01:00
)
2018-11-30 23:49:03 +01:00
from test_framework . script import (
CScript ,
OP_0 ,
2018-12-06 00:28:32 +01:00
OP_2 ,
OP_3 ,
OP_CHECKMULTISIG ,
2018-12-06 00:28:32 +01:00
OP_CHECKSIG ,
OP_DUP ,
OP_EQUAL ,
OP_EQUALVERIFY ,
OP_HASH160 ,
2018-11-30 23:49:03 +01:00
OP_NOP ,
2018-12-06 00:28:32 +01:00
hash160 ,
2018-12-06 00:28:32 +01:00
sha256 ,
2018-11-30 23:49:03 +01:00
)
2016-06-16 16:57:48 +02:00
from test_framework . test_framework import BitcoinTestFramework
2018-09-10 19:08:13 +02:00
from test_framework . util import (
assert_equal ,
assert_greater_than ,
assert_raises_rpc_error ,
bytes_to_hex_str ,
2018-10-09 07:43:20 +02:00
hex_str_to_bytes
2018-09-10 19:08:13 +02:00
)
2018-12-06 00:28:32 +01:00
Key = namedtuple ( ' Key ' , [ ' privkey ' ,
' pubkey ' ,
' p2pkh_script ' ,
' p2pkh_addr ' ,
' p2wpkh_script ' ,
' p2wpkh_addr ' ,
' p2sh_p2wpkh_script ' ,
' p2sh_p2wpkh_redeem_script ' ,
' p2sh_p2wpkh_addr ' ] )
2018-12-06 00:28:32 +01:00
Multisig = namedtuple ( ' Multisig ' , [ ' privkeys ' ,
' pubkeys ' ,
' p2sh_script ' ,
' p2sh_addr ' ,
' redeem_script ' ,
' p2wsh_script ' ,
' p2wsh_addr ' ,
' p2sh_p2wsh_script ' ,
' p2sh_p2wsh_addr ' ] )
2018-09-10 19:08:13 +02:00
class ImportMultiTest ( BitcoinTestFramework ) :
2017-06-10 00:21:21 +02:00
def set_test_params ( self ) :
2016-06-16 16:57:48 +02:00
self . num_nodes = 2
2017-12-01 01:49:11 +01:00
self . extra_args = [ [ " -addresstype=legacy " ] , [ " -addresstype=legacy " ] ]
2016-06-16 16:57:48 +02:00
self . setup_clean_chain = True
2018-09-09 19:32:37 +02:00
def skip_test_if_missing_module ( self ) :
self . skip_if_no_wallet ( )
2017-04-03 15:34:04 +02:00
def setup_network ( self ) :
self . setup_nodes ( )
2016-06-16 16:57:48 +02:00
2018-12-06 00:28:32 +01:00
def get_key ( self ) :
""" Generate a fresh key on node0
Returns a named tuple of privkey , pubkey and all address and scripts . """
addr = self . nodes [ 0 ] . getnewaddress ( )
pubkey = self . nodes [ 0 ] . getaddressinfo ( addr ) [ ' pubkey ' ]
pkh = hash160 ( hex_str_to_bytes ( pubkey ) )
return Key ( self . nodes [ 0 ] . dumpprivkey ( addr ) ,
pubkey ,
CScript ( [ OP_DUP , OP_HASH160 , pkh , OP_EQUALVERIFY , OP_CHECKSIG ] ) . hex ( ) , # p2pkh
key_to_p2pkh ( pubkey ) , # p2pkh addr
CScript ( [ OP_0 , pkh ] ) . hex ( ) , # p2wpkh
key_to_p2wpkh ( pubkey ) , # p2wpkh addr
CScript ( [ OP_HASH160 , hash160 ( CScript ( [ OP_0 , pkh ] ) ) , OP_EQUAL ] ) . hex ( ) , # p2sh-p2wpkh
CScript ( [ OP_0 , pkh ] ) . hex ( ) , # p2sh-p2wpkh redeem script
key_to_p2sh_p2wpkh ( pubkey ) ) # p2sh-p2wpkh addr
2018-12-06 00:28:32 +01:00
def get_multisig ( self ) :
""" Generate a fresh multisig on node0
Returns a named tuple of privkeys , pubkeys and all address and scripts . """
addrs = [ ]
pubkeys = [ ]
for _ in range ( 3 ) :
addr = self . nodes [ 0 ] . getaddressinfo ( self . nodes [ 0 ] . getnewaddress ( ) )
addrs . append ( addr [ ' address ' ] )
pubkeys . append ( addr [ ' pubkey ' ] )
script_code = CScript ( [ OP_2 ] + [ hex_str_to_bytes ( pubkey ) for pubkey in pubkeys ] + [ OP_3 , OP_CHECKMULTISIG ] )
witness_script = CScript ( [ OP_0 , sha256 ( script_code ) ] )
return Multisig ( [ self . nodes [ 0 ] . dumpprivkey ( addr ) for addr in addrs ] ,
pubkeys ,
CScript ( [ OP_HASH160 , hash160 ( script_code ) , OP_EQUAL ] ) . hex ( ) , # p2sh
script_to_p2sh ( script_code ) , # p2sh addr
script_code . hex ( ) , # redeem script
witness_script . hex ( ) , # p2wsh
script_to_p2wsh ( script_code ) , # p2wsh addr
CScript ( [ OP_HASH160 , witness_script , OP_EQUAL ] ) . hex ( ) , # p2sh-p2wsh
script_to_p2sh_p2wsh ( script_code ) ) # p2sh-p2wsh addr
2018-10-25 03:28:17 +02:00
def test_importmulti ( self , req , success , error_code = None , error_message = None , warnings = [ ] ) :
2018-12-06 15:52:38 +01:00
""" Run importmulti and assert success """
result = self . nodes [ 1 ] . importmulti ( [ req ] )
2018-10-25 03:28:17 +02:00
observed_warnings = [ ]
if ' warnings ' in result [ 0 ] :
observed_warnings = result [ 0 ] [ ' warnings ' ]
assert_equal ( " \n " . join ( sorted ( warnings ) ) , " \n " . join ( sorted ( observed_warnings ) ) )
2018-12-06 15:52:38 +01:00
assert_equal ( result [ 0 ] [ ' success ' ] , success )
if error_code is not None :
assert_equal ( result [ 0 ] [ ' error ' ] [ ' code ' ] , error_code )
assert_equal ( result [ 0 ] [ ' error ' ] [ ' message ' ] , error_message )
2018-12-06 16:20:11 +01:00
def test_address ( self , address , * * kwargs ) :
""" Get address info for `address` and test whether the returned values are as expected. """
addr_info = self . nodes [ 1 ] . getaddressinfo ( address )
for key , value in kwargs . items ( ) :
if value is None :
if key in addr_info . keys ( ) :
raise AssertionError ( " key {} unexpectedly returned in getaddressinfo. " . format ( key ) )
elif addr_info [ key ] != value :
raise AssertionError ( " key {} value {} did not match expected value {} " . format ( key , addr_info [ key ] , value ) )
2018-11-30 23:47:46 +01:00
def run_test ( self ) :
2017-03-08 00:46:17 +01:00
self . log . info ( " Mining blocks... " )
2016-06-16 16:57:48 +02:00
self . nodes [ 0 ] . generate ( 1 )
self . nodes [ 1 ] . generate ( 1 )
2016-11-08 22:55:02 +01:00
timestamp = self . nodes [ 1 ] . getblock ( self . nodes [ 1 ] . getbestblockhash ( ) ) [ ' mediantime ' ]
2016-06-16 16:57:48 +02:00
2018-02-09 17:12:27 +01:00
node0_address1 = self . nodes [ 0 ] . getaddressinfo ( self . nodes [ 0 ] . getnewaddress ( ) )
2016-06-16 16:57:48 +02:00
2018-11-30 23:47:46 +01:00
# Check only one address
2016-06-16 16:57:48 +02:00
assert_equal ( node0_address1 [ ' ismine ' ] , True )
2018-11-30 23:47:46 +01:00
# Node 1 sync test
assert_equal ( self . nodes [ 1 ] . getblockcount ( ) , 1 )
2016-06-16 16:57:48 +02:00
2018-11-30 23:47:46 +01:00
# Address Test - before import
2018-02-09 17:12:27 +01:00
address_info = self . nodes [ 1 ] . getaddressinfo ( node0_address1 [ ' address ' ] )
2016-06-16 16:57:48 +02:00
assert_equal ( address_info [ ' iswatchonly ' ] , False )
assert_equal ( address_info [ ' ismine ' ] , False )
# RPC importmulti -----------------------------------------------
2018-11-07 17:24:34 +01:00
# Bitcoin Address (implicit non-internal)
2017-03-08 00:46:17 +01:00
self . log . info ( " Should import an address " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2pkh_addr
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : address } ,
" timestamp " : " now " } ,
True )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
iswatchonly = True ,
ismine = False ,
timestamp = timestamp ,
ischange = False )
2018-12-06 00:28:32 +01:00
watchonly_address = address
2016-11-08 22:55:02 +01:00
watchonly_timestamp = timestamp
2016-06-16 16:57:48 +02:00
2017-03-08 00:46:17 +01:00
self . log . info ( " Should not import an invalid address " )
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : " not valid address " } ,
" timestamp " : " now " } ,
False ,
error_code = - 5 ,
2018-10-25 03:28:17 +02:00
error_message = ' Invalid address \" not valid address \" ' )
2016-06-16 16:57:48 +02:00
# ScriptPubKey + internal
2017-03-08 00:46:17 +01:00
self . log . info ( " Should import a scriptPubKey with internal flag " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : key . p2pkh_script ,
" timestamp " : " now " ,
" internal " : True } ,
True )
2018-12-06 16:20:11 +01:00
self . test_address ( key . p2pkh_addr ,
iswatchonly = True ,
ismine = False ,
timestamp = timestamp ,
ischange = True )
2016-06-16 16:57:48 +02:00
2018-10-09 07:43:20 +02:00
# ScriptPubKey + internal + label
self . log . info ( " Should not allow a label to be specified when internal is true " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : key . p2pkh_script ,
" timestamp " : " now " ,
" internal " : True ,
" label " : " Example label " } ,
False ,
error_code = - 8 ,
error_message = ' Internal addresses should not have a label ' )
2018-10-09 07:43:20 +02:00
2016-11-28 23:19:27 +01:00
# Nonstandard scriptPubKey + !internal
self . log . info ( " Should not import a nonstandard scriptPubKey without internal flag " )
2018-12-06 00:28:32 +01:00
nonstandardScriptPubKey = key . p2pkh_script + bytes_to_hex_str ( CScript ( [ OP_NOP ] ) )
key = self . get_key ( )
address = key . p2pkh_addr
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : nonstandardScriptPubKey ,
" timestamp " : " now " } ,
False ,
error_code = - 8 ,
error_message = ' Internal must be set to true for nonstandard scriptPubKey imports. ' )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
iswatchonly = False ,
ismine = False ,
timestamp = None )
2016-06-16 16:57:48 +02:00
2018-11-07 17:24:34 +01:00
# Address + Public key + !Internal(explicit)
2017-03-08 00:46:17 +01:00
self . log . info ( " Should import an address with public key " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2pkh_addr
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : address } ,
" timestamp " : " now " ,
" pubkeys " : [ key . pubkey ] ,
" internal " : False } ,
2018-10-25 03:28:17 +02:00
True ,
warnings = [ " Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag. " ] )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
iswatchonly = True ,
ismine = False ,
timestamp = timestamp )
2016-06-16 16:57:48 +02:00
# ScriptPubKey + Public key + internal
2017-03-08 00:46:17 +01:00
self . log . info ( " Should import a scriptPubKey with internal and with public key " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2pkh_addr
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : key . p2pkh_script ,
" timestamp " : " now " ,
" pubkeys " : [ key . pubkey ] ,
" internal " : True } ,
2018-10-25 03:28:17 +02:00
True ,
warnings = [ " Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag. " ] )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
iswatchonly = True ,
ismine = False ,
timestamp = timestamp )
2016-06-16 16:57:48 +02:00
2016-11-28 23:19:27 +01:00
# Nonstandard scriptPubKey + Public key + !internal
self . log . info ( " Should not import a nonstandard scriptPubKey without internal and with public key " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2pkh_addr
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : nonstandardScriptPubKey ,
" timestamp " : " now " ,
" pubkeys " : [ key . pubkey ] } ,
False ,
error_code = - 8 ,
error_message = ' Internal must be set to true for nonstandard scriptPubKey imports. ' )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
iswatchonly = False ,
ismine = False ,
timestamp = None )
2016-06-16 16:57:48 +02:00
# Address + Private key + !watchonly
2017-03-08 00:46:17 +01:00
self . log . info ( " Should import an address with private key " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2pkh_addr
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : address } ,
" timestamp " : " now " ,
" keys " : [ key . privkey ] } ,
True )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
iswatchonly = False ,
ismine = True ,
timestamp = timestamp )
2016-06-16 16:57:48 +02:00
2017-10-11 12:12:59 +02:00
self . log . info ( " Should not import an address with private key if is already imported " )
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : address } ,
" timestamp " : " now " ,
" keys " : [ key . privkey ] } ,
False ,
error_code = - 4 ,
error_message = ' The wallet already contains the private key for this address or script ' )
2017-10-11 12:12:59 +02:00
2016-06-16 16:57:48 +02:00
# Address + Private key + watchonly
2018-10-25 03:28:17 +02:00
self . log . info ( " Should import an address with private key and with watchonly " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2pkh_addr
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : address } ,
" timestamp " : " now " ,
" keys " : [ key . privkey ] ,
" watchonly " : True } ,
2018-10-25 03:28:17 +02:00
True ,
warnings = [ " All private keys are provided, outputs will be considered spendable. If this is intentional, do not specify the watchonly flag. " ] )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
iswatchonly = False ,
2018-10-25 03:28:17 +02:00
ismine = True ,
timestamp = timestamp )
2016-06-16 16:57:48 +02:00
# ScriptPubKey + Private key + internal
2017-03-08 00:46:17 +01:00
self . log . info ( " Should import a scriptPubKey with internal and with private key " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2pkh_addr
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : key . p2pkh_script ,
" timestamp " : " now " ,
" keys " : [ key . privkey ] ,
" internal " : True } ,
True )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
iswatchonly = False ,
ismine = True ,
timestamp = timestamp )
2016-06-16 16:57:48 +02:00
2016-11-28 23:19:27 +01:00
# Nonstandard scriptPubKey + Private key + !internal
self . log . info ( " Should not import a nonstandard scriptPubKey without internal and with private key " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2pkh_addr
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : nonstandardScriptPubKey ,
" timestamp " : " now " ,
" keys " : [ key . privkey ] } ,
False ,
error_code = - 8 ,
error_message = ' Internal must be set to true for nonstandard scriptPubKey imports. ' )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
iswatchonly = False ,
ismine = False ,
timestamp = None )
2016-06-16 16:57:48 +02:00
# P2SH address
2018-12-06 00:28:32 +01:00
multisig = self . get_multisig ( )
2016-06-16 16:57:48 +02:00
self . nodes [ 1 ] . generate ( 100 )
2018-12-06 00:28:32 +01:00
self . nodes [ 1 ] . sendtoaddress ( multisig . p2sh_addr , 10.00 )
2016-06-16 16:57:48 +02:00
self . nodes [ 1 ] . generate ( 1 )
2016-11-08 22:55:02 +01:00
timestamp = self . nodes [ 1 ] . getblock ( self . nodes [ 1 ] . getbestblockhash ( ) ) [ ' mediantime ' ]
2016-06-16 16:57:48 +02:00
2017-03-08 00:46:17 +01:00
self . log . info ( " Should import a p2sh " )
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : multisig . p2sh_addr } ,
" timestamp " : " now " } ,
True )
2018-12-06 16:20:11 +01:00
self . test_address ( multisig . p2sh_addr ,
isscript = True ,
iswatchonly = True ,
timestamp = timestamp )
2018-12-06 00:28:32 +01:00
p2shunspent = self . nodes [ 1 ] . listunspent ( 0 , 999999 , [ multisig . p2sh_addr ] ) [ 0 ]
2016-06-16 16:57:48 +02:00
assert_equal ( p2shunspent [ ' spendable ' ] , False )
assert_equal ( p2shunspent [ ' solvable ' ] , False )
# P2SH + Redeem script
2018-12-06 00:28:32 +01:00
multisig = self . get_multisig ( )
2016-06-16 16:57:48 +02:00
self . nodes [ 1 ] . generate ( 100 )
2018-12-06 00:28:32 +01:00
self . nodes [ 1 ] . sendtoaddress ( multisig . p2sh_addr , 10.00 )
2016-06-16 16:57:48 +02:00
self . nodes [ 1 ] . generate ( 1 )
2016-11-08 22:55:02 +01:00
timestamp = self . nodes [ 1 ] . getblock ( self . nodes [ 1 ] . getbestblockhash ( ) ) [ ' mediantime ' ]
2016-06-16 16:57:48 +02:00
2017-03-08 00:46:17 +01:00
self . log . info ( " Should import a p2sh with respective redeem script " )
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : multisig . p2sh_addr } ,
" timestamp " : " now " ,
" redeemscript " : multisig . redeem_script } ,
2018-10-25 03:28:17 +02:00
True ,
warnings = [ " Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag. " ] )
self . test_address ( multisig . p2sh_addr , timestamp = timestamp , iswatchonly = True , ismine = False , solvable = True )
2016-06-16 16:57:48 +02:00
2018-12-06 00:28:32 +01:00
p2shunspent = self . nodes [ 1 ] . listunspent ( 0 , 999999 , [ multisig . p2sh_addr ] ) [ 0 ]
2016-06-16 16:57:48 +02:00
assert_equal ( p2shunspent [ ' spendable ' ] , False )
assert_equal ( p2shunspent [ ' solvable ' ] , True )
# P2SH + Redeem script + Private Keys + !Watchonly
2018-12-06 00:28:32 +01:00
multisig = self . get_multisig ( )
2016-06-16 16:57:48 +02:00
self . nodes [ 1 ] . generate ( 100 )
2018-12-06 00:28:32 +01:00
self . nodes [ 1 ] . sendtoaddress ( multisig . p2sh_addr , 10.00 )
2016-06-16 16:57:48 +02:00
self . nodes [ 1 ] . generate ( 1 )
2016-11-08 22:55:02 +01:00
timestamp = self . nodes [ 1 ] . getblock ( self . nodes [ 1 ] . getbestblockhash ( ) ) [ ' mediantime ' ]
2016-06-16 16:57:48 +02:00
2017-03-08 00:46:17 +01:00
self . log . info ( " Should import a p2sh with respective redeem script and private keys " )
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : multisig . p2sh_addr } ,
" timestamp " : " now " ,
" redeemscript " : multisig . redeem_script ,
" keys " : multisig . privkeys [ 0 : 2 ] } ,
2018-10-25 03:28:17 +02:00
True ,
warnings = [ " Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag. " ] )
2018-12-06 16:20:11 +01:00
self . test_address ( multisig . p2sh_addr ,
2018-10-25 03:28:17 +02:00
timestamp = timestamp ,
ismine = False ,
iswatchonly = True ,
solvable = True )
2016-06-16 16:57:48 +02:00
2018-12-06 00:28:32 +01:00
p2shunspent = self . nodes [ 1 ] . listunspent ( 0 , 999999 , [ multisig . p2sh_addr ] ) [ 0 ]
2016-06-16 16:57:48 +02:00
assert_equal ( p2shunspent [ ' spendable ' ] , False )
assert_equal ( p2shunspent [ ' solvable ' ] , True )
# P2SH + Redeem script + Private Keys + Watchonly
2018-12-06 00:28:32 +01:00
multisig = self . get_multisig ( )
2016-06-16 16:57:48 +02:00
self . nodes [ 1 ] . generate ( 100 )
2018-12-06 00:28:32 +01:00
self . nodes [ 1 ] . sendtoaddress ( multisig . p2sh_addr , 10.00 )
2016-06-16 16:57:48 +02:00
self . nodes [ 1 ] . generate ( 1 )
2017-02-21 16:53:07 +01:00
timestamp = self . nodes [ 1 ] . getblock ( self . nodes [ 1 ] . getbestblockhash ( ) ) [ ' mediantime ' ]
2016-06-16 16:57:48 +02:00
2017-03-08 00:46:17 +01:00
self . log . info ( " Should import a p2sh with respective redeem script and private keys " )
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : multisig . p2sh_addr } ,
" timestamp " : " now " ,
" redeemscript " : multisig . redeem_script ,
" keys " : multisig . privkeys [ 0 : 2 ] ,
" watchonly " : True } ,
2018-10-25 03:28:17 +02:00
True )
self . test_address ( multisig . p2sh_addr ,
iswatchonly = True ,
ismine = False ,
solvable = True ,
timestamp = timestamp )
2016-06-16 16:57:48 +02:00
2016-10-19 16:17:42 +02:00
# Address + Public key + !Internal + Wrong pubkey
2018-10-25 03:28:17 +02:00
self . log . info ( " Should not import an address with the wrong public key as non-solvable " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2pkh_addr
wrong_key = self . get_key ( ) . pubkey
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : address } ,
" timestamp " : " now " ,
" pubkeys " : [ wrong_key ] } ,
2018-10-25 03:28:17 +02:00
True ,
warnings = [ " Importing as non-solvable: some required keys are missing. If this is intentional, don ' t provide any keys, pubkeys, witnessscript, or redeemscript. " , " Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag. " ] )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
2018-10-25 03:28:17 +02:00
iswatchonly = True ,
2018-12-06 16:20:11 +01:00
ismine = False ,
2018-10-25 03:28:17 +02:00
solvable = False ,
timestamp = timestamp )
2016-10-19 16:17:42 +02:00
# ScriptPubKey + Public key + internal + Wrong pubkey
2018-10-25 03:28:17 +02:00
self . log . info ( " Should import a scriptPubKey with internal and with a wrong public key as non-solvable " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2pkh_addr
wrong_key = self . get_key ( ) . pubkey
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : key . p2pkh_script ,
" timestamp " : " now " ,
" pubkeys " : [ wrong_key ] ,
" internal " : True } ,
2018-10-25 03:28:17 +02:00
True ,
warnings = [ " Importing as non-solvable: some required keys are missing. If this is intentional, don ' t provide any keys, pubkeys, witnessscript, or redeemscript. " , " Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag. " ] )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
2018-10-25 03:28:17 +02:00
iswatchonly = True ,
2018-12-06 16:20:11 +01:00
ismine = False ,
2018-10-25 03:28:17 +02:00
solvable = False ,
timestamp = timestamp )
2016-06-16 16:57:48 +02:00
2016-10-19 16:17:42 +02:00
# Address + Private key + !watchonly + Wrong private key
2018-10-25 03:28:17 +02:00
self . log . info ( " Should import an address with a wrong private key as non-solvable " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2pkh_addr
wrong_privkey = self . get_key ( ) . privkey
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : address } ,
" timestamp " : " now " ,
" keys " : [ wrong_privkey ] } ,
2018-10-25 03:28:17 +02:00
True ,
warnings = [ " Importing as non-solvable: some required keys are missing. If this is intentional, don ' t provide any keys, pubkeys, witnessscript, or redeemscript. " , " Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag. " ] )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
2018-10-25 03:28:17 +02:00
iswatchonly = True ,
2018-12-06 16:20:11 +01:00
ismine = False ,
2018-10-25 03:28:17 +02:00
solvable = False ,
timestamp = timestamp )
2016-10-19 16:17:42 +02:00
# ScriptPubKey + Private key + internal + Wrong private key
2018-10-25 03:28:17 +02:00
self . log . info ( " Should import a scriptPubKey with internal and with a wrong private key as non-solvable " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2pkh_addr
wrong_privkey = self . get_key ( ) . privkey
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : key . p2pkh_script ,
" timestamp " : " now " ,
" keys " : [ wrong_privkey ] ,
" internal " : True } ,
2018-10-25 03:28:17 +02:00
True ,
warnings = [ " Importing as non-solvable: some required keys are missing. If this is intentional, don ' t provide any keys, pubkeys, witnessscript, or redeemscript. " , " Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag. " ] )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
2018-10-25 03:28:17 +02:00
iswatchonly = True ,
2018-12-06 16:20:11 +01:00
ismine = False ,
2018-10-25 03:28:17 +02:00
solvable = False ,
timestamp = timestamp )
2016-11-08 22:55:02 +01:00
2017-02-21 16:53:07 +01:00
# Importing existing watch only address with new timestamp should replace saved timestamp.
assert_greater_than ( timestamp , watchonly_timestamp )
2017-03-17 23:04:13 +01:00
self . log . info ( " Should replace previously saved watch only timestamp. " )
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : watchonly_address } ,
" timestamp " : " now " } ,
True )
2018-12-06 16:20:11 +01:00
self . test_address ( watchonly_address ,
iswatchonly = True ,
ismine = False ,
timestamp = timestamp )
2017-02-21 16:53:07 +01:00
watchonly_timestamp = timestamp
2016-11-08 22:55:02 +01:00
# restart nodes to check for proper serialization/deserialization of watch only address
2017-03-24 04:56:31 +01:00
self . stop_nodes ( )
2017-06-09 22:35:17 +02:00
self . start_nodes ( )
2018-12-06 16:20:11 +01:00
self . test_address ( watchonly_address ,
iswatchonly = True ,
ismine = False ,
timestamp = watchonly_timestamp )
2016-10-19 16:17:42 +02:00
2017-02-03 22:23:13 +01:00
# Bad or missing timestamps
2017-03-08 00:46:17 +01:00
self . log . info ( " Should throw on invalid or missing timestamp values " )
2017-07-12 16:33:46 +02:00
assert_raises_rpc_error ( - 3 , ' Missing required timestamp field for key ' ,
2018-12-06 00:28:32 +01:00
self . nodes [ 1 ] . importmulti , [ { " scriptPubKey " : key . p2pkh_script } ] )
2017-07-12 16:33:46 +02:00
assert_raises_rpc_error ( - 3 , ' Expected number or " now " timestamp value for key. got type string ' ,
2018-11-30 23:47:46 +01:00
self . nodes [ 1 ] . importmulti , [ {
2018-12-06 00:28:32 +01:00
" scriptPubKey " : key . p2pkh_script ,
2018-11-30 23:47:46 +01:00
" timestamp " : " "
} ] )
2017-02-03 22:23:13 +01:00
2018-10-09 07:43:20 +02:00
# Import P2WPKH address as watch only
self . log . info ( " Should import a P2WPKH address as watch only " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2wpkh_addr
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : address } ,
" timestamp " : " now " } ,
True )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
iswatchonly = True ,
solvable = False )
2018-10-09 07:43:20 +02:00
# Import P2WPKH address with public key but no private key
self . log . info ( " Should import a P2WPKH address and public key as solvable but not spendable " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2wpkh_addr
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : address } ,
" timestamp " : " now " ,
" pubkeys " : [ key . pubkey ] } ,
2018-10-25 03:28:17 +02:00
True ,
warnings = [ " Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag. " ] )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
ismine = False ,
solvable = True )
2018-10-09 07:43:20 +02:00
# Import P2WPKH address with key and check it is spendable
self . log . info ( " Should import a P2WPKH address with key " )
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2wpkh_addr
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : address } ,
" timestamp " : " now " ,
" keys " : [ key . privkey ] } ,
True )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
iswatchonly = False ,
ismine = True )
2018-10-09 07:43:20 +02:00
# P2WSH multisig address without scripts or keys
2018-12-06 00:28:32 +01:00
multisig = self . get_multisig ( )
2018-10-09 07:43:20 +02:00
self . log . info ( " Should import a p2wsh multisig as watch only without respective redeem script and private keys " )
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : multisig . p2wsh_addr } ,
" timestamp " : " now " } ,
True )
2018-12-06 16:20:11 +01:00
self . test_address ( multisig . p2sh_addr ,
solvable = False )
2018-10-09 07:43:20 +02:00
# Same P2WSH multisig address as above, but now with witnessscript + private keys
2018-12-06 00:28:32 +01:00
self . log . info ( " Should import a p2wsh with respective witness script and private keys " )
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : multisig . p2wsh_addr } ,
" timestamp " : " now " ,
" witnessscript " : multisig . redeem_script ,
" keys " : multisig . privkeys } ,
True )
2018-12-06 16:20:11 +01:00
self . test_address ( multisig . p2sh_addr ,
solvable = True ,
ismine = True ,
sigsrequired = 2 )
2018-10-09 07:43:20 +02:00
# P2SH-P2WPKH address with no redeemscript or public or private key
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2sh_p2wpkh_addr
2018-10-09 07:43:20 +02:00
self . log . info ( " Should import a p2sh-p2wpkh without redeem script or keys " )
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : address } ,
" timestamp " : " now " } ,
True )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
solvable = False ,
ismine = False )
2018-10-09 07:43:20 +02:00
# P2SH-P2WPKH address + redeemscript + public key with no private key
self . log . info ( " Should import a p2sh-p2wpkh with respective redeem script and pubkey as solvable " )
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : address } ,
" timestamp " : " now " ,
" redeemscript " : key . p2sh_p2wpkh_redeem_script ,
" pubkeys " : [ key . pubkey ] } ,
2018-10-25 03:28:17 +02:00
True ,
warnings = [ " Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag. " ] )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
solvable = True ,
ismine = False )
2018-10-09 07:43:20 +02:00
# P2SH-P2WPKH address + redeemscript + private key
2018-12-06 00:28:32 +01:00
key = self . get_key ( )
address = key . p2sh_p2wpkh_addr
2018-10-09 07:43:20 +02:00
self . log . info ( " Should import a p2sh-p2wpkh with respective redeem script and private keys " )
2018-12-06 15:52:38 +01:00
self . test_importmulti ( { " scriptPubKey " : { " address " : address } ,
" timestamp " : " now " ,
" redeemscript " : key . p2sh_p2wpkh_redeem_script ,
" keys " : [ key . privkey ] } ,
True )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
solvable = True ,
ismine = True )
2018-10-09 07:43:20 +02:00
2018-12-06 00:28:32 +01:00
# P2SH-P2WSH multisig + redeemscript with no private key
multisig = self . get_multisig ( )
2018-10-25 03:28:17 +02:00
address = multisig . p2sh_p2wsh_addr
2018-10-09 07:43:20 +02:00
self . log . info ( " Should import a p2sh-p2wsh with respective redeem script but no private key " )
2018-10-25 03:28:17 +02:00
self . test_importmulti ( { " scriptPubKey " : { " address " : address } ,
2018-12-06 15:52:38 +01:00
" timestamp " : " now " ,
" redeemscript " : multisig . p2wsh_script ,
" witnessscript " : multisig . redeem_script } ,
2018-10-25 03:28:17 +02:00
True ,
warnings = [ " Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag. " ] )
2018-12-06 16:20:11 +01:00
self . test_address ( address ,
2018-10-25 03:28:17 +02:00
solvable = True ,
ismine = False )
2017-02-03 22:23:13 +01:00
2016-06-16 16:57:48 +02:00
if __name__ == ' __main__ ' :
2018-11-30 23:47:46 +01:00
ImportMultiTest ( ) . main ( )