@@ -1408,6 +1408,39 @@ mod tests {
14081408 ms. translate_pk ( & mut t) . unwrap_err ( ) ;
14091409 }
14101410
1411+ #[ test]
1412+ fn mixed_timelocks ( ) {
1413+ // You cannot parse a Miniscript that mixes timelocks.
1414+ let err = Miniscript :: < String , Segwitv0 > :: from_str (
1415+ "and_v(v:and_v(v:older(4194304),pk(A)),and_v(v:older(1),pk(B)))" ,
1416+ )
1417+ . unwrap_err ( ) ;
1418+ assert_eq ! ( err, Error :: AnalysisError ( crate :: AnalysisError :: HeightTimelockCombination ) ) ;
1419+
1420+ // Though you can in an or() rather than and()
1421+ let ok_or = Miniscript :: < String , Segwitv0 > :: from_str (
1422+ "or_i(and_v(v:older(4194304),pk(A)),and_v(v:older(1),pk(B)))" ,
1423+ )
1424+ . unwrap ( ) ;
1425+ ok_or. sanity_check ( ) . unwrap ( ) ;
1426+ ok_or. lift ( ) . unwrap ( ) ;
1427+
1428+ // ...and you can parse one with from_str_insane
1429+ let ok_insane = Miniscript :: < String , Segwitv0 > :: from_str_insane (
1430+ "and_v(v:and_v(v:older(4194304),pk(A)),and_v(v:older(1),pk(B)))" ,
1431+ )
1432+ . unwrap ( ) ;
1433+ // ...but this cannot be sanity checked or lifted
1434+ assert_eq ! (
1435+ ok_insane. sanity_check( ) . unwrap_err( ) ,
1436+ crate :: AnalysisError :: HeightTimelockCombination
1437+ ) ;
1438+ assert_eq ! (
1439+ ok_insane. lift( ) . unwrap_err( ) ,
1440+ Error :: LiftError ( crate :: policy:: LiftError :: HeightTimelockCombination )
1441+ ) ;
1442+ }
1443+
14111444 #[ test]
14121445 fn template_timelocks ( ) {
14131446 use crate :: { AbsLockTime , RelLockTime } ;
0 commit comments