[descriptor] Ensure that there are no duplicated keys
This commit is contained in:
parent
4ad0f54c30
commit
4c2042ab01
@ -33,6 +33,8 @@ pub enum Error {
|
|||||||
InvalidDescriptorChecksum,
|
InvalidDescriptorChecksum,
|
||||||
/// The descriptor contains hardened derivation steps on public extended keys
|
/// The descriptor contains hardened derivation steps on public extended keys
|
||||||
HardenedDerivationXpub,
|
HardenedDerivationXpub,
|
||||||
|
/// The descriptor contains multiple keys with the same BIP32 fingerprint
|
||||||
|
DuplicatedKeys,
|
||||||
|
|
||||||
/// Error thrown while working with [`keys`](crate::keys)
|
/// Error thrown while working with [`keys`](crate::keys)
|
||||||
Key(crate::keys::KeyError),
|
Key(crate::keys::KeyError),
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
//! This module contains generic utilities to work with descriptors, plus some re-exported types
|
//! This module contains generic utilities to work with descriptors, plus some re-exported types
|
||||||
//! from [`miniscript`].
|
//! from [`miniscript`].
|
||||||
|
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use bitcoin::util::bip32::{
|
use bitcoin::util::bip32::{
|
||||||
@ -225,6 +225,24 @@ pub(crate) fn into_wallet_descriptor_checked<T: IntoWalletDescriptor>(
|
|||||||
return Err(DescriptorError::HardenedDerivationXpub);
|
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))
|
Ok((descriptor, keymap))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -783,5 +801,14 @@ mod test {
|
|||||||
result.unwrap_err(),
|
result.unwrap_err(),
|
||||||
DescriptorError::HardenedDerivationXpub
|
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
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user