Skip to content

Commit ea70d8a

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 935aa83 commit ea70d8a

File tree

2 files changed

+11
-50
lines changed

2 files changed

+11
-50
lines changed

src/miniscript/astelem.rs

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ 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,
24+
errstr, expression, script_num_size, AbsLockTime, Error, Miniscript, MiniscriptKey,
2525
Terminal, ToPublicKey, TranslateErr, TranslatePk, Translator,
2626
};
2727

@@ -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: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use bitcoin::taproot::{LeafVersion, TapLeafHash};
2323
use self::analyzable::ExtParams;
2424
pub use self::context::{BareCtx, Legacy, Segwitv0, Tap};
2525
use crate::prelude::*;
26+
use crate::iter::TreeLike;
2627
use crate::TranslateErr;
2728

2829
pub mod analyzable;
@@ -296,7 +297,15 @@ 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) => if !pred(p) { return false },
303+
Terminal::PkH(ref p) => if !pred(p) { return false },
304+
Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => if !keys.iter().all(&mut pred) { return false },
305+
_ => {}
306+
}
307+
}
308+
true
300309
}
301310
}
302311

@@ -319,10 +328,6 @@ where
319328
}
320329

321330
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-
326331
pub(super) fn real_translate_pk<Q, CtxQ, T, FuncError>(
327332
&self,
328333
t: &mut T,

0 commit comments

Comments
 (0)