@@ -526,57 +526,80 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
526
526
527
527
/// Filters a policy by eliminating relative timelock constraints
528
528
/// that are not satisfied at the given `age`.
529
- pub fn at_age ( mut self , age : Sequence ) -> Policy < Pk > {
530
- self = match self {
531
- Policy :: Older ( t) => {
532
- if t. is_height_locked ( ) && age. is_time_locked ( )
533
- || t. is_time_locked ( ) && age. is_height_locked ( )
534
- || t. to_consensus_u32 ( ) > age. to_consensus_u32 ( )
535
- {
536
- Policy :: Unsatisfiable
537
- } else {
538
- Policy :: Older ( t)
529
+ pub fn at_age ( self , age : Sequence ) -> Policy < Pk > {
530
+ use Policy :: * ;
531
+
532
+ let mut at_age = vec ! [ ] ;
533
+ for data in Arc :: new ( self ) . post_order_iter ( ) {
534
+ let child_n = |n| Arc :: clone ( & at_age[ data. child_indices [ n] ] ) ;
535
+
536
+ let new_policy = match data. node . as_ref ( ) {
537
+ Older ( ref t) => {
538
+ if t. is_height_locked ( ) && age. is_time_locked ( )
539
+ || t. is_time_locked ( ) && age. is_height_locked ( )
540
+ || t. to_consensus_u32 ( ) > age. to_consensus_u32 ( )
541
+ {
542
+ Some ( Policy :: Unsatisfiable )
543
+ } else {
544
+ Some ( Policy :: Older ( * t) )
545
+ }
546
+ }
547
+ Threshold ( k, ref subs) => {
548
+ Some ( Threshold ( * k, ( 0 ..subs. len ( ) ) . map ( child_n) . collect ( ) ) )
539
549
}
550
+ _ => None ,
551
+ } ;
552
+ match new_policy {
553
+ Some ( new_policy) => at_age. push ( Arc :: new ( new_policy) ) ,
554
+ None => at_age. push ( Arc :: clone ( & data. node ) ) ,
540
555
}
541
- Policy :: Threshold ( k, subs) => Policy :: Threshold (
542
- k,
543
- subs. into_iter ( )
544
- . map ( |sub| Arc :: new ( sub. as_ref ( ) . clone ( ) . at_age ( age) ) )
545
- . collect ( ) ,
546
- ) ,
547
- x => x,
548
- } ;
549
- self . normalized ( )
556
+ }
557
+ // Unwrap is ok because we know we processed at least one node.
558
+ let root_node = at_age. pop ( ) . unwrap ( ) ;
559
+ // Unwrap is ok because we know `root_node` is the only strong reference.
560
+ let policy = Arc :: try_unwrap ( root_node) . unwrap ( ) ;
561
+ policy. normalized ( )
550
562
}
551
563
552
564
/// Filters a policy by eliminating absolute timelock constraints
553
565
/// that are not satisfied at the given `n` (`n OP_CHECKLOCKTIMEVERIFY`).
554
- pub fn at_lock_time ( mut self , n : absolute:: LockTime ) -> Policy < Pk > {
566
+ pub fn at_lock_time ( self , n : absolute:: LockTime ) -> Policy < Pk > {
555
567
use absolute:: LockTime :: * ;
568
+ use Policy :: * ;
556
569
557
- self = match self {
558
- Policy :: After ( t) => {
559
- let t = absolute:: LockTime :: from ( t) ;
560
- let is_satisfied_by = match ( t, n) {
561
- ( Blocks ( t) , Blocks ( n) ) => t <= n,
562
- ( Seconds ( t) , Seconds ( n) ) => t <= n,
563
- _ => false ,
564
- } ;
565
- if !is_satisfied_by {
566
- Policy :: Unsatisfiable
567
- } else {
568
- Policy :: After ( t. into ( ) )
570
+ let mut at_age = vec ! [ ] ;
571
+ for data in Arc :: new ( self ) . post_order_iter ( ) {
572
+ let child_n = |n| Arc :: clone ( & at_age[ data. child_indices [ n] ] ) ;
573
+
574
+ let new_policy = match data. node . as_ref ( ) {
575
+ After ( t) => {
576
+ let t = absolute:: LockTime :: from ( * t) ;
577
+ let is_satisfied_by = match ( t, n) {
578
+ ( Blocks ( t) , Blocks ( n) ) => t <= n,
579
+ ( Seconds ( t) , Seconds ( n) ) => t <= n,
580
+ _ => false ,
581
+ } ;
582
+ if !is_satisfied_by {
583
+ Some ( Unsatisfiable )
584
+ } else {
585
+ Some ( After ( t. into ( ) ) )
586
+ }
587
+ }
588
+ Threshold ( k, ref subs) => {
589
+ Some ( Threshold ( * k, ( 0 ..subs. len ( ) ) . map ( child_n) . collect ( ) ) )
569
590
}
591
+ _ => None ,
592
+ } ;
593
+ match new_policy {
594
+ Some ( new_policy) => at_age. push ( Arc :: new ( new_policy) ) ,
595
+ None => at_age. push ( Arc :: clone ( & data. node ) ) ,
570
596
}
571
- Policy :: Threshold ( k, subs) => Policy :: Threshold (
572
- k,
573
- subs. into_iter ( )
574
- . map ( |sub| Arc :: new ( sub. as_ref ( ) . clone ( ) . at_lock_time ( n) ) )
575
- . collect ( ) ,
576
- ) ,
577
- x => x,
578
- } ;
579
- self . normalized ( )
597
+ }
598
+ // Unwrap is ok because we know we processed at least one node.
599
+ let root_node = at_age. pop ( ) . unwrap ( ) ;
600
+ // Unwrap is ok because we know `root_node` is the only strong reference.
601
+ let policy = Arc :: try_unwrap ( root_node) . unwrap ( ) ;
602
+ policy. normalized ( )
580
603
}
581
604
582
605
/// Counts the number of public keys and keyhashes referenced in a policy.
0 commit comments