From 4d48a077175d89857f8d98f929304aa0b84abbc8 Mon Sep 17 00:00:00 2001 From: Daniela Brozzoni Date: Wed, 19 Jul 2023 18:48:20 +0200 Subject: [PATCH] fix: Explicitly deny multipath keys Although there is *some* code to handle multipath keys inside bdk, it's all untested, and from a few quick tests it seems that it's pretty easy to find buggy edge cases. Better to deny multipath descs for now, and revisit the decision once we work on supporting multidescriptor wallets. --- src/descriptor/error.rs | 6 ++++++ src/descriptor/mod.rs | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/descriptor/error.rs b/src/descriptor/error.rs index 417a43dd..aed2d95b 100644 --- a/src/descriptor/error.rs +++ b/src/descriptor/error.rs @@ -20,6 +20,8 @@ pub enum Error { InvalidDescriptorChecksum, /// The descriptor contains hardened derivation steps on public extended keys HardenedDerivationXpub, + /// The descriptor contains multipath keys + MultiPath, /// Error thrown while working with [`keys`](crate::keys) Key(crate::keys::KeyError), @@ -62,6 +64,10 @@ impl std::fmt::Display for Error { f, "The descriptor contains hardened derivation steps on public extended keys" ), + Self::MultiPath => write!( + f, + "The descriptor contains multipath keys, which are not supported yet" + ), Self::Key(err) => write!(f, "Key error: {}", err), Self::Policy(err) => write!(f, "Policy error: {}", err), Self::InvalidDescriptorCharacter(char) => { diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index 5b97a3ed..1ee43e30 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -306,6 +306,10 @@ pub(crate) fn into_wallet_descriptor_checked( return Err(DescriptorError::HardenedDerivationXpub); } + if descriptor.is_multipath() { + return Err(DescriptorError::MultiPath); + } + // Run miniscript's sanity check, which will look for duplicated keys and other potential // issues descriptor.sanity_check()?; @@ -862,6 +866,12 @@ mod test { assert_matches!(result, Err(DescriptorError::HardenedDerivationXpub)); + let descriptor = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/<0;1>/*)"; + let result = into_wallet_descriptor_checked(descriptor, &secp, Network::Testnet); + + assert_matches!(result, Err(DescriptorError::MultiPath)); + + // repeated pubkeys let descriptor = "wsh(multi(2,tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/0/*,tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/0/*))"; let result = into_wallet_descriptor_checked(descriptor, &secp, Network::Testnet);