Skip to content

Commit 2930938

Browse files
committed
miniscript: eliminate recursion in for_each_key
This is a breaking change because we no longer implement `ForEachKey` on `Terminal`. But IMHO we should never have implemented that trait (or any trait, really..) directly on `Terminal`. The fact that we did was just an implementation detail of how we used to do a lot of iteration.
1 parent 3c0ff73 commit 2930938

File tree

2 files changed

+24
-51
lines changed

2 files changed

+24
-51
lines changed

src/miniscript/astelem.rs

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ use crate::miniscript::ScriptContext;
2121
use crate::prelude::*;
2222
use crate::util::MsKeyBuilder;
2323
use crate::{
24-
errstr, expression, script_num_size, AbsLockTime, Error, ForEachKey, Miniscript, MiniscriptKey,
25-
Terminal, ToPublicKey, TranslateErr, TranslatePk, Translator,
24+
errstr, expression, script_num_size, AbsLockTime, Error, Miniscript, MiniscriptKey, Terminal,
25+
ToPublicKey, TranslateErr, TranslatePk, Translator,
2626
};
2727

2828
impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
@@ -64,44 +64,6 @@ where
6464
}
6565

6666
impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
67-
pub(super) fn real_for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool {
68-
match *self {
69-
Terminal::PkK(ref p) => pred(p),
70-
Terminal::PkH(ref p) => pred(p),
71-
Terminal::RawPkH(..)
72-
| Terminal::After(..)
73-
| Terminal::Older(..)
74-
| Terminal::Sha256(..)
75-
| Terminal::Hash256(..)
76-
| Terminal::Ripemd160(..)
77-
| Terminal::Hash160(..)
78-
| Terminal::True
79-
| Terminal::False => true,
80-
Terminal::Alt(ref sub)
81-
| Terminal::Swap(ref sub)
82-
| Terminal::Check(ref sub)
83-
| Terminal::DupIf(ref sub)
84-
| Terminal::Verify(ref sub)
85-
| Terminal::NonZero(ref sub)
86-
| Terminal::ZeroNotEqual(ref sub) => sub.real_for_each_key(pred),
87-
Terminal::AndV(ref left, ref right)
88-
| Terminal::AndB(ref left, ref right)
89-
| Terminal::OrB(ref left, ref right)
90-
| Terminal::OrD(ref left, ref right)
91-
| Terminal::OrC(ref left, ref right)
92-
| Terminal::OrI(ref left, ref right) => {
93-
left.real_for_each_key(&mut *pred) && right.real_for_each_key(pred)
94-
}
95-
Terminal::AndOr(ref a, ref b, ref c) => {
96-
a.real_for_each_key(&mut *pred)
97-
&& b.real_for_each_key(&mut *pred)
98-
&& c.real_for_each_key(pred)
99-
}
100-
Terminal::Thresh(_, ref subs) => subs.iter().all(|sub| sub.real_for_each_key(pred)),
101-
Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => keys.iter().all(pred),
102-
}
103-
}
104-
10567
pub(super) fn real_translate_pk<Q, CtxQ, T, E>(
10668
&self,
10769
t: &mut T,
@@ -250,12 +212,6 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
250212
}
251213
}
252214

253-
impl<Pk: MiniscriptKey, Ctx: ScriptContext> ForEachKey<Pk> for Terminal<Pk, Ctx> {
254-
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
255-
self.real_for_each_key(&mut pred)
256-
}
257-
}
258-
259215
impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Debug for Terminal<Pk, Ctx> {
260216
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
261217
f.write_str("[")?;

src/miniscript/mod.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use bitcoin::taproot::{LeafVersion, TapLeafHash};
2222

2323
use self::analyzable::ExtParams;
2424
pub use self::context::{BareCtx, Legacy, Segwitv0, Tap};
25+
use crate::iter::TreeLike;
2526
use crate::prelude::*;
2627
use crate::TranslateErr;
2728

@@ -296,7 +297,27 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
296297

297298
impl<Pk: MiniscriptKey, Ctx: ScriptContext> ForEachKey<Pk> for Miniscript<Pk, Ctx> {
298299
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
299-
self.real_for_each_key(&mut pred)
300+
for ms in self.pre_order_iter() {
301+
match ms.node {
302+
Terminal::PkK(ref p) => {
303+
if !pred(p) {
304+
return false;
305+
}
306+
}
307+
Terminal::PkH(ref p) => {
308+
if !pred(p) {
309+
return false;
310+
}
311+
}
312+
Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => {
313+
if !keys.iter().all(&mut pred) {
314+
return false;
315+
}
316+
}
317+
_ => {}
318+
}
319+
}
320+
true
300321
}
301322
}
302323

@@ -319,10 +340,6 @@ where
319340
}
320341

321342
impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
322-
fn real_for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool {
323-
self.node.real_for_each_key(pred)
324-
}
325-
326343
pub(super) fn real_translate_pk<Q, CtxQ, T, FuncError>(
327344
&self,
328345
t: &mut T,

0 commit comments

Comments
 (0)