@@ -535,8 +535,12 @@ impl TaprootAvailableLeaves {
535
535
/// The Assets we can use to satisfy a particular spending path
536
536
#[ derive( Debug , Default ) ]
537
537
pub struct Assets {
538
- /// Keys the user can sign for, and how
539
- pub keys : HashSet < ( DescriptorPublicKey , CanSign ) > ,
538
+ /// Keys the user can sign for, and how. A pair `(fingerprint, derivation_path)` is
539
+ /// provided, meaning that the user can sign using the key with `fingerprint`,
540
+ /// derived with either `derivation_path` or a derivation path that extends `derivation_path`
541
+ /// by exactly one child number. For example, if the derivation path `m/0/1` is provided, the
542
+ /// user can sign with either `m/0/1` or `m/0/1/*`.
543
+ pub keys : HashSet < ( bip32:: KeySource , CanSign ) > ,
540
544
/// Set of available sha256 preimages
541
545
pub sha256_preimages : HashSet < sha256:: Hash > ,
542
546
/// Set of available hash256 preimages
@@ -551,16 +555,44 @@ pub struct Assets {
551
555
pub relative_timelock : Option < Sequence > ,
552
556
}
553
557
558
+ // Checks if the `pk` is a "direct child" of the `derivation_path` provided.
559
+ // Direct child means that the key derivation path is either the same as the
560
+ // `derivation_path`, or the same extened by exactly one child number.
561
+ // For example, `pk/0/1/2` is a direct child of `m/0/1` and of `m/0/1/2`,
562
+ // but not of `m/0`.
563
+ fn is_key_direct_child_of (
564
+ pk : & DefiniteDescriptorKey ,
565
+ derivation_path : & bip32:: DerivationPath ,
566
+ ) -> bool {
567
+ for pk_derivation_path in pk. full_derivation_paths ( ) {
568
+ if & pk_derivation_path == derivation_path {
569
+ return true ;
570
+ }
571
+
572
+ let definite_path_len = pk_derivation_path. len ( ) ;
573
+ if derivation_path. as_ref ( ) == & pk_derivation_path[ ..( definite_path_len - 1 ) ] {
574
+ return true ;
575
+ }
576
+ }
577
+
578
+ false
579
+ }
580
+
554
581
impl Assets {
555
582
pub ( crate ) fn has_ecdsa_key ( & self , pk : & DefiniteDescriptorKey ) -> bool {
556
- self . keys
557
- . iter ( )
558
- . any ( |( key, can_sign) | can_sign. ecdsa && key. is_parent ( pk) . is_some ( ) )
583
+ self . keys . iter ( ) . any ( |( keysource, can_sign) | {
584
+ can_sign. ecdsa
585
+ && pk. master_fingerprint ( ) == keysource. 0
586
+ && is_key_direct_child_of ( pk, & keysource. 1 )
587
+ } )
559
588
}
560
589
561
590
pub ( crate ) fn has_taproot_internal_key ( & self , pk : & DefiniteDescriptorKey ) -> Option < usize > {
562
- self . keys . iter ( ) . find_map ( |( key, can_sign) | {
563
- if !can_sign. taproot . key_spend || !key. is_parent ( pk) . is_some ( ) {
591
+ self . keys . iter ( ) . find_map ( |( keysource, can_sign) | {
592
+ if !can_sign. taproot . key_spend
593
+ || pk. master_fingerprint ( ) != keysource. 0
594
+ || !is_key_direct_child_of ( pk, & keysource. 1 )
595
+ {
564
596
None
565
597
} else {
566
598
Some ( can_sign. taproot . sig_len ( ) )
@@ -573,9 +605,10 @@ impl Assets {
573
605
pk : & DefiniteDescriptorKey ,
574
606
tap_leaf_hash : & TapLeafHash ,
575
607
) -> Option < usize > {
576
- self . keys . iter ( ) . find_map ( |( key , can_sign) | {
608
+ self . keys . iter ( ) . find_map ( |( keysource , can_sign) | {
577
609
if !can_sign. taproot . script_spend . is_available ( tap_leaf_hash)
578
- || !key. is_parent ( pk) . is_some ( )
610
+ || pk. master_fingerprint ( ) != keysource. 0
611
+ || !is_key_direct_child_of ( pk, & keysource. 1 )
579
612
{
580
613
None
581
614
} else {
@@ -640,11 +673,14 @@ impl AssetProvider<DefiniteDescriptorKey> for Assets {
640
673
641
674
impl FromIterator < DescriptorPublicKey > for Assets {
642
675
fn from_iter < I : IntoIterator < Item = DescriptorPublicKey > > ( iter : I ) -> Self {
676
+ let mut keys = HashSet :: new ( ) ;
677
+ for pk in iter {
678
+ for deriv_path in pk. full_derivation_paths ( ) {
679
+ keys. insert ( ( ( pk. master_fingerprint ( ) , deriv_path) , CanSign :: default ( ) ) ) ;
680
+ }
681
+ }
643
682
Assets {
644
- keys : iter
645
- . into_iter ( )
646
- . map ( |pk| ( pk, CanSign :: default ( ) ) )
647
- . collect ( ) ,
683
+ keys,
648
684
..Default :: default ( )
649
685
}
650
686
}
0 commit comments