[descriptor] Ensure that there are no duplicated keys

This commit is contained in:
Alekos Filini 2021-02-23 15:57:43 +01:00
parent 4ad0f54c30
commit 4c2042ab01
No known key found for this signature in database
GPG Key ID: 431401E4A4530061
2 changed files with 30 additions and 1 deletions

View File

@ -33,6 +33,8 @@ pub enum Error {
InvalidDescriptorChecksum,
/// The descriptor contains hardened derivation steps on public extended keys
HardenedDerivationXpub,
/// The descriptor contains multiple keys with the same BIP32 fingerprint
DuplicatedKeys,
/// Error thrown while working with [`keys`](crate::keys)
Key(crate::keys::KeyError),

View File

@ -27,7 +27,7 @@
//! This module contains generic utilities to work with descriptors, plus some re-exported types
//! from [`miniscript`].
use std::collections::{BTreeMap, HashMap};
use std::collections::{BTreeMap, HashMap, HashSet};
use std::ops::Deref;
use bitcoin::util::bip32::{
@ -225,6 +225,24 @@ pub(crate) fn into_wallet_descriptor_checked<T: IntoWalletDescriptor>(
return Err(DescriptorError::HardenedDerivationXpub);
}
// Ensure that there are no duplicated keys
let mut found_keys = HashSet::new();
let descriptor_contains_duplicated_keys = descriptor.for_any_key(|k| {
if let DescriptorPublicKey::XPub(xkey) = k.as_key() {
let fingerprint = xkey.root_fingerprint(secp);
if found_keys.contains(&fingerprint) {
return true;
}
found_keys.insert(fingerprint);
}
false
});
if descriptor_contains_duplicated_keys {
return Err(DescriptorError::DuplicatedKeys);
}
Ok((descriptor, keymap))
}
@ -783,5 +801,14 @@ mod test {
result.unwrap_err(),
DescriptorError::HardenedDerivationXpub
));
let descriptor = "wsh(multi(2,tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/0/*,tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/*))";
let result = into_wallet_descriptor_checked(descriptor, &secp, Network::Testnet);
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
DescriptorError::DuplicatedKeys
));
}
}