diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -1122,6 +1122,11 @@ std::vector vData(ParseHex(output)); script = CScript(vData.begin(), vData.end()); + if (!ExtractDestination(script, dest) && !internal) { + throw JSONRPCError(RPC_INVALID_PARAMETER, + "Internal must be set to true for " + "nonstandard scriptPubKey imports."); + } } // Watchonly and private keys @@ -1138,12 +1143,6 @@ "Incompatibility found between internal and label"); } - // Not having Internal + Script - if (!internal && isScript) { - throw JSONRPCError(RPC_INVALID_PARAMETER, - "Internal must be set for hex scriptPubKey"); - } - // Keys / PubKeys size check. if (!isP2SH && (keys.size() > 1 || pubKeys.size() > 1)) { // Address / scriptPubKey @@ -1263,23 +1262,11 @@ CTxDestination pubkey_dest = pubKey.GetID(); // Consistency check. - if (!isScript && !(pubkey_dest == dest)) { + if (!(pubkey_dest == dest)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed"); } - // Consistency check. - if (isScript) { - CTxDestination destination; - - if (ExtractDestination(script, destination)) { - if (!(destination == pubkey_dest)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, - "Consistency check failed"); - } - } - } - CScript pubKeyScript = GetScriptForDestination(pubkey_dest); if (::IsMine(*pwallet, pubKeyScript) == ISMINE_SPENDABLE) { @@ -1339,23 +1326,11 @@ CTxDestination pubkey_dest = pubKey.GetID(); // Consistency check. - if (!isScript && !(pubkey_dest == dest)) { + if (!(pubkey_dest == dest)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed"); } - // Consistency check. - if (isScript) { - CTxDestination destination; - - if (ExtractDestination(script, destination)) { - if (!(destination == pubkey_dest)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, - "Consistency check failed"); - } - } - } - CKeyID vchAddress = pubKey.GetID(); pwallet->MarkDirty(); pwallet->SetAddressBook(vchAddress, label, "receive"); @@ -1395,7 +1370,7 @@ "Error adding address to wallet"); } - if (scriptPubKey.getType() == UniValue::VOBJ) { + if (!internal) { // add to address book or update label if (IsValidDestination(dest)) { pwallet->SetAddressBook(dest, label, "receive"); diff --git a/test/functional/wallet_import_rescan.py b/test/functional/wallet_import_rescan.py --- a/test/functional/wallet_import_rescan.py +++ b/test/functional/wallet_import_rescan.py @@ -33,7 +33,7 @@ ) -Call = enum.Enum("Call", "single multi") +Call = enum.Enum("Call", "single multiaddress multiscript") Data = enum.Enum("Data", "address pub priv") Rescan = enum.Enum("Rescan", "no yes late_timestamp") @@ -74,11 +74,11 @@ rescan=rescan) assert_equal(response, None) - elif self.call == Call.multi: + elif self.call in (Call.multiaddress, Call.multiscript): response = self.node.importmulti([{ "scriptPubKey": { "address": self.address["address"] - }, + } if self.call == Call.multiaddress else self.address["scriptPubKey"], "timestamp": timestamp + TIMESTAMP_WINDOW + (1 if self.rescan == Rescan.late_timestamp else 0), "pubkeys": [self.address["pubkey"]] if self.data == Data.pub else [], "keys": [self.key] if self.data == Data.priv else [], @@ -179,7 +179,7 @@ variant.address = self.nodes[1].getaddressinfo( self.nodes[1].getnewaddress(variant.label)) variant.key = self.nodes[1].dumpprivkey(variant.address["address"]) - variant.initial_amount = 10 - (i + 1) / 4.0 + variant.initial_amount = 1 - (i + 1) / 64 variant.initial_txid = self.nodes[0].sendtoaddress( variant.address["address"], variant.initial_amount) @@ -212,7 +212,7 @@ # Create new transactions sending to each address. for i, variant in enumerate(IMPORT_VARIANTS): - variant.sent_amount = 10 - (2 * i + 1) / 8.0 + variant.sent_amount = 1 - (2 * i + 1) / 128 variant.sent_txid = self.nodes[0].sendtoaddress( variant.address["address"], variant.sent_amount) 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 @@ -3,6 +3,8 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the importmulti RPC.""" + +from test_framework import script from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, @@ -89,17 +91,21 @@ assert_equal(address_assert['timestamp'], timestamp) assert_equal(address_assert['ischange'], True) - # ScriptPubKey + !internal - self.log.info("Should not import a scriptPubKey without internal flag") + # Nonstandard scriptPubKey + !internal + self.log.info( + "Should not import a nonstandard scriptPubKey without internal flag") + nonstandardScriptPubKey = address['scriptPubKey'] + \ + script.CScript([script.OP_NOP]).hex() address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress()) result = self.nodes[1].importmulti([{ - "scriptPubKey": address['scriptPubKey'], + "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 for hex scriptPubKey') + assert_equal( + result[0]['error']['message'], + 'Internal must be set to true for nonstandard scriptPubKey imports.') address_assert = self.nodes[1].getaddressinfo(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) @@ -139,20 +145,21 @@ assert_equal(address_assert['ismine'], False) assert_equal(address_assert['timestamp'], timestamp) - # ScriptPubKey + Public key + !internal + # Nonstandard scriptPubKey + Public key + !internal self.log.info( - "Should not import a scriptPubKey without internal and with public key") + "Should not import a nonstandard scriptPubKey without internal and with public key") address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress()) request = [{ - "scriptPubKey": address['scriptPubKey'], + "scriptPubKey": nonstandardScriptPubKey, "timestamp": "now", "pubkeys": [address['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 for hex scriptPubKey') + assert_equal( + result[0]['error']['message'], + 'Internal must be set to true for nonstandard scriptPubKey imports.') address_assert = self.nodes[1].getaddressinfo(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False) @@ -225,19 +232,20 @@ assert_equal(address_assert['ismine'], True) assert_equal(address_assert['timestamp'], timestamp) - # ScriptPubKey + Private key + !internal + # Nonstandard scriptPubKey + Private key + !internal self.log.info( - "Should not import a scriptPubKey without internal and with private key") + "Should not import a nonstandard scriptPubKey without internal and with private key") address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress()) result = self.nodes[1].importmulti([{ - "scriptPubKey": address['scriptPubKey'], + "scriptPubKey": nonstandardScriptPubKey, "timestamp": "now", "keys": [self.nodes[0].dumpprivkey(address['address'])] }]) assert_equal(result[0]['success'], False) assert_equal(result[0]['error']['code'], -8) - assert_equal(result[0]['error']['message'], - 'Internal must be set for hex scriptPubKey') + assert_equal( + result[0]['error']['message'], + 'Internal must be set to true for nonstandard scriptPubKey imports.') address_assert = self.nodes[1].getaddressinfo(address['address']) assert_equal(address_assert['iswatchonly'], False) assert_equal(address_assert['ismine'], False)