Skip to content

Commit 09a47cb

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 eb75602 commit 09a47cb

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
@@ -611,28 +611,34 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
611611
///
612612
/// Returns `None` if the policy is not satisfiable.
613613
pub fn minimum_n_keys(&self) -> Option<usize> {
614-
match *self {
615-
Policy::Unsatisfiable => None,
616-
Policy::Trivial => Some(0),
617-
Policy::Key(..) => Some(1),
618-
Policy::After(..)
619-
| Policy::Older(..)
620-
| Policy::Sha256(..)
621-
| Policy::Hash256(..)
622-
| Policy::Ripemd160(..)
623-
| Policy::Hash160(..) => Some(0),
624-
Policy::Threshold(k, ref subs) => {
625-
let mut sublens: Vec<usize> =
626-
subs.iter().filter_map(|p| p.minimum_n_keys()).collect();
627-
if sublens.len() < k {
628-
// Not enough branches are satisfiable
629-
None
630-
} else {
631-
sublens.sort_unstable();
632-
Some(sublens[0..k].iter().cloned().sum::<usize>())
614+
use Policy::*;
615+
616+
let mut minimum_n_keys = vec![];
617+
for data in Arc::new(self).post_order_iter() {
618+
let minimum_n_keys_for_child_n = |n| minimum_n_keys[data.child_indices[n]];
619+
620+
let minimum_n_key = match data.node {
621+
Unsatisfiable => None,
622+
Trivial | After(..) | Older(..) | Sha256(..) | Hash256(..) | Ripemd160(..)
623+
| Hash160(..) => Some(0),
624+
Key(..) => Some(1),
625+
Threshold(k, ref subs) => {
626+
let mut sublens = (0..subs.len())
627+
.filter_map(minimum_n_keys_for_child_n)
628+
.collect::<Vec<usize>>();
629+
if sublens.len() < *k {
630+
// Not enough branches are satisfiable
631+
None
632+
} else {
633+
sublens.sort_unstable();
634+
Some(sublens[0..*k].iter().cloned().sum::<usize>())
635+
}
633636
}
634-
}
637+
};
638+
minimum_n_keys.push(minimum_n_key);
635639
}
640+
// Ok to unwrap because we know we processed at least one node.
641+
minimum_n_keys.pop().unwrap()
636642
}
637643
}
638644

0 commit comments

Comments
 (0)