Skip to content

Commit 211abad

Browse files
committed
semantic: Remove recursion in translate_pk
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::translate_pk`.
1 parent 97ba4e9 commit 211abad

File tree

1 file changed

+23
-16
lines changed

1 file changed

+23
-16
lines changed

src/policy/semantic.rs

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -120,23 +120,30 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
120120
T: Translator<Pk, Q, E>,
121121
Q: MiniscriptKey,
122122
{
123-
match *self {
124-
Policy::Unsatisfiable => Ok(Policy::Unsatisfiable),
125-
Policy::Trivial => Ok(Policy::Trivial),
126-
Policy::Key(ref pk) => t.pk(pk).map(Policy::Key),
127-
Policy::Sha256(ref h) => t.sha256(h).map(Policy::Sha256),
128-
Policy::Hash256(ref h) => t.hash256(h).map(Policy::Hash256),
129-
Policy::Ripemd160(ref h) => t.ripemd160(h).map(Policy::Ripemd160),
130-
Policy::Hash160(ref h) => t.hash160(h).map(Policy::Hash160),
131-
Policy::After(n) => Ok(Policy::After(n)),
132-
Policy::Older(n) => Ok(Policy::Older(n)),
133-
Policy::Threshold(k, ref subs) => {
134-
let new_subs: Result<Vec<Policy<Q>>, _> =
135-
subs.iter().map(|sub| sub.translate_pk(t)).collect();
136-
let new_subs = new_subs?.into_iter().map(Arc::new).collect();
137-
Ok(Policy::Threshold(k, new_subs))
138-
}
123+
use Policy::*;
124+
125+
let mut translated = vec![];
126+
for data in self.post_order_iter() {
127+
let child_n = |n| Arc::clone(&translated[data.child_indices[n]]);
128+
129+
let new_policy = match data.node {
130+
Unsatisfiable => Unsatisfiable,
131+
Trivial => Trivial,
132+
Key(ref pk) => t.pk(pk).map(Key)?,
133+
Sha256(ref h) => t.sha256(h).map(Sha256)?,
134+
Hash256(ref h) => t.hash256(h).map(Hash256)?,
135+
Ripemd160(ref h) => t.ripemd160(h).map(Ripemd160)?,
136+
Hash160(ref h) => t.hash160(h).map(Hash160)?,
137+
Older(ref n) => Older(*n),
138+
After(ref n) => After(*n),
139+
Threshold(ref k, ref subs) => Threshold(*k, (0..subs.len()).map(child_n).collect()),
140+
};
141+
translated.push(Arc::new(new_policy));
139142
}
143+
// Unwrap is ok because we know we processed at least one node.
144+
let root_node = translated.pop().unwrap();
145+
// Unwrap is ok because we know `root_node` is the only strong reference.
146+
Ok(Arc::try_unwrap(root_node).unwrap())
140147
}
141148

142149
/// Computes whether the current policy entails the second one.

0 commit comments

Comments
 (0)