Add consistency check to RPC call importmulti
This commit is contained in:
parent
cb08fdbf78
commit
215caba4ed
2 changed files with 108 additions and 9 deletions
|
@ -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 ()
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
Loading…
Reference in a new issue