mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 23:09:44 -04:00
wallet, rpc: Disallow import of unused() if key already exists
This commit is contained in:
parent
9e70f515a0
commit
09e5a684fe
2 changed files with 34 additions and 0 deletions
|
@ -1573,6 +1573,23 @@ static UniValue ProcessDescriptorImport(CWallet& wallet, const UniValue& data, c
|
|||
}
|
||||
}
|
||||
|
||||
// If this is an unused(KEY) descriptor, check that the wallet doesn't already have other descriptors with this key
|
||||
if (!parsed_desc->HasScripts()) {
|
||||
// Unused descriptors must contain a single key.
|
||||
// Earlier checks will have enforced that this key is either a private key when private keys are enabled,
|
||||
// or that this key is a public key when private keys are disabled.
|
||||
// If we can retrieve the corresponding private key from the wallet, then this key is already in the wallet
|
||||
// and we should not import it.
|
||||
std::set<CPubKey> pubkeys;
|
||||
std::set<CExtPubKey> extpubs;
|
||||
parsed_desc->GetPubKeys(pubkeys, extpubs);
|
||||
std::transform(extpubs.begin(), extpubs.end(), std::inserter(pubkeys, pubkeys.begin()), [](const CExtPubKey& xpub) { return xpub.pubkey; });
|
||||
CHECK_NONFATAL(pubkeys.size() == 1);
|
||||
if (wallet.GetKey(pubkeys.begin()->GetID())) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Cannot import an unused() descriptor when its private key is already in the wallet");
|
||||
}
|
||||
}
|
||||
|
||||
WalletDescriptor w_desc(std::move(parsed_desc), timestamp, range_start, range_end, next_index);
|
||||
|
||||
// Check if the wallet already contains the descriptor
|
||||
|
|
|
@ -83,6 +83,22 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
|||
assert_equal(hdkeys[0]["xpub"], xpub)
|
||||
wallet.unloadwallet()
|
||||
|
||||
def test_import_unused_key_existing(self):
|
||||
self.log.info("Test import of unused(KEY) with existing KEY")
|
||||
self.nodes[0].createwallet(wallet_name="import_existing_unused")
|
||||
wallet = self.nodes[0].get_wallet_rpc("import_existing_unused")
|
||||
|
||||
hdkeys = wallet.gethdkeys(private=True)
|
||||
assert_equal(len(hdkeys), 1)
|
||||
xprv = hdkeys[0]["xprv"]
|
||||
|
||||
self.test_importdesc({"timestamp": "now", "desc": descsum_create(f"unused({xprv})")},
|
||||
success=False,
|
||||
error_code=-4,
|
||||
error_message="Cannot import an unused() descriptor when its private key is already in the wallet",
|
||||
wallet=wallet)
|
||||
wallet.unloadwallet()
|
||||
|
||||
def run_test(self):
|
||||
self.log.info('Setting up wallets')
|
||||
self.nodes[0].createwallet(wallet_name='w0', disable_private_keys=False, descriptors=True)
|
||||
|
@ -791,6 +807,7 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
|||
assert_equal(sorted(w_multipath.listdescriptors()["descriptors"], key=lambda x: x["desc"]), sorted(w_multisplit.listdescriptors()["descriptors"], key=lambda x: x["desc"]))
|
||||
|
||||
self.test_import_unused_key()
|
||||
self.test_import_unused_key_existing()
|
||||
|
||||
if __name__ == '__main__':
|
||||
ImportDescriptorsTest(__file__).main()
|
||||
|
|
Loading…
Add table
Reference in a new issue