@@ -889,6 +889,34 @@ pub struct Satisfaction<T> {
889
889
}
890
890
891
891
impl < Pk : MiniscriptKey + ToPublicKey > Satisfaction < Placeholder < Pk > > {
892
+ /// The empty satisfaction.
893
+ ///
894
+ /// This has the property that, when concatenated on either side with another satisfaction
895
+ /// X, the result will be X.
896
+ fn empty ( ) -> Self {
897
+ Satisfaction {
898
+ has_sig : false ,
899
+ relative_timelock : None ,
900
+ absolute_timelock : None ,
901
+ stack : Witness :: Stack ( vec ! [ ] ) ,
902
+ }
903
+ }
904
+
905
+ /// Forms a satisfaction which is the concatenation of two satisfactions, with `other`'s
906
+ /// stack before `self`'s.
907
+ ///
908
+ /// This order allows callers to write `left.concatenate_rev(right)` which feels more
909
+ /// natural than the opposite order, and more importantly, allows this method to be
910
+ /// used when folding over an iterator of multiple satisfactions.
911
+ fn concatenate_rev ( self , other : Self ) -> Self {
912
+ Satisfaction {
913
+ has_sig : self . has_sig || other. has_sig ,
914
+ relative_timelock : cmp:: max ( self . relative_timelock , other. relative_timelock ) ,
915
+ absolute_timelock : cmp:: max ( self . absolute_timelock , other. absolute_timelock ) ,
916
+ stack : Witness :: combine ( other. stack , self . stack ) ,
917
+ }
918
+ }
919
+
892
920
pub ( crate ) fn build_template < P , Ctx > (
893
921
term : & Terminal < Pk , Ctx > ,
894
922
provider : & P ,
@@ -1041,20 +1069,9 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
1041
1069
}
1042
1070
} else {
1043
1071
// Otherwise flatten everything out
1044
- Satisfaction {
1045
- has_sig : ret_stack. iter ( ) . any ( |sat| sat. has_sig ) ,
1046
- relative_timelock : ret_stack
1047
- . iter ( )
1048
- . filter_map ( |sat| sat. relative_timelock )
1049
- . max ( ) ,
1050
- absolute_timelock : ret_stack
1051
- . iter ( )
1052
- . filter_map ( |sat| sat. absolute_timelock )
1053
- . max ( ) ,
1054
- stack : ret_stack
1055
- . into_iter ( )
1056
- . fold ( Witness :: empty ( ) , |acc, next| Witness :: combine ( next. stack , acc) ) ,
1057
- }
1072
+ ret_stack
1073
+ . into_iter ( )
1074
+ . fold ( Satisfaction :: empty ( ) , Satisfaction :: concatenate_rev)
1058
1075
}
1059
1076
}
1060
1077
@@ -1125,20 +1142,9 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
1125
1142
1126
1143
// combine the witness
1127
1144
// no non-malleability checks needed
1128
- Satisfaction {
1129
- has_sig : ret_stack. iter ( ) . any ( |sat| sat. has_sig ) ,
1130
- relative_timelock : ret_stack
1131
- . iter ( )
1132
- . filter_map ( |sat| sat. relative_timelock )
1133
- . max ( ) ,
1134
- absolute_timelock : ret_stack
1135
- . iter ( )
1136
- . filter_map ( |sat| sat. absolute_timelock )
1137
- . max ( ) ,
1138
- stack : ret_stack
1139
- . into_iter ( )
1140
- . fold ( Witness :: empty ( ) , |acc, next| Witness :: combine ( next. stack , acc) ) ,
1141
- }
1145
+ ret_stack
1146
+ . into_iter ( )
1147
+ . fold ( Satisfaction :: empty ( ) , Satisfaction :: concatenate_rev)
1142
1148
}
1143
1149
1144
1150
fn minimum ( sat1 : Self , sat2 : Self ) -> Self {
@@ -1360,12 +1366,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
1360
1366
Self :: satisfy_helper ( & l. node , stfr, root_has_sig, leaf_hash, min_fn, thresh_fn) ;
1361
1367
let r_sat =
1362
1368
Self :: satisfy_helper ( & r. node , stfr, root_has_sig, leaf_hash, min_fn, thresh_fn) ;
1363
- Satisfaction {
1364
- stack : Witness :: combine ( r_sat. stack , l_sat. stack ) ,
1365
- has_sig : l_sat. has_sig || r_sat. has_sig ,
1366
- relative_timelock : cmp:: max ( l_sat. relative_timelock , r_sat. relative_timelock ) ,
1367
- absolute_timelock : cmp:: max ( l_sat. absolute_timelock , r_sat. absolute_timelock ) ,
1368
- }
1369
+ l_sat. concatenate_rev ( r_sat)
1369
1370
}
1370
1371
Terminal :: AndOr ( ref a, ref b, ref c) => {
1371
1372
let a_sat =
@@ -1383,27 +1384,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
1383
1384
let c_sat =
1384
1385
Self :: satisfy_helper ( & c. node , stfr, root_has_sig, leaf_hash, min_fn, thresh_fn) ;
1385
1386
1386
- min_fn (
1387
- Satisfaction {
1388
- stack : Witness :: combine ( b_sat. stack , a_sat. stack ) ,
1389
- has_sig : a_sat. has_sig || b_sat. has_sig ,
1390
- relative_timelock : cmp:: max (
1391
- a_sat. relative_timelock ,
1392
- b_sat. relative_timelock ,
1393
- ) ,
1394
- absolute_timelock : cmp:: max (
1395
- a_sat. absolute_timelock ,
1396
- b_sat. absolute_timelock ,
1397
- ) ,
1398
- } ,
1399
- Satisfaction {
1400
- stack : Witness :: combine ( c_sat. stack , a_nsat. stack ) ,
1401
- has_sig : a_nsat. has_sig || c_sat. has_sig ,
1402
- // timelocks can't be dissatisfied, so here we ignore a_nsat and only consider c_sat
1403
- relative_timelock : c_sat. relative_timelock ,
1404
- absolute_timelock : c_sat. absolute_timelock ,
1405
- } ,
1406
- )
1387
+ min_fn ( a_sat. concatenate_rev ( b_sat) , a_nsat. concatenate_rev ( c_sat) )
1407
1388
}
1408
1389
Terminal :: OrB ( ref l, ref r) => {
1409
1390
let l_sat =
@@ -1431,18 +1412,8 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
1431
1412
assert ! ( !r_nsat. has_sig) ;
1432
1413
1433
1414
min_fn (
1434
- Satisfaction {
1435
- stack : Witness :: combine ( r_sat. stack , l_nsat. stack ) ,
1436
- has_sig : r_sat. has_sig ,
1437
- relative_timelock : r_sat. relative_timelock ,
1438
- absolute_timelock : r_sat. absolute_timelock ,
1439
- } ,
1440
- Satisfaction {
1441
- stack : Witness :: combine ( r_nsat. stack , l_sat. stack ) ,
1442
- has_sig : l_sat. has_sig ,
1443
- relative_timelock : l_sat. relative_timelock ,
1444
- absolute_timelock : l_sat. absolute_timelock ,
1445
- } ,
1415
+ Satisfaction :: concatenate_rev ( l_nsat, r_sat) ,
1416
+ Satisfaction :: concatenate_rev ( l_sat, r_nsat) ,
1446
1417
)
1447
1418
}
1448
1419
Terminal :: OrD ( ref l, ref r) | Terminal :: OrC ( ref l, ref r) => {
@@ -1461,15 +1432,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
1461
1432
1462
1433
assert ! ( !l_nsat. has_sig) ;
1463
1434
1464
- min_fn (
1465
- l_sat,
1466
- Satisfaction {
1467
- stack : Witness :: combine ( r_sat. stack , l_nsat. stack ) ,
1468
- has_sig : r_sat. has_sig ,
1469
- relative_timelock : r_sat. relative_timelock ,
1470
- absolute_timelock : r_sat. absolute_timelock ,
1471
- } ,
1472
- )
1435
+ min_fn ( l_sat, Satisfaction :: concatenate_rev ( l_nsat, r_sat) )
1473
1436
}
1474
1437
Terminal :: OrI ( ref l, ref r) => {
1475
1438
let l_sat =
@@ -1492,7 +1455,24 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
1492
1455
)
1493
1456
}
1494
1457
Terminal :: Thresh ( ref thresh) => {
1495
- thresh_fn ( thresh, stfr, root_has_sig, leaf_hash, min_fn)
1458
+ if thresh. k ( ) == thresh. n ( ) {
1459
+ // this is just an and
1460
+ thresh
1461
+ . iter ( )
1462
+ . map ( |s| {
1463
+ Self :: satisfy_helper (
1464
+ & s. node ,
1465
+ stfr,
1466
+ root_has_sig,
1467
+ leaf_hash,
1468
+ min_fn,
1469
+ thresh_fn,
1470
+ )
1471
+ } )
1472
+ . fold ( Satisfaction :: empty ( ) , Satisfaction :: concatenate_rev)
1473
+ } else {
1474
+ thresh_fn ( thresh, stfr, root_has_sig, leaf_hash, min_fn)
1475
+ }
1496
1476
}
1497
1477
Terminal :: Multi ( ref thresh) => {
1498
1478
// Collect all available signatures
@@ -1682,12 +1662,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
1682
1662
min_fn,
1683
1663
thresh_fn,
1684
1664
) ;
1685
- Satisfaction {
1686
- stack : Witness :: combine ( odissat. stack , vsat. stack ) ,
1687
- has_sig : vsat. has_sig || odissat. has_sig ,
1688
- relative_timelock : None ,
1689
- absolute_timelock : None ,
1690
- }
1665
+ vsat. concatenate_rev ( odissat)
1691
1666
}
1692
1667
Terminal :: AndB ( ref l, ref r)
1693
1668
| Terminal :: OrB ( ref l, ref r)
@@ -1709,12 +1684,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
1709
1684
min_fn,
1710
1685
thresh_fn,
1711
1686
) ;
1712
- Satisfaction {
1713
- stack : Witness :: combine ( rnsat. stack , lnsat. stack ) ,
1714
- has_sig : rnsat. has_sig || lnsat. has_sig ,
1715
- relative_timelock : None ,
1716
- absolute_timelock : None ,
1717
- }
1687
+ lnsat. concatenate_rev ( rnsat)
1718
1688
}
1719
1689
Terminal :: OrI ( ref l, ref r) => {
1720
1690
let lnsat = Self :: dissatisfy_helper (
@@ -1750,23 +1720,19 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
1750
1720
// Dissatisfactions don't need to non-malleable. Use minimum_mall always
1751
1721
Satisfaction :: minimum_mall ( dissat_1, dissat_2)
1752
1722
}
1753
- Terminal :: Thresh ( ref thresh) => Satisfaction {
1754
- stack : thresh. iter ( ) . fold ( Witness :: empty ( ) , |acc, sub| {
1755
- let nsat = Self :: dissatisfy_helper (
1756
- & sub. node ,
1723
+ Terminal :: Thresh ( ref thresh) => thresh
1724
+ . iter ( )
1725
+ . map ( |s| {
1726
+ Self :: dissatisfy_helper (
1727
+ & s. node ,
1757
1728
stfr,
1758
1729
root_has_sig,
1759
1730
leaf_hash,
1760
1731
min_fn,
1761
1732
thresh_fn,
1762
- ) ;
1763
- assert ! ( !nsat. has_sig) ;
1764
- Witness :: combine ( nsat. stack , acc)
1765
- } ) ,
1766
- has_sig : false ,
1767
- relative_timelock : None ,
1768
- absolute_timelock : None ,
1769
- } ,
1733
+ )
1734
+ } )
1735
+ . fold ( Satisfaction :: empty ( ) , Satisfaction :: concatenate_rev) ,
1770
1736
Terminal :: Multi ( ref thresh) => Satisfaction {
1771
1737
stack : Witness :: Stack ( vec ! [ Placeholder :: PushZero ; thresh. k( ) + 1 ] ) ,
1772
1738
has_sig : false ,
0 commit comments