@@ -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,86 @@ 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 {
597+ if threshold. k ( ) == 0 {
598598 return Ok ( None ) ;
599599 }
600600
601- let parsed_keys = keys . iter ( ) . map ( |k| PkOrF :: from_key ( k, secp) ) . collect ( ) ;
601+ let parsed_keys = threshold . iter ( ) . map ( |k| PkOrF :: from_key ( k, secp) ) . collect ( ) ;
602602
603603 let mut contribution = Satisfaction :: Partial {
604- n : keys. len ( ) ,
605- m : threshold,
604+ n : threshold. n ( ) ,
605+ m : threshold. k ( ) ,
606+ items : vec ! [ ] ,
607+ conditions : Default :: default ( ) ,
608+ sorted : Some ( sorted) ,
609+ } ;
610+ let mut satisfaction = contribution. clone ( ) ;
611+
612+ for ( index, key) in threshold. iter ( ) . enumerate ( ) {
613+ if signers. find ( signer_id ( key, secp) ) . is_some ( ) {
614+ contribution. add (
615+ & Satisfaction :: Complete {
616+ condition : Default :: default ( ) ,
617+ } ,
618+ index,
619+ ) ?;
620+ }
621+
622+ if let Some ( psbt) = build_sat. psbt ( ) {
623+ if Ctx :: find_signature ( psbt, key, secp) {
624+ satisfaction. add (
625+ & Satisfaction :: Complete {
626+ condition : Default :: default ( ) ,
627+ } ,
628+ index,
629+ ) ?;
630+ }
631+ }
632+ }
633+ satisfaction. finalize ( ) ;
634+ contribution. finalize ( ) ;
635+
636+ let mut policy: Policy = SatisfiableItem :: Multisig {
637+ keys : parsed_keys,
638+ threshold : threshold. k ( ) ,
639+ }
640+ . into ( ) ;
641+ policy. contribution = contribution;
642+ policy. satisfaction = satisfaction;
643+
644+ Ok ( Some ( policy) )
645+ }
646+
647+ fn make_multi_a < Ctx : ScriptContext + ' static > (
648+ threshold : & Threshold < DescriptorPublicKey , MAX_PUBKEYS_IN_CHECKSIGADD > ,
649+ signers : & SignersContainer ,
650+ build_sat : BuildSatisfaction ,
651+ sorted : bool ,
652+ secp : & SecpCtx ,
653+ ) -> Result < Option < Policy > , PolicyError > {
654+ if threshold. k ( ) == 0 {
655+ return Ok ( None ) ;
656+ }
657+
658+ let parsed_keys = threshold. iter ( ) . map ( |k| PkOrF :: from_key ( k, secp) ) . collect ( ) ;
659+
660+ let mut contribution = Satisfaction :: Partial {
661+ n : threshold. n ( ) ,
662+ m : threshold. k ( ) ,
606663 items : vec ! [ ] ,
607664 conditions : Default :: default ( ) ,
608665 sorted : Some ( sorted) ,
609666 } ;
610667 let mut satisfaction = contribution. clone ( ) ;
611668
612- for ( index, key) in keys . iter ( ) . enumerate ( ) {
669+ for ( index, key) in threshold . iter ( ) . enumerate ( ) {
613670 if signers. find ( signer_id ( key, secp) ) . is_some ( ) {
614671 contribution. add (
615672 & Satisfaction :: Complete {
@@ -635,7 +692,7 @@ impl Policy {
635692
636693 let mut policy: Policy = SatisfiableItem :: Multisig {
637694 keys : parsed_keys,
638- threshold,
695+ threshold : threshold . k ( ) ,
639696 }
640697 . into ( ) ;
641698 policy. contribution = contribution;
@@ -952,11 +1009,14 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
9521009 Some ( policy)
9531010 }
9541011 Terminal :: Older ( value) => {
955- let mut policy: Policy = SatisfiableItem :: RelativeTimelock { value : * value } . into ( ) ;
1012+ let mut policy: Policy = SatisfiableItem :: RelativeTimelock {
1013+ value : ( ( * value) . into ( ) ) ,
1014+ }
1015+ . into ( ) ;
9561016 policy. contribution = Satisfaction :: Complete {
9571017 condition : Condition {
9581018 timelock : None ,
959- csv : Some ( * value) ,
1019+ csv : Some ( Sequence :: from ( * value) ) ,
9601020 } ,
9611021 } ;
9621022 if let BuildSatisfaction :: PsbtTimelocks {
@@ -966,9 +1026,11 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
9661026 } = build_sat
9671027 {
9681028 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) ) ;
1029+ let older_sat =
1030+ Satisfier :: < bitcoin:: PublicKey > :: check_older ( & older, ( * value) . into ( ) ) ;
1031+ let inputs_sat = psbt_inputs_sat ( psbt) . all ( |sat| {
1032+ Satisfier :: < bitcoin:: PublicKey > :: check_older ( & sat, ( * value) . into ( ) )
1033+ } ) ;
9721034 if older_sat && inputs_sat {
9731035 policy. satisfaction = policy. contribution . clone ( ) ;
9741036 }
@@ -986,8 +1048,11 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
9861048 Terminal :: Hash160 ( hash) => {
9871049 Some ( SatisfiableItem :: Hash160Preimage { hash : * hash } . into ( ) )
9881050 }
989- Terminal :: Multi ( k, pks) | Terminal :: MultiA ( k, pks) => {
990- Policy :: make_multisig :: < Ctx > ( pks, signers, build_sat, * k, false , secp) ?
1051+ Terminal :: Multi ( ref thresh) => {
1052+ Policy :: make_multi :: < Ctx > ( thresh, signers, build_sat, false , secp) ?
1053+ }
1054+ Terminal :: MultiA ( ref thresh) => {
1055+ Policy :: make_multi_a :: < Ctx > ( thresh, signers, build_sat, false , secp) ?
9911056 }
9921057 // Identities
9931058 Terminal :: Alt ( inner)
@@ -1087,13 +1152,10 @@ impl ExtractPolicy for Descriptor<DescriptorPublicKey> {
10871152 build_sat : BuildSatisfaction ,
10881153 secp : & SecpCtx ,
10891154 ) -> 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,
1155+ let thresh =
1156+ Threshold :: new ( keys. k ( ) , keys. pks ( ) . to_vec ( ) ) . expect ( "TODO: Handle this error" ) ;
1157+ Ok ( Policy :: make_multi :: < Ctx > (
1158+ & thresh, signers, build_sat, true , secp,
10971159 ) ?)
10981160 }
10991161
0 commit comments