@@ -54,8 +54,9 @@ use miniscript::descriptor::{
5454 DescriptorPublicKey , ShInner , SinglePub , SinglePubKey , SortedMultiVec , WshInner ,
5555} ;
5656use miniscript:: hash256;
57+ use miniscript:: miniscript:: limits:: { MAX_PUBKEYS_IN_CHECKSIGADD , MAX_PUBKEYS_PER_MULTISIG } ;
5758use miniscript:: {
58- Descriptor , Miniscript , Satisfier , ScriptContext , SigType , Terminal , ToPublicKey ,
59+ Descriptor , Miniscript , Satisfier , ScriptContext , SigType , Terminal , Threshold , ToPublicKey ,
5960} ;
6061
6162use crate :: descriptor:: ExtractPolicy ;
@@ -586,30 +587,78 @@ impl Policy {
586587 Ok ( Some ( policy) )
587588 }
588589
589- fn make_multisig < Ctx : ScriptContext + ' static > (
590- keys : & [ DescriptorPublicKey ] ,
590+ fn make_multi < Ctx : ScriptContext + ' static > (
591+ threshold : & Threshold < DescriptorPublicKey , MAX_PUBKEYS_PER_MULTISIG > ,
591592 signers : & SignersContainer ,
592593 build_sat : BuildSatisfaction ,
593- threshold : usize ,
594594 sorted : bool ,
595595 secp : & SecpCtx ,
596596 ) -> Result < Option < Policy > , PolicyError > {
597- if threshold == 0 {
598- return Ok ( None ) ;
597+ let parsed_keys = threshold. iter ( ) . map ( |k| PkOrF :: from_key ( k, secp) ) . collect ( ) ;
598+
599+ let mut contribution = Satisfaction :: Partial {
600+ n : threshold. n ( ) ,
601+ m : threshold. k ( ) ,
602+ items : vec ! [ ] ,
603+ conditions : Default :: default ( ) ,
604+ sorted : Some ( sorted) ,
605+ } ;
606+ let mut satisfaction = contribution. clone ( ) ;
607+
608+ for ( index, key) in threshold. iter ( ) . enumerate ( ) {
609+ if signers. find ( signer_id ( key, secp) ) . is_some ( ) {
610+ contribution. add (
611+ & Satisfaction :: Complete {
612+ condition : Default :: default ( ) ,
613+ } ,
614+ index,
615+ ) ?;
616+ }
617+
618+ if let Some ( psbt) = build_sat. psbt ( ) {
619+ if Ctx :: find_signature ( psbt, key, secp) {
620+ satisfaction. add (
621+ & Satisfaction :: Complete {
622+ condition : Default :: default ( ) ,
623+ } ,
624+ index,
625+ ) ?;
626+ }
627+ }
628+ }
629+ satisfaction. finalize ( ) ;
630+ contribution. finalize ( ) ;
631+
632+ let mut policy: Policy = SatisfiableItem :: Multisig {
633+ keys : parsed_keys,
634+ threshold : threshold. k ( ) ,
599635 }
636+ . into ( ) ;
637+ policy. contribution = contribution;
638+ policy. satisfaction = satisfaction;
639+
640+ Ok ( Some ( policy) )
641+ }
600642
601- let parsed_keys = keys. iter ( ) . map ( |k| PkOrF :: from_key ( k, secp) ) . collect ( ) ;
643+ fn make_multi_a < Ctx : ScriptContext + ' static > (
644+ threshold : & Threshold < DescriptorPublicKey , MAX_PUBKEYS_IN_CHECKSIGADD > ,
645+ signers : & SignersContainer ,
646+ build_sat : BuildSatisfaction ,
647+ sorted : bool ,
648+ secp : & SecpCtx ,
649+ ) -> Result < Option < Policy > , PolicyError > {
650+ let parsed_keys = threshold. iter ( ) . map ( |k| PkOrF :: from_key ( k, secp) ) . collect ( ) ;
602651
603652 let mut contribution = Satisfaction :: Partial {
604- n : keys . len ( ) ,
605- m : threshold,
653+ n : threshold . n ( ) ,
654+ m : threshold. k ( ) ,
606655 items : vec ! [ ] ,
607656 conditions : Default :: default ( ) ,
608657 sorted : Some ( sorted) ,
609658 } ;
610659 let mut satisfaction = contribution. clone ( ) ;
611660
612- for ( index, key) in keys . iter ( ) . enumerate ( ) {
661+ for ( index, key) in threshold . iter ( ) . enumerate ( ) {
613662 if signers. find ( signer_id ( key, secp) ) . is_some ( ) {
614663 contribution. add (
615664 & Satisfaction :: Complete {
@@ -635,7 +684,7 @@ impl Policy {
635684
636685 let mut policy: Policy = SatisfiableItem :: Multisig {
637686 keys : parsed_keys,
638- threshold,
687+ threshold : threshold . k ( ) ,
639688 }
640689 . into ( ) ;
641690 policy. contribution = contribution;
@@ -952,11 +1001,14 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
9521001 Some ( policy)
9531002 }
9541003 Terminal :: Older ( value) => {
955- let mut policy: Policy = SatisfiableItem :: RelativeTimelock { value : * value } . into ( ) ;
1004+ let mut policy: Policy = SatisfiableItem :: RelativeTimelock {
1005+ value : ( ( * value) . into ( ) ) ,
1006+ }
1007+ . into ( ) ;
9561008 policy. contribution = Satisfaction :: Complete {
9571009 condition : Condition {
9581010 timelock : None ,
959- csv : Some ( * value) ,
1011+ csv : Some ( Sequence :: from ( * value) ) ,
9601012 } ,
9611013 } ;
9621014 if let BuildSatisfaction :: PsbtTimelocks {
@@ -966,9 +1018,11 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
9661018 } = build_sat
9671019 {
9681020 let older = Older :: new ( Some ( current_height) , Some ( input_max_height) , false ) ;
969- let older_sat = Satisfier :: < bitcoin:: PublicKey > :: check_older ( & older, * value) ;
970- let inputs_sat = psbt_inputs_sat ( psbt)
971- . all ( |sat| Satisfier :: < bitcoin:: PublicKey > :: check_older ( & sat, * value) ) ;
1021+ let older_sat =
1022+ Satisfier :: < bitcoin:: PublicKey > :: check_older ( & older, ( * value) . into ( ) ) ;
1023+ let inputs_sat = psbt_inputs_sat ( psbt) . all ( |sat| {
1024+ Satisfier :: < bitcoin:: PublicKey > :: check_older ( & sat, ( * value) . into ( ) )
1025+ } ) ;
9721026 if older_sat && inputs_sat {
9731027 policy. satisfaction = policy. contribution . clone ( ) ;
9741028 }
@@ -986,8 +1040,11 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
9861040 Terminal :: Hash160 ( hash) => {
9871041 Some ( SatisfiableItem :: Hash160Preimage { hash : * hash } . into ( ) )
9881042 }
989- Terminal :: Multi ( k, pks) | Terminal :: MultiA ( k, pks) => {
990- Policy :: make_multisig :: < Ctx > ( pks, signers, build_sat, * k, false , secp) ?
1043+ Terminal :: Multi ( ref thresh) => {
1044+ Policy :: make_multi :: < Ctx > ( thresh, signers, build_sat, false , secp) ?
1045+ }
1046+ Terminal :: MultiA ( ref thresh) => {
1047+ Policy :: make_multi_a :: < Ctx > ( thresh, signers, build_sat, false , secp) ?
9911048 }
9921049 // Identities
9931050 Terminal :: Alt ( inner)
@@ -1087,13 +1144,10 @@ impl ExtractPolicy for Descriptor<DescriptorPublicKey> {
10871144 build_sat : BuildSatisfaction ,
10881145 secp : & SecpCtx ,
10891146 ) -> Result < Option < Policy > , Error > {
1090- Ok ( Policy :: make_multisig :: < Ctx > (
1091- keys. pks . as_ref ( ) ,
1092- signers,
1093- build_sat,
1094- keys. k ,
1095- true ,
1096- secp,
1147+ let thresh =
1148+ Threshold :: new ( keys. k ( ) , keys. pks ( ) . to_vec ( ) ) . expect ( "TODO: Handle this error" ) ;
1149+ Ok ( Policy :: make_multi :: < Ctx > (
1150+ & thresh, signers, build_sat, true , secp,
10971151 ) ?)
10981152 }
10991153
0 commit comments