@@ -18,10 +18,12 @@ use sync::Arc;
1818use crate :: miniscript:: context:: SigType ;
1919use crate :: miniscript:: types:: { self , Property } ;
2020use crate :: miniscript:: ScriptContext ;
21+ use crate :: plan:: Assets ;
2122use crate :: prelude:: * ;
2223use crate :: util:: MsKeyBuilder ;
2324use crate :: {
24- errstr, expression, AbsLockTime , Error , Miniscript , MiniscriptKey , Terminal , ToPublicKey ,
25+ errstr, expression, AbsLockTime , DescriptorPublicKey , Error , Miniscript , MiniscriptKey ,
26+ Terminal , ToPublicKey ,
2527} ;
2628
2729impl < Pk : MiniscriptKey , Ctx : ScriptContext > Terminal < Pk , Ctx > {
@@ -594,3 +596,233 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
594596 }
595597 }
596598}
599+
600+ impl < Ctx : ScriptContext > Terminal < DescriptorPublicKey , Ctx > {
601+ /// Retrieve the assets associated with the type of miniscript element.
602+ pub fn get_all_assets ( & self ) -> Vec < Assets > {
603+ match self {
604+ Terminal :: True => vec ! [ Assets :: new( ) ] ,
605+ Terminal :: False => Vec :: new ( ) ,
606+ Terminal :: PkK ( k) => {
607+ let mut asset = Assets :: new ( ) ;
608+ asset = asset. add ( k. clone ( ) ) ;
609+ vec ! [ asset]
610+ }
611+ Terminal :: PkH ( k) => {
612+ let mut asset = Assets :: new ( ) ;
613+ asset = asset. add ( k. clone ( ) ) ;
614+ vec ! [ asset]
615+ }
616+ Terminal :: RawPkH ( k) => {
617+ let mut asset = Assets :: new ( ) ;
618+ asset = asset. add ( k. clone ( ) ) ;
619+ vec ! [ asset]
620+ }
621+ Terminal :: After ( k) => {
622+ let mut asset = Assets :: new ( ) ;
623+ asset. absolute_timelock = Some ( k. clone ( ) . into ( ) ) ;
624+ vec ! [ asset]
625+ }
626+ Terminal :: Older ( k) => {
627+ let mut asset = Assets :: new ( ) ;
628+ asset. relative_timelock = Some ( k. clone ( ) ) ;
629+ vec ! [ asset]
630+ }
631+ Terminal :: Sha256 ( k) => {
632+ let mut asset = Assets :: new ( ) ;
633+ asset = asset. add ( k. clone ( ) ) ;
634+ vec ! [ asset]
635+ }
636+ Terminal :: Hash256 ( k) => {
637+ let mut asset = Assets :: new ( ) ;
638+ asset = asset. add ( k. clone ( ) ) ;
639+ vec ! [ asset]
640+ }
641+ Terminal :: Ripemd160 ( k) => {
642+ let mut asset = Assets :: new ( ) ;
643+ asset = asset. add ( k. clone ( ) ) ;
644+ vec ! [ asset]
645+ }
646+ Terminal :: Hash160 ( k) => {
647+ let mut asset = Assets :: new ( ) ;
648+ asset = asset. add ( k. clone ( ) ) ;
649+ vec ! [ asset]
650+ }
651+ Terminal :: Alt ( k) => k. get_all_assets ( ) ,
652+ Terminal :: Swap ( k) => k. get_all_assets ( ) ,
653+ Terminal :: Check ( k) => k. get_all_assets ( ) ,
654+ Terminal :: DupIf ( k) => k. get_all_assets ( ) ,
655+ Terminal :: Verify ( k) => k. get_all_assets ( ) ,
656+ Terminal :: NonZero ( k) => k. get_all_assets ( ) ,
657+ Terminal :: ZeroNotEqual ( k) => k. get_all_assets ( ) ,
658+ Terminal :: AndV ( left, right) => {
659+ let a = left. get_all_assets ( ) ;
660+ let b = right. get_all_assets ( ) ;
661+ let result: Vec < Assets > = a
662+ . into_iter ( )
663+ . flat_map ( |x| {
664+ b. clone ( ) . into_iter ( ) . map ( move |y| {
665+ let mut new_asset = Assets :: new ( ) ;
666+ new_asset = new_asset. add ( x. clone ( ) ) ;
667+ new_asset = new_asset. add ( y. clone ( ) ) ;
668+ new_asset
669+ } )
670+ } )
671+ . collect ( ) ;
672+ result
673+ }
674+ Terminal :: AndB ( left, right) => {
675+ let a = left. get_all_assets ( ) ;
676+ let b = right. get_all_assets ( ) ;
677+ let result: Vec < Assets > = a
678+ . into_iter ( )
679+ . flat_map ( |x| {
680+ b. clone ( ) . into_iter ( ) . map ( move |y| {
681+ let mut new_asset = Assets :: new ( ) ;
682+ new_asset = new_asset. add ( x. clone ( ) ) ;
683+ new_asset = new_asset. add ( y. clone ( ) ) ;
684+ new_asset
685+ } )
686+ } )
687+ . collect ( ) ;
688+ result
689+ }
690+ Terminal :: AndOr ( a, b, c) => {
691+ let a = a. get_all_assets ( ) ;
692+ let b = b. get_all_assets ( ) ;
693+ let mut c = c. get_all_assets ( ) ;
694+ let and: Vec < Assets > = a
695+ . into_iter ( )
696+ . flat_map ( |x| {
697+ b. clone ( ) . into_iter ( ) . map ( move |y| {
698+ let mut new_asset = Assets :: new ( ) ;
699+ new_asset = new_asset. add ( x. clone ( ) ) ;
700+ new_asset = new_asset. add ( y. clone ( ) ) ;
701+ new_asset
702+ } )
703+ } )
704+ . collect ( ) ;
705+ c. extend ( and) ;
706+ c
707+ }
708+ Terminal :: OrB ( left, right) => {
709+ let mut a = left. get_all_assets ( ) ;
710+ let b = right. get_all_assets ( ) ;
711+ a. extend ( b) ;
712+ a
713+ }
714+ Terminal :: OrD ( left, right) => {
715+ let mut a = left. get_all_assets ( ) ;
716+ let b = right. get_all_assets ( ) ;
717+ a. extend ( b) ;
718+ a
719+ }
720+ Terminal :: OrC ( left, right) => {
721+ let mut a = left. get_all_assets ( ) ;
722+ let b = right. get_all_assets ( ) ;
723+ a. extend ( b) ;
724+ a
725+ }
726+ Terminal :: OrI ( left, right) => {
727+ let mut a = left. get_all_assets ( ) ;
728+ let b = right. get_all_assets ( ) ;
729+ a. extend ( b) ;
730+ a
731+ }
732+ Terminal :: Thresh ( k, ms) => {
733+ let ms_v = Self :: get_ms_combination_thresh ( * k, ms) ;
734+ // k = 2
735+ // ms = [ms(A),ms(B),ms(C)];
736+ // ms_v = [[ms(A),ms(B)],[ms(A),ms(C)],[ms(B),ms(C)]]
737+ // Do ms_v[0] OR ms_v[1] OR ms_v[2]
738+ // Also Do ms_v[0][0] AND ms_v[0][1] and so on in the inner for loop
739+
740+ let mut result = Vec :: new ( ) ;
741+ for ms in ms_v {
742+ let mut and: Vec < Assets > = Vec :: new ( ) ;
743+ if let Some ( first_assets) = ms. first ( ) {
744+ and = first_assets. get_all_assets ( ) . clone ( ) ;
745+ }
746+ for i in ms. iter ( ) . skip ( 1 ) {
747+ let i_assets = i. get_all_assets ( ) ;
748+ and = and
749+ . iter ( )
750+ . flat_map ( |x| {
751+ i_assets. iter ( ) . map ( move |y| {
752+ let mut new_asset = x. clone ( ) ;
753+ new_asset = new_asset. add ( y. clone ( ) ) ;
754+ new_asset
755+ } )
756+ } )
757+ . collect ( ) ;
758+ }
759+ // OR of all combinations.
760+ result. extend ( and. clone ( ) ) ;
761+ }
762+ result
763+ }
764+ Terminal :: Multi ( k, dpk_v) => Self :: get_asset_combination ( * k, dpk_v) ,
765+ Terminal :: MultiA ( k, dpk_v) => Self :: get_asset_combination ( * k, dpk_v) ,
766+ }
767+ }
768+
769+ // Helper to get all possible pairs of K of N assets
770+ fn get_asset_combination ( k : usize , dpk_v : & Vec < DescriptorPublicKey > ) -> Vec < Assets > {
771+ let mut all_assets: Vec < Assets > = Vec :: new ( ) ;
772+ let current_assets = Assets :: new ( ) ;
773+ Self :: combine_assets ( k, dpk_v, 0 , current_assets, & mut all_assets) ;
774+ all_assets
775+ }
776+
777+ // Combine K of N assets
778+ fn combine_assets (
779+ k : usize ,
780+ dpk_v : & [ DescriptorPublicKey ] ,
781+ index : usize ,
782+ current_assets : Assets ,
783+ all_assets : & mut Vec < Assets > ,
784+ ) {
785+ if k == 0 {
786+ all_assets. push ( current_assets) ;
787+ return ;
788+ }
789+ if index >= dpk_v. len ( ) {
790+ return ;
791+ }
792+ Self :: combine_assets ( k, dpk_v, index + 1 , current_assets. clone ( ) , all_assets) ;
793+ let mut new_asset = current_assets;
794+ new_asset = new_asset. add ( dpk_v[ index] . clone ( ) ) ;
795+ println ! ( "{:#?}" , new_asset) ;
796+ Self :: combine_assets ( k - 1 , dpk_v, index + 1 , new_asset, all_assets)
797+ }
798+
799+ // Helper to get all combinations of K policies of N for thresh
800+ fn get_ms_combination_thresh (
801+ k : usize ,
802+ ms : & Vec < Arc < Miniscript < DescriptorPublicKey , Ctx > > > ,
803+ ) -> Vec < Vec < Arc < Miniscript < DescriptorPublicKey , Ctx > > > > {
804+ let mut result = Vec :: new ( ) ;
805+ let mut current_combination = Vec :: new ( ) ;
806+ Self :: combine_ms ( 0 , & mut current_combination, & mut result, ms, k) ;
807+ result
808+ }
809+
810+ // combine K policies of N for thresh
811+ fn combine_ms (
812+ start : usize ,
813+ current_combination : & mut Vec < Arc < Miniscript < DescriptorPublicKey , Ctx > > > ,
814+ result : & mut Vec < Vec < Arc < Miniscript < DescriptorPublicKey , Ctx > > > > ,
815+ ms : & Vec < Arc < Miniscript < DescriptorPublicKey , Ctx > > > ,
816+ k : usize ,
817+ ) {
818+ if current_combination. len ( ) == k {
819+ result. push ( current_combination. clone ( ) ) ;
820+ return ;
821+ }
822+ for i in start..ms. len ( ) {
823+ current_combination. push ( ms[ i] . clone ( ) ) ;
824+ Self :: combine_ms ( i + 1 , current_combination, result, ms, k) ;
825+ current_combination. truncate ( current_combination. len ( ) - 1 ) ;
826+ }
827+ }
828+ }
0 commit comments