Skip to content

Commit 807c60f

Browse files
committed
semantic: Remove recursion in minimum_n_keys
Done as part of the effort to remove all the recursion crate wide. Use the `TreeLike` trait to iterate over policy nodes and remove the recursive call in `semantic::Policy::minimum_n_keys`.
1 parent 2dfe144 commit 807c60f

File tree

1 file changed

+26
-20
lines changed

1 file changed

+26
-20
lines changed

src/policy/semantic.rs

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -618,28 +618,34 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
618618
///
619619
/// Returns `None` if the policy is not satisfiable.
620620
pub fn minimum_n_keys(&self) -> Option<usize> {
621-
match *self {
622-
Policy::Unsatisfiable => None,
623-
Policy::Trivial => Some(0),
624-
Policy::Key(..) => Some(1),
625-
Policy::After(..)
626-
| Policy::Older(..)
627-
| Policy::Sha256(..)
628-
| Policy::Hash256(..)
629-
| Policy::Ripemd160(..)
630-
| Policy::Hash160(..) => Some(0),
631-
Policy::Threshold(k, ref subs) => {
632-
let mut sublens: Vec<usize> =
633-
subs.iter().filter_map(|p| p.minimum_n_keys()).collect();
634-
if sublens.len() < k {
635-
// Not enough branches are satisfiable
636-
None
637-
} else {
638-
sublens.sort_unstable();
639-
Some(sublens[0..k].iter().cloned().sum::<usize>())
621+
use Policy::*;
622+
623+
let mut minimum_n_keys = vec![];
624+
for data in Arc::new(self).post_order_iter() {
625+
let minimum_n_keys_for_child_n = |n| minimum_n_keys[data.child_indices[n]];
626+
627+
let minimum_n_key = match data.node {
628+
Unsatisfiable => None,
629+
Trivial | After(..) | Older(..) | Sha256(..) | Hash256(..) | Ripemd160(..)
630+
| Hash160(..) => Some(0),
631+
Key(..) => Some(1),
632+
Threshold(k, ref subs) => {
633+
let mut sublens = (0..subs.len())
634+
.filter_map(minimum_n_keys_for_child_n)
635+
.collect::<Vec<usize>>();
636+
if sublens.len() < *k {
637+
// Not enough branches are satisfiable
638+
None
639+
} else {
640+
sublens.sort_unstable();
641+
Some(sublens[0..*k].iter().cloned().sum::<usize>())
642+
}
640643
}
641-
}
644+
};
645+
minimum_n_keys.push(minimum_n_key);
642646
}
647+
// Ok to unwrap because we know we processed at least one node.
648+
minimum_n_keys.pop().unwrap()
643649
}
644650
}
645651

0 commit comments

Comments
 (0)