Skip to content

Commit 19ee6fe

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 6f881d8 commit 19ee6fe

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
@@ -711,42 +711,45 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
711711
// Checks whether the given concrete policy contains a combination of
712712
// timelocks and heightlocks
713713
fn check_timelocks_helper(&self) -> TimelockInfo {
714-
// timelocks[csv_h, csv_t, cltv_h, cltv_t, combination]
715-
match *self {
716-
Policy::Unsatisfiable
717-
| Policy::Trivial
718-
| Policy::Key(_)
719-
| Policy::Sha256(_)
720-
| Policy::Hash256(_)
721-
| Policy::Ripemd160(_)
722-
| Policy::Hash160(_) => TimelockInfo::default(),
723-
Policy::After(t) => TimelockInfo {
724-
csv_with_height: false,
725-
csv_with_time: false,
726-
cltv_with_height: absolute::LockTime::from(t).is_block_height(),
727-
cltv_with_time: absolute::LockTime::from(t).is_block_time(),
728-
contains_combination: false,
729-
},
730-
Policy::Older(t) => TimelockInfo {
731-
csv_with_height: t.is_height_locked(),
732-
csv_with_time: t.is_time_locked(),
733-
cltv_with_height: false,
734-
cltv_with_time: false,
735-
contains_combination: false,
736-
},
737-
Policy::Threshold(k, ref subs) => {
738-
let iter = subs.iter().map(|sub| sub.check_timelocks_helper());
739-
TimelockInfo::combine_threshold(k, iter)
740-
}
741-
Policy::And(ref subs) => {
742-
let iter = subs.iter().map(|sub| sub.check_timelocks_helper());
743-
TimelockInfo::combine_threshold(subs.len(), iter)
744-
}
745-
Policy::Or(ref subs) => {
746-
let iter = subs.iter().map(|(_p, sub)| sub.check_timelocks_helper());
747-
TimelockInfo::combine_threshold(1, iter)
748-
}
714+
use Policy::*;
715+
716+
let mut infos = vec![];
717+
for data in Arc::new(self).post_order_iter() {
718+
let info_for_child_n = |n| infos[data.child_indices[n]];
719+
720+
let info = match data.node {
721+
Policy::After(ref t) => TimelockInfo {
722+
csv_with_height: false,
723+
csv_with_time: false,
724+
cltv_with_height: absolute::LockTime::from(*t).is_block_height(),
725+
cltv_with_time: absolute::LockTime::from(*t).is_block_time(),
726+
contains_combination: false,
727+
},
728+
Policy::Older(ref t) => TimelockInfo {
729+
csv_with_height: t.is_height_locked(),
730+
csv_with_time: t.is_time_locked(),
731+
cltv_with_height: false,
732+
cltv_with_time: false,
733+
contains_combination: false,
734+
},
735+
Threshold(ref k, subs) => {
736+
let iter = (0..subs.len()).map(info_for_child_n);
737+
TimelockInfo::combine_threshold(*k, iter)
738+
}
739+
And(ref subs) => {
740+
let iter = (0..subs.len()).map(info_for_child_n);
741+
TimelockInfo::combine_threshold(subs.len(), iter)
742+
}
743+
Or(ref subs) => {
744+
let iter = (0..subs.len()).map(info_for_child_n);
745+
TimelockInfo::combine_threshold(1, iter)
746+
}
747+
_ => TimelockInfo::default(),
748+
};
749+
infos.push(info);
749750
}
751+
// Ok to unwrap, we had to have visited at least one node.
752+
infos.pop().unwrap()
750753
}
751754

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

0 commit comments

Comments
 (0)