Skip to content

Commit 4749931

Browse files
committed
Use TreeLike to implement check_timelocks_helper
Remove recursive calls and use `TreeLike`'s post order iterator to implement `check_timelocks_helper` for the `concrete::Policy`. Note, no additional unit tests added for this code path, this is a familiar code pattern now.
1 parent 1cbc018 commit 4749931

File tree

1 file changed

+38
-35
lines changed

1 file changed

+38
-35
lines changed

src/policy/concrete.rs

+38-35
Original file line numberDiff line numberDiff line change
@@ -696,42 +696,45 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
696696
// Checks whether the given concrete policy contains a combination of
697697
// timelocks and heightlocks
698698
fn check_timelocks_helper(&self) -> TimelockInfo {
699-
// timelocks[csv_h, csv_t, cltv_h, cltv_t, combination]
700-
match *self {
701-
Policy::Unsatisfiable
702-
| Policy::Trivial
703-
| Policy::Key(_)
704-
| Policy::Sha256(_)
705-
| Policy::Hash256(_)
706-
| Policy::Ripemd160(_)
707-
| Policy::Hash160(_) => TimelockInfo::default(),
708-
Policy::After(t) => TimelockInfo {
709-
csv_with_height: false,
710-
csv_with_time: false,
711-
cltv_with_height: absolute::LockTime::from(t).is_block_height(),
712-
cltv_with_time: absolute::LockTime::from(t).is_block_time(),
713-
contains_combination: false,
714-
},
715-
Policy::Older(t) => TimelockInfo {
716-
csv_with_height: t.is_height_locked(),
717-
csv_with_time: t.is_time_locked(),
718-
cltv_with_height: false,
719-
cltv_with_time: false,
720-
contains_combination: false,
721-
},
722-
Policy::Threshold(k, ref subs) => {
723-
let iter = subs.iter().map(|sub| sub.check_timelocks_helper());
724-
TimelockInfo::combine_threshold(k, iter)
725-
}
726-
Policy::And(ref subs) => {
727-
let iter = subs.iter().map(|sub| sub.check_timelocks_helper());
728-
TimelockInfo::combine_threshold(subs.len(), iter)
729-
}
730-
Policy::Or(ref subs) => {
731-
let iter = subs.iter().map(|(_p, sub)| sub.check_timelocks_helper());
732-
TimelockInfo::combine_threshold(1, iter)
733-
}
699+
use Policy::*;
700+
701+
let mut infos = vec![];
702+
for data in Arc::new(self).post_order_iter() {
703+
let info_for_child_n = |n| infos[data.child_indices[n]];
704+
705+
let info = match data.node {
706+
Policy::After(ref t) => TimelockInfo {
707+
csv_with_height: false,
708+
csv_with_time: false,
709+
cltv_with_height: absolute::LockTime::from(*t).is_block_height(),
710+
cltv_with_time: absolute::LockTime::from(*t).is_block_time(),
711+
contains_combination: false,
712+
},
713+
Policy::Older(ref t) => TimelockInfo {
714+
csv_with_height: t.is_height_locked(),
715+
csv_with_time: t.is_time_locked(),
716+
cltv_with_height: false,
717+
cltv_with_time: false,
718+
contains_combination: false,
719+
},
720+
Threshold(ref k, subs) => {
721+
let iter = (0..subs.len()).map(info_for_child_n);
722+
TimelockInfo::combine_threshold(*k, iter)
723+
}
724+
And(ref subs) => {
725+
let iter = (0..subs.len()).map(info_for_child_n);
726+
TimelockInfo::combine_threshold(subs.len(), iter)
727+
}
728+
Or(ref subs) => {
729+
let iter = (0..subs.len()).map(info_for_child_n);
730+
TimelockInfo::combine_threshold(1, iter)
731+
}
732+
_ => TimelockInfo::default(),
733+
};
734+
infos.push(info);
734735
}
736+
// Ok to unwrap, we had to have visited at least one node.
737+
infos.pop().unwrap()
735738
}
736739

737740
/// This returns whether the given policy is valid or not. It maybe possible that the policy

0 commit comments

Comments
 (0)