@@ -23,8 +23,9 @@ use sync::Arc;
2323use self :: checksum:: verify_checksum;
2424use crate :: miniscript:: decode:: Terminal ;
2525use crate :: miniscript:: { satisfy, Legacy , Miniscript , Segwitv0 } ;
26- use crate :: plan:: { AssetProvider , Plan } ;
26+ use crate :: plan:: { AssetProvider , Assets , Plan } ;
2727use crate :: prelude:: * ;
28+ use crate :: util:: get_asset_combination;
2829use crate :: {
2930 expression, hash256, BareCtx , Error , ForEachKey , MiniscriptKey , Satisfier , ToPublicKey ,
3031 TranslateErr , TranslatePk , Translator ,
@@ -568,6 +569,124 @@ impl Descriptor<DefiniteDescriptorKey> {
568569 }
569570}
570571
572+ impl Descriptor < DescriptorPublicKey > {
573+ /// Count total possible assets for a given descriptor.
574+ pub fn count_assets ( & self ) -> u64 {
575+ match self {
576+ Descriptor :: Bare ( k) => k. as_inner ( ) . count_assets ( ) ,
577+ Descriptor :: Pkh ( _) => 1 ,
578+ Descriptor :: Wpkh ( _) => 1 ,
579+ Descriptor :: Sh ( k) => match k. as_inner ( ) {
580+ ShInner :: Wsh ( k) => match k. as_inner ( ) {
581+ WshInner :: SortedMulti ( k) => {
582+ let n = k. pks . len ( ) as u64 ;
583+ let k = k. k as u64 ;
584+ Self :: k_of_n ( k, n)
585+ }
586+ WshInner :: Ms ( k) => k. count_assets ( ) ,
587+ } ,
588+ ShInner :: Wpkh ( _) => 1 ,
589+ ShInner :: SortedMulti ( k) => {
590+ let n = k. clone ( ) . pks . len ( ) as u64 ;
591+ let k = k. clone ( ) . k as u64 ;
592+ Self :: k_of_n ( k, n)
593+ }
594+ ShInner :: Ms ( k) => k. count_assets ( ) ,
595+ } ,
596+ Descriptor :: Wsh ( k) => match k. as_inner ( ) {
597+ WshInner :: SortedMulti ( k) => {
598+ let n = k. clone ( ) . pks . len ( ) as u64 ;
599+ let k = k. clone ( ) . k as u64 ;
600+ Self :: k_of_n ( k, n)
601+ }
602+ WshInner :: Ms ( k) => k. count_assets ( ) ,
603+ } ,
604+ Descriptor :: Tr ( k) => {
605+ let s = k. taptree ( ) . clone ( ) . unwrap ( ) ;
606+ match s {
607+ TapTree :: Tree ( ref left, ref right) => {
608+ let a = left. count_assets ( ) ;
609+ let b = right. count_assets ( ) ;
610+ a + b
611+ }
612+ TapTree :: Leaf ( k) => k. count_assets ( ) ,
613+ }
614+ }
615+ }
616+ }
617+
618+ /// Get all possible assets for a given descriptor
619+ pub fn all_assets ( & self ) -> Result < Vec < Assets > , Error > {
620+ match self {
621+ Descriptor :: Bare ( k) => Ok ( k. as_inner ( ) . all_assets ( ) ) ,
622+ Descriptor :: Pkh ( k) => {
623+ let mut asset = Assets :: new ( ) ;
624+ asset = asset. add ( k. as_inner ( ) . clone ( ) ) ;
625+ Ok ( vec ! [ asset] )
626+ }
627+ Descriptor :: Wpkh ( k) => {
628+ let mut asset = Assets :: new ( ) ;
629+ asset = asset. add ( k. as_inner ( ) . clone ( ) ) ;
630+ Ok ( vec ! [ asset] )
631+ }
632+ Descriptor :: Sh ( k) => match k. as_inner ( ) {
633+ ShInner :: Wsh ( k) => match k. as_inner ( ) {
634+ WshInner :: SortedMulti ( k) => {
635+ let dpk_v = k. clone ( ) . pks ;
636+ let k = k. clone ( ) . k ;
637+ Ok ( get_asset_combination ( k, & dpk_v) )
638+ }
639+ WshInner :: Ms ( k) => Ok ( k. all_assets ( ) ) ,
640+ } ,
641+ ShInner :: Wpkh ( k) => {
642+ let mut asset = Assets :: new ( ) ;
643+ asset = asset. add ( k. as_inner ( ) . clone ( ) ) ;
644+ Ok ( vec ! [ asset] )
645+ }
646+ ShInner :: SortedMulti ( k) => {
647+ let dpk_v = k. clone ( ) . pks ;
648+ let k = k. clone ( ) . k ;
649+ Ok ( get_asset_combination ( k, & dpk_v) )
650+ }
651+ ShInner :: Ms ( k) => Ok ( k. all_assets ( ) ) ,
652+ } ,
653+ Descriptor :: Wsh ( k) => match k. as_inner ( ) {
654+ WshInner :: SortedMulti ( k) => {
655+ let dpk_v = k. clone ( ) . pks ;
656+ let k = k. clone ( ) . k ;
657+ Ok ( get_asset_combination ( k, & dpk_v) )
658+ }
659+ WshInner :: Ms ( k) => {
660+ println ! ( "{}" , k) ;
661+ let a = k. all_assets ( ) ;
662+ println ! ( "{:#?}" , a) ;
663+ Ok ( a)
664+ }
665+ } ,
666+ Descriptor :: Tr ( k) => {
667+ let s = k. taptree ( ) . clone ( ) . unwrap ( ) ;
668+ match s {
669+ TapTree :: Tree ( ref left, ref right) => {
670+ let mut a = left. all_assets ( ) ;
671+ let b = right. all_assets ( ) ;
672+ a. extend ( b) ;
673+ Ok ( a)
674+ }
675+ TapTree :: Leaf ( k) => Ok ( k. all_assets ( ) ) ,
676+ }
677+ }
678+ }
679+ }
680+
681+ // ways to select k things out of n
682+ fn k_of_n ( k : u64 , n : u64 ) -> u64 {
683+ if k == 0 || k == n {
684+ return 1 ;
685+ }
686+ Self :: k_of_n ( k - 1 , n - 1 ) + Self :: k_of_n ( k - 1 , n)
687+ }
688+ }
689+
571690impl < P , Q > TranslatePk < P , Q > for Descriptor < P >
572691where
573692 P : MiniscriptKey ,
@@ -2094,4 +2213,75 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
20942213 Desc :: from_str ( & format ! ( "tr({},pk({}))" , x_only_key, uncomp_key) ) . unwrap_err ( ) ;
20952214 Desc :: from_str ( & format ! ( "tr({},pk({}))" , x_only_key, x_only_key) ) . unwrap ( ) ;
20962215 }
2216+
2217+ #[ test]
2218+ fn test_all_assets_bare ( ) {
2219+ let descriptor = Descriptor :: < DescriptorPublicKey > :: from_str (
2220+ "pk(0237b1c59ab055a8d3de40eaeb215c7b1922664b5ac049d849fb3346f81431e77f)" ,
2221+ )
2222+ . unwrap ( ) ;
2223+
2224+ // Getting the assets from the all_assets method
2225+ let assets = descriptor. all_assets ( ) . unwrap ( ) ;
2226+
2227+ let mut expected_asset = Assets :: new ( ) ;
2228+ expected_asset = expected_asset. add (
2229+ DescriptorPublicKey :: from_str (
2230+ "0237b1c59ab055a8d3de40eaeb215c7b1922664b5ac049d849fb3346f81431e77f" ,
2231+ )
2232+ . unwrap ( ) ,
2233+ ) ;
2234+ assert_eq ! ( assets, vec![ expected_asset] ) ;
2235+ }
2236+
2237+ #[ test]
2238+ fn test_all_assets_sh_sortedmulti ( ) {
2239+ let keys = vec ! [
2240+ "0360eabc52e04f70c89e944f379895cdff28fed60849afe7736815c091765afb3c" ,
2241+ "03a80a24196e66ccf6bca6e6f96633bb629ec702acd76b074de10922b0cf41cc81" ,
2242+ ] ;
2243+
2244+ let descriptor = Descriptor :: < DescriptorPublicKey > :: from_str ( & format ! (
2245+ "sh(sortedmulti(1,{},{}))" ,
2246+ keys[ 0 ] , keys[ 1 ]
2247+ ) )
2248+ . unwrap ( ) ;
2249+
2250+ let assets = descriptor. all_assets ( ) . unwrap ( ) ;
2251+
2252+ let mut expected_assets: Vec < Assets > = Vec :: new ( ) ;
2253+
2254+ let mut asset1 = Assets :: new ( ) ;
2255+ asset1 = asset1. add ( DescriptorPublicKey :: from_str ( keys[ 0 ] ) . unwrap ( ) ) ;
2256+ expected_assets. push ( asset1) ;
2257+
2258+ let mut asset2 = Assets :: new ( ) ;
2259+ asset2 = asset2. add ( DescriptorPublicKey :: from_str ( keys[ 1 ] ) . unwrap ( ) ) ;
2260+ expected_assets. push ( asset2) ;
2261+
2262+ for expected_asset in & expected_assets {
2263+ assert ! ( assets. contains( expected_asset) ) ;
2264+ }
2265+ }
2266+
2267+ #[ test]
2268+ fn test_all_assets_taproot ( ) {
2269+ let x_only_key = bitcoin:: key:: XOnlyPublicKey :: from_str (
2270+ "015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab" ,
2271+ )
2272+ . unwrap ( ) ;
2273+ let descriptor =
2274+ Descriptor :: from_str ( & format ! ( "tr({},pk({}))" , x_only_key, x_only_key) ) . unwrap ( ) ;
2275+ let assets = descriptor. all_assets ( ) . unwrap ( ) ;
2276+ let mut expected_assets: Vec < Assets > = Vec :: new ( ) ;
2277+ let mut asset_1 = Assets :: new ( ) ;
2278+ asset_1 = asset_1. add (
2279+ DescriptorPublicKey :: from_str (
2280+ "015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab" ,
2281+ )
2282+ . unwrap ( ) ,
2283+ ) ;
2284+ expected_assets. push ( asset_1) ;
2285+ assert_eq ! ( assets, expected_assets) ;
2286+ }
20972287}
0 commit comments