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