Skip to content

Commit a6faf09

Browse files
committed
Merge #938: Implement MiniscriptKey for each variant of DescriptorPublicKey
eeb49eb Implement MiniscriptKey for each variant of DescriptorPublicKey (Velnbur) Pull request description: This adds ability to specify `SinglePub`, `DescriptorXKey` and `DescriptorMultiXKey` directly in `Descriptor` without using `enum DescriptorPublicKey`. In one of the projects we're using only `DescriptorMultiXKey` with fixed structure, so matching `DescriptorPublicKey` is kind of a pain. This PR fixes that ACKs for top commit: apoelstra: ACK eeb49eb; successfully ran local tests; can do `ToPublicKey` in a followup if you like Tree-SHA512: 8efbee15f3000cc7d0f989ed4766289617bcf0f6f294ab50522d39cbbbdf7478a040c9229077541883a25bbd6b22d8ce4c20261a1c5ec55ee2b376fa645983ac
2 parents 1834bc0 + eeb49eb commit a6faf09

1 file changed

Lines changed: 89 additions & 33 deletions

File tree

src/descriptor/key.rs

Lines changed: 89 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// SPDX-License-Identifier: CC0-1.0
22

33
use core::convert::TryInto;
4-
use core::fmt;
54
use core::str::FromStr;
5+
use core::{fmt, hash};
66
#[cfg(feature = "std")]
77
use std::error;
88

@@ -212,6 +212,35 @@ impl fmt::Display for Wildcard {
212212
}
213213
}
214214

215+
impl fmt::Display for SinglePub {
216+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217+
maybe_fmt_master_id(f, &self.origin)?;
218+
match self.key {
219+
SinglePubKey::FullKey(full_key) => full_key.fmt(f),
220+
SinglePubKey::XOnly(x_only_key) => x_only_key.fmt(f),
221+
}?;
222+
Ok(())
223+
}
224+
}
225+
226+
impl MiniscriptKey for SinglePub {
227+
type Sha256 = sha256::Hash;
228+
type Hash256 = hash256::Hash;
229+
type Ripemd160 = ripemd160::Hash;
230+
type Hash160 = hash160::Hash;
231+
232+
fn is_x_only_key(&self) -> bool { matches!(self.key, SinglePubKey::XOnly(_)) }
233+
234+
fn num_der_paths(&self) -> usize { 0 }
235+
236+
fn is_uncompressed(&self) -> bool {
237+
match self.key {
238+
SinglePubKey::FullKey(ref key) => key.is_uncompressed(),
239+
_ => false,
240+
}
241+
}
242+
}
243+
215244
impl SinglePriv {
216245
/// Returns the public key of this key.
217246
fn to_public<C: Signing>(&self, secp: &Secp256k1<C>) -> SinglePub {
@@ -269,6 +298,30 @@ impl DescriptorXKey<bip32::Xpriv> {
269298
}
270299
}
271300

301+
impl<K: InnerXKey> fmt::Display for DescriptorXKey<K> {
302+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
303+
maybe_fmt_master_id(f, &self.origin)?;
304+
self.xkey.fmt(f)?;
305+
fmt_derivation_path(f, &self.derivation_path)?;
306+
self.wildcard.fmt(f)?;
307+
Ok(())
308+
}
309+
}
310+
311+
impl<K> MiniscriptKey for DescriptorXKey<K>
312+
where
313+
K: InnerXKey + Clone + Ord + Eq + hash::Hash + fmt::Debug,
314+
{
315+
type Sha256 = sha256::Hash;
316+
type Hash256 = hash256::Hash;
317+
type Ripemd160 = ripemd160::Hash;
318+
type Hash160 = hash160::Hash;
319+
320+
fn is_x_only_key(&self) -> bool { false }
321+
322+
fn num_der_paths(&self) -> usize { 1 }
323+
}
324+
272325
impl DescriptorMultiXKey<bip32::Xpriv> {
273326
/// Returns the public version of this multi-key, applying all the hardened derivation steps that
274327
/// are shared among all derivation paths before turning it into a public key.
@@ -350,6 +403,30 @@ impl DescriptorMultiXKey<bip32::Xpriv> {
350403
}
351404
}
352405

406+
impl<K: InnerXKey> fmt::Display for DescriptorMultiXKey<K> {
407+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
408+
maybe_fmt_master_id(f, &self.origin)?;
409+
self.xkey.fmt(f)?;
410+
fmt_derivation_paths(f, self.derivation_paths.paths())?;
411+
self.wildcard.fmt(f)?;
412+
Ok(())
413+
}
414+
}
415+
416+
impl<K> MiniscriptKey for DescriptorMultiXKey<K>
417+
where
418+
K: InnerXKey + Clone + Ord + Eq + hash::Hash + fmt::Debug,
419+
{
420+
type Sha256 = sha256::Hash;
421+
type Hash256 = hash256::Hash;
422+
type Ripemd160 = ripemd160::Hash;
423+
type Hash160 = hash160::Hash;
424+
425+
fn is_x_only_key(&self) -> bool { false }
426+
427+
fn num_der_paths(&self) -> usize { self.derivation_paths.paths().len() }
428+
}
429+
353430
/// Kinds of malformed key data
354431
#[derive(Debug, PartialEq, Eq, Clone)]
355432
#[non_exhaustive]
@@ -531,28 +608,9 @@ impl From<bip32::Error> for XKeyParseError {
531608
impl fmt::Display for DescriptorPublicKey {
532609
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
533610
match *self {
534-
Self::Single(ref pk) => {
535-
maybe_fmt_master_id(f, &pk.origin)?;
536-
match pk.key {
537-
SinglePubKey::FullKey(full_key) => full_key.fmt(f),
538-
SinglePubKey::XOnly(x_only_key) => x_only_key.fmt(f),
539-
}?;
540-
Ok(())
541-
}
542-
Self::XPub(ref xpub) => {
543-
maybe_fmt_master_id(f, &xpub.origin)?;
544-
xpub.xkey.fmt(f)?;
545-
fmt_derivation_path(f, &xpub.derivation_path)?;
546-
xpub.wildcard.fmt(f)?;
547-
Ok(())
548-
}
549-
Self::MultiXPub(ref xpub) => {
550-
maybe_fmt_master_id(f, &xpub.origin)?;
551-
xpub.xkey.fmt(f)?;
552-
fmt_derivation_paths(f, xpub.derivation_paths.paths())?;
553-
xpub.wildcard.fmt(f)?;
554-
Ok(())
555-
}
611+
Self::Single(ref pk) => pk.fmt(f),
612+
Self::XPub(ref xpub) => xpub.fmt(f),
613+
Self::MultiXPub(ref xpub) => xpub.fmt(f),
556614
}
557615
}
558616
}
@@ -1292,25 +1350,23 @@ impl MiniscriptKey for DescriptorPublicKey {
12921350

12931351
fn is_uncompressed(&self) -> bool {
12941352
match self {
1295-
DescriptorPublicKey::Single(SinglePub {
1296-
key: SinglePubKey::FullKey(ref key), ..
1297-
}) => key.is_uncompressed(),
1353+
DescriptorPublicKey::Single(key) => key.is_uncompressed(),
12981354
_ => false,
12991355
}
13001356
}
13011357

13021358
fn is_x_only_key(&self) -> bool {
1303-
matches!(
1304-
self,
1305-
DescriptorPublicKey::Single(SinglePub { key: SinglePubKey::XOnly(ref _key), .. })
1306-
)
1359+
match self {
1360+
DescriptorPublicKey::Single(single_pub) => single_pub.is_x_only_key(),
1361+
_ => false,
1362+
}
13071363
}
13081364

13091365
fn num_der_paths(&self) -> usize {
13101366
match self {
1311-
DescriptorPublicKey::Single(_) => 0,
1312-
DescriptorPublicKey::XPub(_) => 1,
1313-
DescriptorPublicKey::MultiXPub(xpub) => xpub.derivation_paths.paths().len(),
1367+
DescriptorPublicKey::Single(single) => single.num_der_paths(),
1368+
DescriptorPublicKey::XPub(xpub) => xpub.num_der_paths(),
1369+
DescriptorPublicKey::MultiXPub(xpub) => xpub.num_der_paths(),
13141370
}
13151371
}
13161372
}

0 commit comments

Comments
 (0)