1use std::ops::Deref;
9use std::sync::Arc;
10
11use super::decode::Terminal;
12use super::{Miniscript, MiniscriptKey, ScriptContext};
13use crate::Extension;
14
15impl<Pk: MiniscriptKey, Ctx: ScriptContext, Ext: Extension> Miniscript<Pk, Ctx, Ext> {
17 pub fn iter(&self) -> Iter<'_, Pk, Ctx, Ext> {
21 Iter::new(self)
22 }
23
24 pub fn iter_pk(&self) -> PkIter<'_, Pk, Ctx, Ext> {
28 PkIter::new(self)
29 }
30
31 pub fn branches(&self) -> Vec<&Miniscript<Pk, Ctx, Ext>> {
34 match self.node {
35 Terminal::PkK(_) | Terminal::PkH(_) | Terminal::RawPkH(_) | Terminal::Multi(_, _) => {
36 vec![]
37 }
38
39 Terminal::Alt(ref node)
40 | Terminal::Swap(ref node)
41 | Terminal::Check(ref node)
42 | Terminal::DupIf(ref node)
43 | Terminal::Verify(ref node)
44 | Terminal::NonZero(ref node)
45 | Terminal::ZeroNotEqual(ref node) => vec![node],
46
47 Terminal::AndV(ref node1, ref node2)
48 | Terminal::AndB(ref node1, ref node2)
49 | Terminal::OrB(ref node1, ref node2)
50 | Terminal::OrD(ref node1, ref node2)
51 | Terminal::OrC(ref node1, ref node2)
52 | Terminal::OrI(ref node1, ref node2) => vec![node1, node2],
53
54 Terminal::AndOr(ref node1, ref node2, ref node3) => vec![node1, node2, node3],
55
56 Terminal::Thresh(_, ref node_vec) => node_vec.iter().map(Arc::deref).collect(),
57
58 _ => vec![],
59 }
60 }
61
62 pub fn get_nth_child(&self, n: usize) -> Option<&Miniscript<Pk, Ctx, Ext>> {
64 match (n, &self.node) {
65 (0, Terminal::Alt(node))
66 | (0, Terminal::Swap(node))
67 | (0, Terminal::Check(node))
68 | (0, Terminal::DupIf(node))
69 | (0, Terminal::Verify(node))
70 | (0, Terminal::NonZero(node))
71 | (0, Terminal::ZeroNotEqual(node))
72 | (0, Terminal::AndV(node, _))
73 | (0, Terminal::AndB(node, _))
74 | (0, Terminal::OrB(node, _))
75 | (0, Terminal::OrD(node, _))
76 | (0, Terminal::OrC(node, _))
77 | (0, Terminal::OrI(node, _))
78 | (1, Terminal::AndV(_, node))
79 | (1, Terminal::AndB(_, node))
80 | (1, Terminal::OrB(_, node))
81 | (1, Terminal::OrD(_, node))
82 | (1, Terminal::OrC(_, node))
83 | (1, Terminal::OrI(_, node))
84 | (0, Terminal::AndOr(node, _, _))
85 | (1, Terminal::AndOr(_, node, _))
86 | (2, Terminal::AndOr(_, _, node)) => Some(node),
87
88 (n, Terminal::Thresh(_, node_vec)) => node_vec.get(n).map(|x| &**x),
89
90 _ => None,
91 }
92 }
93
94 pub fn get_nth_pk(&self, n: usize) -> Option<Pk> {
99 match (&self.node, n) {
100 (&Terminal::PkK(ref key), 0) | (&Terminal::PkH(ref key), 0) => Some(key.clone()),
101 (&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => {
102 keys.get(n).cloned()
103 }
104 _ => None,
105 }
106 }
107}
108
109pub struct Iter<'a, Pk: MiniscriptKey, Ctx: ScriptContext, Ext: Extension> {
112 next: Option<&'a Miniscript<Pk, Ctx, Ext>>,
113 path: Vec<(&'a Miniscript<Pk, Ctx, Ext>, usize)>,
117}
118
119impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext, Ext: Extension> Iter<'a, Pk, Ctx, Ext> {
120 fn new(miniscript: &'a Miniscript<Pk, Ctx, Ext>) -> Self {
121 Iter {
122 next: Some(miniscript),
123 path: vec![],
124 }
125 }
126}
127
128impl<'a, Pk: MiniscriptKey, Ctx: 'a + ScriptContext, Ext: 'a + Extension> Iterator
129 for Iter<'a, Pk, Ctx, Ext>
130{
131 type Item = &'a Miniscript<Pk, Ctx, Ext>;
132
133 fn next(&mut self) -> Option<Self::Item> {
155 let mut curr = self.next;
156 if curr.is_none() {
157 while let Some((node, child)) = self.path.pop() {
158 curr = node.get_nth_child(child);
159 if curr.is_some() {
160 self.path.push((node, child + 1));
161 break;
162 }
163 }
164 }
165 if let Some(node) = curr {
166 self.next = node.get_nth_child(0);
167 self.path.push((node, 1));
168 }
169 curr
170 }
171}
172
173pub struct PkIter<'a, Pk: MiniscriptKey, Ctx: ScriptContext, Ext: Extension> {
176 node_iter: Iter<'a, Pk, Ctx, Ext>,
177 curr_node: Option<&'a Miniscript<Pk, Ctx, Ext>>,
178 key_index: usize,
179}
180
181impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext, Ext: Extension> PkIter<'a, Pk, Ctx, Ext> {
182 fn new(miniscript: &'a Miniscript<Pk, Ctx, Ext>) -> Self {
183 let mut iter = Iter::new(miniscript);
184 PkIter {
185 curr_node: iter.next(),
186 node_iter: iter,
187 key_index: 0,
188 }
189 }
190}
191
192impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext, Ext: Extension> Iterator
193 for PkIter<'a, Pk, Ctx, Ext>
194{
195 type Item = Pk;
196
197 fn next(&mut self) -> Option<Self::Item> {
198 loop {
199 match self.curr_node {
200 None => break None,
201 Some(node) => match node.get_nth_pk(self.key_index) {
202 None => {
203 self.curr_node = self.node_iter.next();
204 self.key_index = 0;
205 continue;
206 }
207 Some(pk) => {
208 self.key_index += 1;
209 break Some(pk);
210 }
211 },
212 }
213 }
214 }
215}
216
217#[cfg(test)]
220pub mod test {
221 use bitcoin;
222 use elements::hashes::{hash160, ripemd160, sha256, sha256d, Hash};
223 use elements::secp256k1_zkp;
224
225 use super::Miniscript;
226 use crate::miniscript::context::Segwitv0;
227 use crate::NoExt;
228
229 pub type TestData = (
230 Miniscript<bitcoin::PublicKey, Segwitv0, NoExt>,
231 Vec<bitcoin::PublicKey>,
232 Vec<hash160::Hash>,
233 bool, );
235
236 pub fn gen_secp_pubkeys(n: usize) -> Vec<secp256k1_zkp::PublicKey> {
237 let mut ret = Vec::with_capacity(n);
238 let secp = secp256k1_zkp::Secp256k1::new();
239 let mut sk = [0; 32];
240
241 for i in 1..n + 1 {
242 sk[0] = i as u8;
243 sk[1] = (i >> 8) as u8;
244 sk[2] = (i >> 16) as u8;
245
246 ret.push(secp256k1_zkp::PublicKey::from_secret_key(
247 &secp,
248 &secp256k1_zkp::SecretKey::from_slice(&sk[..]).unwrap(),
249 ));
250 }
251 ret
252 }
253
254 pub fn gen_bitcoin_pubkeys(n: usize, compressed: bool) -> Vec<bitcoin::PublicKey> {
255 gen_secp_pubkeys(n)
256 .into_iter()
257 .map(|inner| bitcoin::PublicKey { inner, compressed })
258 .collect()
259 }
260
261 pub fn gen_testcases() -> Vec<TestData> {
262 let k = gen_bitcoin_pubkeys(10, true);
263 let _h: Vec<hash160::Hash> = k
264 .iter()
265 .map(|pk| hash160::Hash::hash(&pk.to_bytes()))
266 .collect();
267
268 let preimage = vec![0xab; 32];
269 let sha256_hash = sha256::Hash::hash(&preimage);
270 let sha256d_hash_rev = sha256d::Hash::hash(&preimage);
271 let mut sha256d_hash_bytes = sha256d_hash_rev.to_byte_array();
272 sha256d_hash_bytes.reverse();
273 let sha256d_hash = sha256d::Hash::from_byte_array(sha256d_hash_bytes);
274 let hash160_hash = hash160::Hash::hash(&preimage);
275 let ripemd160_hash = ripemd160::Hash::hash(&preimage);
276
277 vec![
278 (ms_str!("after({})", 1000), vec![], vec![], false),
279 (ms_str!("older({})", 1000), vec![], vec![], false),
280 (ms_str!("sha256({})", sha256_hash), vec![], vec![], false),
281 (ms_str!("hash256({})", sha256d_hash), vec![], vec![], false),
282 (ms_str!("hash160({})", hash160_hash), vec![], vec![], false),
283 (
284 ms_str!("ripemd160({})", ripemd160_hash),
285 vec![],
286 vec![],
287 false,
288 ),
289 (ms_str!("c:pk_k({})", k[0]), vec![k[0]], vec![], true),
290 (ms_str!("c:pk_h({})", k[0]), vec![k[0]], vec![], true),
291 (
292 ms_str!("and_v(vc:pk_k({}),c:pk_h({}))", k[0], k[1]),
293 vec![k[0], k[1]],
294 vec![],
295 false,
296 ),
297 (
298 ms_str!("and_b(c:pk_k({}),sjtv:sha256({}))", k[0], sha256_hash),
299 vec![k[0]],
300 vec![],
301 false,
302 ),
303 (
304 ms_str!(
305 "andor(c:pk_k({}),jtv:sha256({}),c:pk_h({}))",
306 k[1],
307 sha256_hash,
308 k[2]
309 ),
310 vec![k[1], k[2]],
311 vec![],
312 false,
313 ),
314 (
315 ms_str!("multi(3,{},{},{},{},{})", k[9], k[8], k[7], k[0], k[1]),
316 vec![k[9], k[8], k[7], k[0], k[1]],
317 vec![],
318 true,
319 ),
320 (
321 ms_str!(
322 "thresh(3,c:pk_k({}),sc:pk_k({}),sc:pk_k({}),sc:pk_k({}),sc:pk_k({}))",
323 k[2],
324 k[3],
325 k[4],
326 k[5],
327 k[6]
328 ),
329 vec![k[2], k[3], k[4], k[5], k[6]],
330 vec![],
331 false,
332 ),
333 (
334 ms_str!(
335 "or_d(multi(2,{},{}),and_v(v:multi(2,{},{}),older(10000)))",
336 k[6],
337 k[7],
338 k[8],
339 k[9]
340 ),
341 vec![k[6], k[7], k[8], k[9]],
342 vec![],
343 false,
344 ),
345 (
346 ms_str!(
347 "or_d(multi(3,{},{},{},{},{}),\
348 and_v(v:thresh(2,c:pk_h({}),\
349 ac:pk_h({}),ac:pk_h({})),older(10000)))",
350 k[0],
351 k[2],
352 k[4],
353 k[6],
354 k[9],
355 k[1],
356 k[3],
357 k[5]
358 ),
359 vec![k[0], k[2], k[4], k[6], k[9], k[1], k[3], k[5]],
360 vec![],
361 false,
362 ),
363 ]
364 }
365
366 #[test]
367 fn find_keys() {
368 gen_testcases().into_iter().for_each(|(ms, k, _, _)| {
369 assert_eq!(ms.iter_pk().collect::<Vec<bitcoin::PublicKey>>(), k);
370 })
371 }
372}