Skip to content

Commit d45efc6

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 220ecb0 commit d45efc6

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

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

0 commit comments

Comments
 (0)