diff --git a/test/functional/wallet_importmulti.py b/test/functional/wallet_importmulti.py --- a/test/functional/wallet_importmulti.py +++ b/test/functional/wallet_importmulti.py @@ -9,7 +9,9 @@ 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.""" + 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.""" from collections import namedtuple from test_framework.address import ( @@ -97,6 +99,15 @@ # redeem script script_code.hex()) + def test_importmulti(self, req, success, + error_code=None, error_message=None): + """Run importmulti and assert success""" + result = self.nodes[1].importmulti([req]) + 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) + def run_test(self): self.log.info("Mining blocks...") self.nodes[0].generate(1) @@ -124,13 +135,9 @@ self.log.info("Should import an address") key = self.get_key() address = key.p2pkh_addr - result = self.nodes[1].importmulti([{ - "scriptPubKey": { - "address": address - }, - "timestamp": "now", - }]) - assert_equal(result[0]['success'], True) + self.test_importmulti({"scriptPubKey": {"address": address}, + "timestamp": "now"}, + True) address_assert = self.nodes[1].getaddressinfo(address) assert_equal(address_assert['iswatchonly'], True) assert_equal(address_assert['ismine'], False) @@ -140,25 +147,19 @@ watchonly_timestamp = timestamp self.log.info("Should not import an invalid address") - result = self.nodes[1].importmulti([{ - "scriptPubKey": { - "address": "not valid address", - }, - "timestamp": "now", - }]) - assert_equal(result[0]['success'], False) - assert_equal(result[0]['error']['code'], -5) - assert_equal(result[0]['error']['message'], 'Invalid address') + self.test_importmulti({"scriptPubKey": {"address": "not valid address"}, + "timestamp": "now"}, + False, + error_code=-5, + error_message='Invalid address') # ScriptPubKey + internal self.log.info("Should import a scriptPubKey with internal flag") key = self.get_key() - result = self.nodes[1].importmulti([{ - "scriptPubKey": key.p2pkh_script, - "timestamp": "now", - "internal": True - }]) - assert_equal(result[0]['success'], True) + self.test_importmulti({"scriptPubKey": key.p2pkh_script, + "timestamp": "now", + "internal": True}, + True) address_assert = self.nodes[1].getaddressinfo(key.p2pkh_addr) assert_equal(address_assert['iswatchonly'], True) assert_equal(address_assert['ismine'], False) @@ -169,16 +170,13 @@ self.log.info( "Should not allow a label to be specified when internal is true") key = self.get_key() - result = self.nodes[1].importmulti([{ - "scriptPubKey": key.p2pkh_script, - "timestamp": "now", - "internal": True, - "label": "Example label" - }]) - assert_equal(result[0]['success'], False) - assert_equal(result[0]['error']['code'], -8) - assert_equal(result[0]['error']['message'], - 'Internal addresses should not have a label') + 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') # Nonstandard scriptPubKey + !internal self.log.info( @@ -186,15 +184,11 @@ nonstandardScriptPubKey = key.p2pkh_script + CScript([OP_NOP]).hex() key = self.get_key() address = key.p2pkh_addr - result = self.nodes[1].importmulti([{ - "scriptPubKey": nonstandardScriptPubKey, - "timestamp": "now", - }]) - assert_equal(result[0]['success'], False) - assert_equal(result[0]['error']['code'], -8) - assert_equal( - result[0]['error']['message'], - 'Internal must be set to true for nonstandard scriptPubKey imports.') + self.test_importmulti({"scriptPubKey": nonstandardScriptPubKey, + "timestamp": "now"}, + False, + error_code=-8, + error_message='Internal must be set to true for nonstandard scriptPubKey imports.') address_assert = self.nodes[1].getaddressinfo(address) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) @@ -204,15 +198,11 @@ self.log.info("Should import an address with public key") key = self.get_key() address = key.p2pkh_addr - result = self.nodes[1].importmulti([{ - "scriptPubKey": { - "address": address - }, - "timestamp": "now", - "pubkeys": [key.pubkey], - "internal": False - }]) - assert_equal(result[0]['success'], True) + self.test_importmulti({"scriptPubKey": {"address": address}, + "timestamp": "now", + "pubkeys": [key.pubkey], + "internal": False}, + True) address_assert = self.nodes[1].getaddressinfo(address) assert_equal(address_assert['iswatchonly'], True) assert_equal(address_assert['ismine'], False) @@ -223,14 +213,11 @@ "Should import a scriptPubKey with internal and with public key") key = self.get_key() address = key.p2pkh_addr - request = [{ - "scriptPubKey": key.p2pkh_script, - "timestamp": "now", - "pubkeys": [key.pubkey], - "internal": True - }] - result = self.nodes[1].importmulti(requests=request) - assert_equal(result[0]['success'], True) + self.test_importmulti({"scriptPubKey": key.p2pkh_script, + "timestamp": "now", + "pubkeys": [key.pubkey], + "internal": True}, + True) address_assert = self.nodes[1].getaddressinfo(address) assert_equal(address_assert['iswatchonly'], True) assert_equal(address_assert['ismine'], False) @@ -241,17 +228,12 @@ "Should not import a nonstandard scriptPubKey without internal and with public key") key = self.get_key() address = key.p2pkh_addr - request = [{ - "scriptPubKey": nonstandardScriptPubKey, - "timestamp": "now", - "pubkeys": [key.pubkey] - }] - result = self.nodes[1].importmulti(requests=request) - assert_equal(result[0]['success'], False) - assert_equal(result[0]['error']['code'], -8) - assert_equal( - result[0]['error']['message'], - 'Internal must be set to true for nonstandard scriptPubKey imports.') + 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.') address_assert = self.nodes[1].getaddressinfo(address) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) @@ -261,14 +243,10 @@ self.log.info("Should import an address with private key") key = self.get_key() address = key.p2pkh_addr - result = self.nodes[1].importmulti([{ - "scriptPubKey": { - "address": address - }, - "timestamp": "now", - "keys": [key.privkey] - }]) - assert_equal(result[0]['success'], True) + self.test_importmulti({"scriptPubKey": {"address": address}, + "timestamp": "now", + "keys": [key.privkey]}, + True) address_assert = self.nodes[1].getaddressinfo(address) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], True) @@ -276,36 +254,25 @@ self.log.info( "Should not import an address with private key if is already imported") - result = self.nodes[1].importmulti([{ - "scriptPubKey": { - "address": address - }, - "timestamp": "now", - "keys": [key.privkey] - }]) - assert_equal(result[0]['success'], False) - assert_equal(result[0]['error']['code'], -4) - assert_equal(result[0]['error']['message'], - 'The wallet already contains the private key for this address or script') + 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') # Address + Private key + watchonly self.log.info( "Should not import an address with private key and with watchonly") key = self.get_key() address = key.p2pkh_addr - result = self.nodes[1].importmulti([{ - "scriptPubKey": { - "address": address - }, - "timestamp": "now", - "keys": [key.privkey], - "watchonly": True - }]) - assert_equal(result[0]['success'], False) - assert_equal(result[0]['error']['code'], -8) - assert_equal( - result[0]['error']['message'], - 'Watch-only addresses should not include private keys') + self.test_importmulti({"scriptPubKey": {"address": address}, + "timestamp": "now", + "keys": [key.privkey], + "watchonly": True}, + False, + error_code=-8, + error_message='Watch-only addresses should not include private keys') address_assert = self.nodes[1].getaddressinfo(address) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) @@ -316,13 +283,11 @@ "Should import a scriptPubKey with internal and with private key") key = self.get_key() address = key.p2pkh_addr - result = self.nodes[1].importmulti([{ - "scriptPubKey": key.p2pkh_script, - "timestamp": "now", - "keys": [key.privkey], - "internal": True - }]) - assert_equal(result[0]['success'], True) + self.test_importmulti({"scriptPubKey": key.p2pkh_script, + "timestamp": "now", + "keys": [key.privkey], + "internal": True}, + True) address_assert = self.nodes[1].getaddressinfo(address) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], True) @@ -333,16 +298,12 @@ "Should not import a nonstandard scriptPubKey without internal and with private key") key = self.get_key() address = key.p2pkh_addr - result = self.nodes[1].importmulti([{ - "scriptPubKey": nonstandardScriptPubKey, - "timestamp": "now", - "keys": [key.privkey] - }]) - assert_equal(result[0]['success'], False) - assert_equal(result[0]['error']['code'], -8) - assert_equal( - result[0]['error']['message'], - 'Internal must be set to true for nonstandard scriptPubKey imports.') + 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.') address_assert = self.nodes[1].getaddressinfo(address) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) @@ -357,13 +318,9 @@ self.nodes[1].getbestblockhash())['mediantime'] self.log.info("Should import a p2sh") - result = self.nodes[1].importmulti([{ - "scriptPubKey": { - "address": multisig.p2sh_addr - }, - "timestamp": "now", - }]) - assert_equal(result[0]['success'], True) + self.test_importmulti({"scriptPubKey": {"address": multisig.p2sh_addr}, + "timestamp": "now"}, + True) address_assert = self.nodes[1].getaddressinfo(multisig.p2sh_addr) assert_equal(address_assert['isscript'], True) assert_equal(address_assert['iswatchonly'], True) @@ -382,14 +339,10 @@ self.nodes[1].getbestblockhash())['mediantime'] self.log.info("Should import a p2sh with respective redeem script") - result = self.nodes[1].importmulti([{ - "scriptPubKey": { - "address": multisig.p2sh_addr - }, - "timestamp": "now", - "redeemscript": multisig.redeem_script - }]) - assert_equal(result[0]['success'], True) + self.test_importmulti({"scriptPubKey": {"address": multisig.p2sh_addr}, + "timestamp": "now", + "redeemscript": multisig.redeem_script}, + True) address_assert = self.nodes[1].getaddressinfo(multisig.p2sh_addr) assert_equal(address_assert['timestamp'], timestamp) @@ -408,15 +361,11 @@ self.log.info( "Should import a p2sh with respective redeem script and private keys") - result = self.nodes[1].importmulti([{ - "scriptPubKey": { - "address": multisig.p2sh_addr - }, - "timestamp": "now", - "redeemscript": multisig.redeem_script, - "keys": multisig.privkeys[0:2] - }]) - assert_equal(result[0]['success'], True) + self.test_importmulti({"scriptPubKey": {"address": multisig.p2sh_addr}, + "timestamp": "now", + "redeemscript": multisig.redeem_script, + "keys": multisig.privkeys[0:2]}, + True) address_assert = self.nodes[1].getaddressinfo(multisig.p2sh_addr) assert_equal(address_assert['timestamp'], timestamp) @@ -435,38 +384,26 @@ self.log.info( "Should import a p2sh with respective redeem script and private keys") - result = self.nodes[1].importmulti([{ - "scriptPubKey": { - "address": multisig.p2sh_addr - }, - "timestamp": "now", - "redeemscript": multisig.redeem_script, - "keys": multisig.privkeys[0:2], - "watchonly": True - }]) - assert_equal(result[0]['success'], False) - assert_equal(result[0]['error']['code'], -8) - assert_equal( - result[0]['error']['message'], - 'Watch-only addresses should not include private keys') + self.test_importmulti({"scriptPubKey": {"address": multisig.p2sh_addr}, + "timestamp": "now", + "redeemscript": multisig.redeem_script, + "keys": multisig.privkeys[0:2], + "watchonly": True}, + False, + error_code=-8, + error_message='Watch-only addresses should not include private keys') # Address + Public key + !Internal + Wrong pubkey self.log.info("Should not import an address with a wrong public key") key = self.get_key() address = key.p2pkh_addr wrong_key = self.get_key().pubkey - result = self.nodes[1].importmulti([{ - "scriptPubKey": { - "address": address - }, - "timestamp": "now", - "pubkeys": [wrong_key] - }]) - assert_equal(result[0]['success'], False) - assert_equal(result[0]['error']['code'], -5) - assert_equal( - result[0]['error']['message'], - 'Key does not match address destination') + self.test_importmulti({"scriptPubKey": {"address": address}, + "timestamp": "now", + "pubkeys": [wrong_key]}, + False, + error_code=-5, + error_message='Key does not match address destination') address_assert = self.nodes[1].getaddressinfo(address) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) @@ -478,18 +415,13 @@ key = self.get_key() address = key.p2pkh_addr wrong_key = self.get_key().pubkey - request = [{ - "scriptPubKey": key.p2pkh_script, - "timestamp": "now", - "pubkeys": [wrong_key], - "internal": True - }] - result = self.nodes[1].importmulti(request) - assert_equal(result[0]['success'], False) - assert_equal(result[0]['error']['code'], -5) - assert_equal( - result[0]['error']['message'], - 'Key does not match address destination') + self.test_importmulti({"scriptPubKey": key.p2pkh_script, + "timestamp": "now", + "pubkeys": [wrong_key], + "internal": True}, + False, + error_code=-5, + error_message='Key does not match address destination') address_assert = self.nodes[1].getaddressinfo(address) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) @@ -500,18 +432,12 @@ key = self.get_key() address = key.p2pkh_addr wrong_privkey = self.get_key().privkey - result = self.nodes[1].importmulti([{ - "scriptPubKey": { - "address": address - }, - "timestamp": "now", - "keys": [wrong_privkey] - }]) - assert_equal(result[0]['success'], False) - assert_equal(result[0]['error']['code'], -5) - assert_equal( - result[0]['error']['message'], - 'Key does not match address destination') + self.test_importmulti({"scriptPubKey": {"address": address}, + "timestamp": "now", + "keys": [wrong_privkey]}, + False, + error_code=-5, + error_message='Key does not match address destination') address_assert = self.nodes[1].getaddressinfo(address) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) @@ -523,17 +449,13 @@ key = self.get_key() address = key.p2pkh_addr wrong_privkey = self.get_key().privkey - result = self.nodes[1].importmulti([{ - "scriptPubKey": key.p2pkh_script, - "timestamp": "now", - "keys": [wrong_privkey], - "internal": True - }]) - assert_equal(result[0]['success'], False) - assert_equal(result[0]['error']['code'], -5) - assert_equal( - result[0]['error']['message'], - 'Key does not match address destination') + self.test_importmulti({"scriptPubKey": key.p2pkh_script, + "timestamp": "now", + "keys": [wrong_privkey], + "internal": True}, + False, + error_code=-5, + error_message='Key does not match address destination') address_assert = self.nodes[1].getaddressinfo(address) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) @@ -543,13 +465,9 @@ # replace saved timestamp. assert_greater_than(timestamp, watchonly_timestamp) self.log.info("Should replace previously saved watch only timestamp.") - result = self.nodes[1].importmulti([{ - "scriptPubKey": { - "address": watchonly_address, - }, - "timestamp": "now", - }]) - assert_equal(result[0]['success'], True) + self.test_importmulti({"scriptPubKey": {"address": watchonly_address}, + "timestamp": "now"}, + True) address_assert = self.nodes[1].getaddressinfo(watchonly_address) assert_equal(address_assert['iswatchonly'], True) assert_equal(address_assert['ismine'], False)