aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Branco <branco@uphold.com>2016-10-19 15:17:42 +0100
committerPedro Branco <branco@uphold.com>2016-10-19 15:17:42 +0100
commit215caba4ed4547d6f2a0954fa9fe1ae78f4a7c40 (patch)
treeda88271ec1e64d3307c04522c87632791f14a5fb
parentcb08fdbf78685b55029768524ca867772711c32b (diff)
Add consistency check to RPC call importmulti
-rwxr-xr-xqa/rpc-tests/importmulti.py69
-rw-r--r--src/wallet/rpcdump.cpp48
2 files changed, 108 insertions, 9 deletions
diff --git a/qa/rpc-tests/importmulti.py b/qa/rpc-tests/importmulti.py
index 960cb63d76..5c536f2f49 100755
--- a/qa/rpc-tests/importmulti.py
+++ b/qa/rpc-tests/importmulti.py
@@ -285,9 +285,76 @@ class ImportMultiTest (BitcoinTestFramework):
assert_equal(result[0]['error']['code'], -8)
assert_equal(result[0]['error']['message'], 'Incompatibility found between watchonly and keys')
- # TODO Consistency tests?
+ # Address + Public key + !Internal + Wrong pubkey
+ print("Should not import an address with a wrong public key")
+ address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ result = self.nodes[1].importmulti([{
+ "scriptPubKey": {
+ "address": address['address']
+ },
+ "pubkeys": [ address2['pubkey'] ]
+ }])
+ assert_equal(result[0]['success'], False)
+ assert_equal(result[0]['error']['code'], -5)
+ assert_equal(result[0]['error']['message'], 'Consistency check failed')
+ address_assert = self.nodes[1].validateaddress(address['address'])
+ assert_equal(address_assert['iswatchonly'], False)
+ assert_equal(address_assert['ismine'], False)
+
+
+ # ScriptPubKey + Public key + internal + Wrong pubkey
+ print("Should not import a scriptPubKey with internal and with a wrong public key")
+ address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ request = [{
+ "scriptPubKey": address['scriptPubKey'],
+ "pubkeys": [ address2['pubkey'] ],
+ "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'], 'Consistency check failed')
+ address_assert = self.nodes[1].validateaddress(address['address'])
+ assert_equal(address_assert['iswatchonly'], False)
+ assert_equal(address_assert['ismine'], False)
+ # Address + Private key + !watchonly + Wrong private key
+ print("Should not import an address with a wrong private key")
+ address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ result = self.nodes[1].importmulti([{
+ "scriptPubKey": {
+ "address": address['address']
+ },
+ "keys": [ self.nodes[0].dumpprivkey(address2['address']) ]
+ }])
+ assert_equal(result[0]['success'], False)
+ assert_equal(result[0]['error']['code'], -5)
+ assert_equal(result[0]['error']['message'], 'Consistency check failed')
+ address_assert = self.nodes[1].validateaddress(address['address'])
+ assert_equal(address_assert['iswatchonly'], False)
+ assert_equal(address_assert['ismine'], False)
+
+
+ # ScriptPubKey + Private key + internal + Wrong private key
+ print("Should not import a scriptPubKey with internal and with a wrong private key")
+ address = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ address2 = self.nodes[0].validateaddress(self.nodes[0].getnewaddress())
+ result = self.nodes[1].importmulti([{
+ "scriptPubKey": address['scriptPubKey'],
+ "keys": [ self.nodes[0].dumpprivkey(address2['address']) ],
+ "internal": True
+ }])
+ assert_equal(result[0]['success'], False)
+ assert_equal(result[0]['error']['code'], -5)
+ assert_equal(result[0]['error']['message'], 'Consistency check failed')
+ address_assert = self.nodes[1].validateaddress(address['address'])
+ assert_equal(address_assert['iswatchonly'], False)
+ assert_equal(address_assert['ismine'], False)
+
if __name__ == '__main__':
ImportMultiTest ().main ()
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index 0297337c2a..7b16b4adfb 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -641,9 +641,6 @@ UniValue dumpwallet(const JSONRPCRequest& request)
UniValue processImport(const UniValue& data) {
- // TODO List:
- // - Check consistency between pubkeys/privkeys and scriptPubKey/redeemScript.
-
try {
bool success = false;
@@ -713,8 +710,6 @@ UniValue processImport(const UniValue& data) {
// P2SH
if (isP2SH) {
- // TODO: check consistency between private keys and p2sh redeemscript + p2sh address
-
// Import redeem script.
std::vector<unsigned char> vData(ParseHex(strRedeemScript));
CScript redeemScript = CScript(vData.begin(), vData.end());
@@ -795,8 +790,6 @@ UniValue processImport(const UniValue& data) {
success = true;
} else {
- // TODO: check consistency between private/public keys and scriptPubKey / address
-
// Import public keys.
if (pubKeys.size() && keys.size() == 0) {
const string& strPubKey = pubKeys[0].get_str();
@@ -813,6 +806,25 @@ UniValue processImport(const UniValue& data) {
}
CBitcoinAddress pubKeyAddress = CBitcoinAddress(pubKey.GetID());
+
+ // Consistency check.
+ if (!isScript && pubKeyAddress.Get() != address.Get()) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed");
+ }
+
+ // Consistency check.
+ if (isScript) {
+ CBitcoinAddress scriptAddress;
+ CTxDestination destination;
+
+ if (ExtractDestination(script, destination)) {
+ scriptAddress = CBitcoinAddress(destination);
+ if (scriptAddress.Get() != pubKeyAddress.Get()) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed");
+ }
+ }
+ }
+
CScript pubKeyScript = GetScriptForDestination(pubKeyAddress.Get());
if (::IsMine(*pwalletMain, pubKeyScript) == ISMINE_SPENDABLE) {
@@ -866,7 +878,27 @@ UniValue processImport(const UniValue& data) {
CPubKey pubKey = key.GetPubKey();
assert(key.VerifyPubKey(pubKey));
- CKeyID vchAddress = pubkey.GetID();
+ CBitcoinAddress pubKeyAddress = CBitcoinAddress(pubKey.GetID());
+
+ // Consistency check.
+ if (!isScript && pubKeyAddress.Get() != address.Get()) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed");
+ }
+
+ // Consistency check.
+ if (isScript) {
+ CBitcoinAddress scriptAddress;
+ CTxDestination destination;
+
+ if (ExtractDestination(script, destination)) {
+ scriptAddress = CBitcoinAddress(destination);
+ if (scriptAddress.Get() != pubKeyAddress.Get()) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed");
+ }
+ }
+ }
+
+ CKeyID vchAddress = pubKey.GetID();
pwalletMain->MarkDirty();
pwalletMain->SetAddressBook(vchAddress, label, "receive");