@@ -499,6 +499,34 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
499
499
ret
500
500
}
501
501
502
+ /// Helper function for recursion in `absolute timelocks`
503
+ fn real_absolute_timelocks ( & self ) -> Vec < u32 > {
504
+ match * self {
505
+ Policy :: Unsatisfiable
506
+ | Policy :: Trivial
507
+ | Policy :: KeyHash ( ..)
508
+ | Policy :: Sha256 ( ..)
509
+ | Policy :: Hash256 ( ..)
510
+ | Policy :: Ripemd160 ( ..)
511
+ | Policy :: Hash160 ( ..) => vec ! [ ] ,
512
+ Policy :: Older ( ..) => vec ! [ ] ,
513
+ Policy :: After ( t) => vec ! [ t] ,
514
+ Policy :: Threshold ( _, ref subs) => subs. iter ( ) . fold ( vec ! [ ] , |mut acc, x| {
515
+ acc. extend ( x. real_absolute_timelocks ( ) ) ;
516
+ acc
517
+ } ) ,
518
+ }
519
+ }
520
+
521
+ /// Returns a list of all absolute timelocks, not including 0,
522
+ /// which appear in the policy
523
+ pub fn absolute_timelocks ( & self ) -> Vec < u32 > {
524
+ let mut ret = self . real_absolute_timelocks ( ) ;
525
+ ret. sort ( ) ;
526
+ ret. dedup ( ) ;
527
+ ret
528
+ }
529
+
502
530
/// Filter a policy by eliminating relative timelock constraints
503
531
/// that are not satisfied at the given age.
504
532
pub fn at_age ( mut self , time : u32 ) -> Policy < Pk > {
@@ -518,6 +546,25 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
518
546
self . normalized ( )
519
547
}
520
548
549
+ /// Filter a policy by eliminating absolute timelock constraints
550
+ /// that are not satisfied at the given age.
551
+ pub fn at_height ( mut self , time : u32 ) -> Policy < Pk > {
552
+ self = match self {
553
+ Policy :: After ( t) => {
554
+ if t > time {
555
+ Policy :: Unsatisfiable
556
+ } else {
557
+ Policy :: After ( t)
558
+ }
559
+ }
560
+ Policy :: Threshold ( k, subs) => {
561
+ Policy :: Threshold ( k, subs. into_iter ( ) . map ( |sub| sub. at_height ( time) ) . collect ( ) )
562
+ }
563
+ x => x,
564
+ } ;
565
+ self . normalized ( )
566
+ }
567
+
521
568
/// Count the number of public keys and keyhashes referenced in a policy.
522
569
/// Duplicate keys will be double-counted.
523
570
pub fn n_keys ( & self ) -> usize {
@@ -604,13 +651,15 @@ mod tests {
604
651
let policy = StringPolicy :: from_str ( "pkh()" ) . unwrap ( ) ;
605
652
assert_eq ! ( policy, Policy :: KeyHash ( "" . to_owned( ) ) ) ;
606
653
assert_eq ! ( policy. relative_timelocks( ) , vec![ ] ) ;
654
+ assert_eq ! ( policy. absolute_timelocks( ) , vec![ ] ) ;
607
655
assert_eq ! ( policy. clone( ) . at_age( 0 ) , policy. clone( ) ) ;
608
656
assert_eq ! ( policy. clone( ) . at_age( 10000 ) , policy. clone( ) ) ;
609
657
assert_eq ! ( policy. n_keys( ) , 1 ) ;
610
658
assert_eq ! ( policy. minimum_n_keys( ) , 1 ) ;
611
659
612
660
let policy = StringPolicy :: from_str ( "older(1000)" ) . unwrap ( ) ;
613
661
assert_eq ! ( policy, Policy :: Older ( 1000 ) ) ;
662
+ assert_eq ! ( policy. absolute_timelocks( ) , vec![ ] ) ;
614
663
assert_eq ! ( policy. relative_timelocks( ) , vec![ 1000 ] ) ;
615
664
assert_eq ! ( policy. clone( ) . at_age( 0 ) , Policy :: Unsatisfiable ) ;
616
665
assert_eq ! ( policy. clone( ) . at_age( 999 ) , Policy :: Unsatisfiable ) ;
@@ -628,6 +677,7 @@ mod tests {
628
677
)
629
678
) ;
630
679
assert_eq ! ( policy. relative_timelocks( ) , vec![ 1000 ] ) ;
680
+ assert_eq ! ( policy. absolute_timelocks( ) , vec![ ] ) ;
631
681
assert_eq ! ( policy. clone( ) . at_age( 0 ) , Policy :: KeyHash ( "" . to_owned( ) ) ) ;
632
682
assert_eq ! ( policy. clone( ) . at_age( 999 ) , Policy :: KeyHash ( "" . to_owned( ) ) ) ;
633
683
assert_eq ! ( policy. clone( ) . at_age( 1000 ) , policy. clone( ) . normalized( ) ) ;
@@ -658,6 +708,17 @@ mod tests {
658
708
policy. relative_timelocks( ) ,
659
709
vec![ 1000 , 2000 , 10000 ] //sorted and dedup'd
660
710
) ;
711
+
712
+ let policy = StringPolicy :: from_str ( "after(1000)" ) . unwrap ( ) ;
713
+ assert_eq ! ( policy, Policy :: After ( 1000 ) ) ;
714
+ assert_eq ! ( policy. absolute_timelocks( ) , vec![ 1000 ] ) ;
715
+ assert_eq ! ( policy. relative_timelocks( ) , vec![ ] ) ;
716
+ assert_eq ! ( policy. clone( ) . at_height( 0 ) , Policy :: Unsatisfiable ) ;
717
+ assert_eq ! ( policy. clone( ) . at_height( 999 ) , Policy :: Unsatisfiable ) ;
718
+ assert_eq ! ( policy. clone( ) . at_height( 1000 ) , policy. clone( ) ) ;
719
+ assert_eq ! ( policy. clone( ) . at_height( 10000 ) , policy. clone( ) ) ;
720
+ assert_eq ! ( policy. n_keys( ) , 0 ) ;
721
+ assert_eq ! ( policy. minimum_n_keys( ) , 0 ) ;
661
722
}
662
723
663
724
#[ test]
0 commit comments