@@ -892,6 +892,29 @@ pub struct Satisfaction<T> {
892892}
893893
894894impl < Pk : MiniscriptKey + ToPublicKey > Satisfaction < Placeholder < Pk > > {
895+ /// The empty satisfaction.
896+ ///
897+ /// This has the property that, when concatenated on either side with another satisfaction
898+ /// X, the result will be X.
899+ fn empty ( ) -> Self {
900+ Satisfaction {
901+ has_sig : false ,
902+ relative_timelock : None ,
903+ absolute_timelock : None ,
904+ stack : Witness :: Stack ( vec ! [ ] ) ,
905+ }
906+ }
907+
908+ /// Forms a satisfaction which is the concatenation of two satisfactions.
909+ fn concatenate ( self , other : Self ) -> Self {
910+ Satisfaction {
911+ has_sig : self . has_sig || other. has_sig ,
912+ relative_timelock : cmp:: max ( self . relative_timelock , other. relative_timelock ) ,
913+ absolute_timelock : cmp:: max ( self . absolute_timelock , other. absolute_timelock ) ,
914+ stack : Witness :: combine ( self . stack , other. stack ) ,
915+ }
916+ }
917+
895918 pub ( crate ) fn build_template < P , Ctx > (
896919 term : & Terminal < Pk , Ctx > ,
897920 provider : & P ,
@@ -1044,20 +1067,9 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
10441067 }
10451068 } else {
10461069 // Otherwise flatten everything out
1047- Satisfaction {
1048- has_sig : ret_stack. iter ( ) . any ( |sat| sat. has_sig ) ,
1049- relative_timelock : ret_stack
1050- . iter ( )
1051- . filter_map ( |sat| sat. relative_timelock )
1052- . max ( ) ,
1053- absolute_timelock : ret_stack
1054- . iter ( )
1055- . filter_map ( |sat| sat. absolute_timelock )
1056- . max ( ) ,
1057- stack : ret_stack
1058- . into_iter ( )
1059- . fold ( Witness :: empty ( ) , |acc, next| Witness :: combine ( next. stack , acc) ) ,
1060- }
1070+ ret_stack
1071+ . into_iter ( )
1072+ . fold ( Satisfaction :: empty ( ) , Satisfaction :: concatenate)
10611073 }
10621074 }
10631075
@@ -1128,20 +1140,9 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
11281140
11291141 // combine the witness
11301142 // no non-malleability checks needed
1131- Satisfaction {
1132- has_sig : ret_stack. iter ( ) . any ( |sat| sat. has_sig ) ,
1133- relative_timelock : ret_stack
1134- . iter ( )
1135- . filter_map ( |sat| sat. relative_timelock )
1136- . max ( ) ,
1137- absolute_timelock : ret_stack
1138- . iter ( )
1139- . filter_map ( |sat| sat. absolute_timelock )
1140- . max ( ) ,
1141- stack : ret_stack
1142- . into_iter ( )
1143- . fold ( Witness :: empty ( ) , |acc, next| Witness :: combine ( next. stack , acc) ) ,
1144- }
1143+ ret_stack
1144+ . into_iter ( )
1145+ . fold ( Satisfaction :: empty ( ) , Satisfaction :: concatenate)
11451146 }
11461147
11471148 fn minimum ( sat1 : Self , sat2 : Self ) -> Self {
@@ -1363,12 +1364,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
13631364 Self :: satisfy_helper ( & l. node , stfr, root_has_sig, leaf_hash, min_fn, thresh_fn) ;
13641365 let r_sat =
13651366 Self :: satisfy_helper ( & r. node , stfr, root_has_sig, leaf_hash, min_fn, thresh_fn) ;
1366- Satisfaction {
1367- stack : Witness :: combine ( r_sat. stack , l_sat. stack ) ,
1368- has_sig : l_sat. has_sig || r_sat. has_sig ,
1369- relative_timelock : cmp:: max ( l_sat. relative_timelock , r_sat. relative_timelock ) ,
1370- absolute_timelock : cmp:: max ( l_sat. absolute_timelock , r_sat. absolute_timelock ) ,
1371- }
1367+ r_sat. concatenate ( l_sat)
13721368 }
13731369 Terminal :: AndOr ( ref a, ref b, ref c) => {
13741370 let a_sat =
@@ -1386,27 +1382,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
13861382 let c_sat =
13871383 Self :: satisfy_helper ( & c. node , stfr, root_has_sig, leaf_hash, min_fn, thresh_fn) ;
13881384
1389- min_fn (
1390- Satisfaction {
1391- stack : Witness :: combine ( b_sat. stack , a_sat. stack ) ,
1392- has_sig : a_sat. has_sig || b_sat. has_sig ,
1393- relative_timelock : cmp:: max (
1394- a_sat. relative_timelock ,
1395- b_sat. relative_timelock ,
1396- ) ,
1397- absolute_timelock : cmp:: max (
1398- a_sat. absolute_timelock ,
1399- b_sat. absolute_timelock ,
1400- ) ,
1401- } ,
1402- Satisfaction {
1403- stack : Witness :: combine ( c_sat. stack , a_nsat. stack ) ,
1404- has_sig : a_nsat. has_sig || c_sat. has_sig ,
1405- // timelocks can't be dissatisfied, so here we ignore a_nsat and only consider c_sat
1406- relative_timelock : c_sat. relative_timelock ,
1407- absolute_timelock : c_sat. absolute_timelock ,
1408- } ,
1409- )
1385+ min_fn ( b_sat. concatenate ( a_sat) , c_sat. concatenate ( a_nsat) )
14101386 }
14111387 Terminal :: OrB ( ref l, ref r) => {
14121388 let l_sat =
@@ -1434,18 +1410,8 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
14341410 assert ! ( !r_nsat. has_sig) ;
14351411
14361412 min_fn (
1437- Satisfaction {
1438- stack : Witness :: combine ( r_sat. stack , l_nsat. stack ) ,
1439- has_sig : r_sat. has_sig ,
1440- relative_timelock : r_sat. relative_timelock ,
1441- absolute_timelock : r_sat. absolute_timelock ,
1442- } ,
1443- Satisfaction {
1444- stack : Witness :: combine ( r_nsat. stack , l_sat. stack ) ,
1445- has_sig : l_sat. has_sig ,
1446- relative_timelock : l_sat. relative_timelock ,
1447- absolute_timelock : l_sat. absolute_timelock ,
1448- } ,
1413+ Satisfaction :: concatenate ( r_sat, l_nsat) ,
1414+ Satisfaction :: concatenate ( r_nsat, l_sat) ,
14491415 )
14501416 }
14511417 Terminal :: OrD ( ref l, ref r) | Terminal :: OrC ( ref l, ref r) => {
@@ -1464,15 +1430,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
14641430
14651431 assert ! ( !l_nsat. has_sig) ;
14661432
1467- min_fn (
1468- l_sat,
1469- Satisfaction {
1470- stack : Witness :: combine ( r_sat. stack , l_nsat. stack ) ,
1471- has_sig : r_sat. has_sig ,
1472- relative_timelock : r_sat. relative_timelock ,
1473- absolute_timelock : r_sat. absolute_timelock ,
1474- } ,
1475- )
1433+ min_fn ( l_sat, Satisfaction :: concatenate ( r_sat, l_nsat) )
14761434 }
14771435 Terminal :: OrI ( ref l, ref r) => {
14781436 let l_sat =
@@ -1495,7 +1453,24 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
14951453 )
14961454 }
14971455 Terminal :: Thresh ( ref thresh) => {
1498- thresh_fn ( thresh, stfr, root_has_sig, leaf_hash, min_fn)
1456+ if thresh. k ( ) == thresh. n ( ) {
1457+ // this is just an and
1458+ thresh
1459+ . iter ( )
1460+ . map ( |s| {
1461+ Self :: satisfy_helper (
1462+ & s. node ,
1463+ stfr,
1464+ root_has_sig,
1465+ leaf_hash,
1466+ min_fn,
1467+ thresh_fn,
1468+ )
1469+ } )
1470+ . fold ( Satisfaction :: empty ( ) , Satisfaction :: concatenate)
1471+ } else {
1472+ thresh_fn ( thresh, stfr, root_has_sig, leaf_hash, min_fn)
1473+ }
14991474 }
15001475 Terminal :: Multi ( ref thresh) => {
15011476 // Collect all available signatures
@@ -1685,12 +1660,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
16851660 min_fn,
16861661 thresh_fn,
16871662 ) ;
1688- Satisfaction {
1689- stack : Witness :: combine ( odissat. stack , vsat. stack ) ,
1690- has_sig : vsat. has_sig || odissat. has_sig ,
1691- relative_timelock : None ,
1692- absolute_timelock : None ,
1693- }
1663+ odissat. concatenate ( vsat)
16941664 }
16951665 Terminal :: AndB ( ref l, ref r)
16961666 | Terminal :: OrB ( ref l, ref r)
@@ -1712,12 +1682,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
17121682 min_fn,
17131683 thresh_fn,
17141684 ) ;
1715- Satisfaction {
1716- stack : Witness :: combine ( rnsat. stack , lnsat. stack ) ,
1717- has_sig : rnsat. has_sig || lnsat. has_sig ,
1718- relative_timelock : None ,
1719- absolute_timelock : None ,
1720- }
1685+ rnsat. concatenate ( lnsat)
17211686 }
17221687 Terminal :: OrI ( ref l, ref r) => {
17231688 let lnsat = Self :: dissatisfy_helper (
@@ -1753,23 +1718,19 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
17531718 // Dissatisfactions don't need to non-malleable. Use minimum_mall always
17541719 Satisfaction :: minimum_mall ( dissat_1, dissat_2)
17551720 }
1756- Terminal :: Thresh ( ref thresh) => Satisfaction {
1757- stack : thresh. iter ( ) . fold ( Witness :: empty ( ) , |acc, sub| {
1758- let nsat = Self :: dissatisfy_helper (
1759- & sub. node ,
1721+ Terminal :: Thresh ( ref thresh) => thresh
1722+ . iter ( )
1723+ . map ( |s| {
1724+ Self :: dissatisfy_helper (
1725+ & s. node ,
17601726 stfr,
17611727 root_has_sig,
17621728 leaf_hash,
17631729 min_fn,
17641730 thresh_fn,
1765- ) ;
1766- assert ! ( !nsat. has_sig) ;
1767- Witness :: combine ( nsat. stack , acc)
1768- } ) ,
1769- has_sig : false ,
1770- relative_timelock : None ,
1771- absolute_timelock : None ,
1772- } ,
1731+ )
1732+ } )
1733+ . fold ( Satisfaction :: empty ( ) , Satisfaction :: concatenate) ,
17731734 Terminal :: Multi ( ref thresh) => Satisfaction {
17741735 stack : Witness :: Stack ( vec ! [ Placeholder :: PushZero ; thresh. k( ) + 1 ] ) ,
17751736 has_sig : false ,
0 commit comments