1use super::decode::Terminal;
20use super::{Miniscript, MiniscriptKey, ScriptContext};
21use std::ops::Deref;
22use std::sync::Arc;
23
24impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
26 pub fn iter(&self) -> Iter<Pk, Ctx> {
30 Iter::new(self)
31 }
32
33 pub fn iter_pk(&self) -> PkIter<Pk, Ctx> {
37 PkIter::new(self)
38 }
39
40 pub fn iter_pkh(&self) -> PkhIter<Pk, Ctx> {
44 PkhIter::new(self)
45 }
46
47 pub fn iter_pk_pkh(&self) -> PkPkhIter<Pk, Ctx> {
51 PkPkhIter::new(self)
52 }
53
54 pub fn branches(&self) -> Vec<&Miniscript<Pk, Ctx>> {
57 match self.node {
58 Terminal::PkK(_) | Terminal::PkH(_) | Terminal::Multi(_, _) => vec![],
59
60 Terminal::Alt(ref node)
61 | Terminal::Swap(ref node)
62 | Terminal::Check(ref node)
63 | Terminal::DupIf(ref node)
64 | Terminal::Verify(ref node)
65 | Terminal::NonZero(ref node)
66 | Terminal::ZeroNotEqual(ref node) => vec![node],
67
68 Terminal::AndV(ref node1, ref node2)
69 | Terminal::AndB(ref node1, ref node2)
70 | Terminal::OrB(ref node1, ref node2)
71 | Terminal::OrD(ref node1, ref node2)
72 | Terminal::OrC(ref node1, ref node2)
73 | Terminal::OrI(ref node1, ref node2) => vec![node1, node2],
74
75 Terminal::AndOr(ref node1, ref node2, ref node3) => vec![node1, node2, node3],
76
77 Terminal::Thresh(_, ref node_vec) => node_vec.iter().map(Arc::deref).collect(),
78
79 _ => vec![],
80 }
81 }
82
83 pub fn get_nth_child(&self, n: usize) -> Option<&Miniscript<Pk, Ctx>> {
85 match (n, &self.node) {
86 (0, &Terminal::Alt(ref node))
87 | (0, &Terminal::Swap(ref node))
88 | (0, &Terminal::Check(ref node))
89 | (0, &Terminal::DupIf(ref node))
90 | (0, &Terminal::Verify(ref node))
91 | (0, &Terminal::NonZero(ref node))
92 | (0, &Terminal::ZeroNotEqual(ref node))
93 | (0, &Terminal::AndV(ref node, _))
94 | (0, &Terminal::AndB(ref node, _))
95 | (0, &Terminal::OrB(ref node, _))
96 | (0, &Terminal::OrD(ref node, _))
97 | (0, &Terminal::OrC(ref node, _))
98 | (0, &Terminal::OrI(ref node, _))
99 | (1, &Terminal::AndV(_, ref node))
100 | (1, &Terminal::AndB(_, ref node))
101 | (1, &Terminal::OrB(_, ref node))
102 | (1, &Terminal::OrD(_, ref node))
103 | (1, &Terminal::OrC(_, ref node))
104 | (1, &Terminal::OrI(_, ref node))
105 | (0, &Terminal::AndOr(ref node, _, _))
106 | (1, &Terminal::AndOr(_, ref node, _))
107 | (2, &Terminal::AndOr(_, _, ref node)) => Some(node),
108
109 (n, &Terminal::Thresh(_, ref node_vec)) => node_vec.get(n).map(|x| &**x),
110
111 _ => None,
112 }
113 }
114
115 pub fn get_leaf_pk(&self) -> Vec<Pk> {
122 match self.node {
123 Terminal::PkK(ref key) => vec![key.clone()],
124 Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => keys.clone(),
125 _ => vec![],
126 }
127 }
128
129 pub fn get_leaf_pkh(&self) -> Vec<Pk::Hash> {
139 match self.node {
140 Terminal::PkH(ref hash) => vec![hash.clone()],
141 Terminal::PkK(ref key) => vec![key.to_pubkeyhash()],
142 Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => {
143 keys.iter().map(Pk::to_pubkeyhash).collect()
144 }
145 _ => vec![],
146 }
147 }
148
149 pub fn get_leaf_pk_pkh(&self) -> Vec<PkPkh<Pk>> {
157 match self.node {
158 Terminal::PkH(ref hash) => vec![PkPkh::HashedPubkey(hash.clone())],
159 Terminal::PkK(ref key) => vec![PkPkh::PlainPubkey(key.clone())],
160 Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => keys
161 .into_iter()
162 .map(|key| PkPkh::PlainPubkey(key.clone()))
163 .collect(),
164 _ => vec![],
165 }
166 }
167
168 pub fn get_nth_pk(&self, n: usize) -> Option<Pk> {
173 match (&self.node, n) {
174 (&Terminal::PkK(ref key), 0) => Some(key.clone()),
175 (&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => {
176 keys.get(n).cloned()
177 }
178 _ => None,
179 }
180 }
181
182 pub fn get_nth_pkh(&self, n: usize) -> Option<Pk::Hash> {
190 match (&self.node, n) {
191 (&Terminal::PkH(ref hash), 0) => Some(hash.clone()),
192 (&Terminal::PkK(ref key), 0) => Some(key.to_pubkeyhash()),
193 (&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => {
194 keys.get(n).map(Pk::to_pubkeyhash)
195 }
196 _ => None,
197 }
198 }
199
200 pub fn get_nth_pk_pkh(&self, n: usize) -> Option<PkPkh<Pk>> {
205 match (&self.node, n) {
206 (&Terminal::PkH(ref hash), 0) => Some(PkPkh::HashedPubkey(hash.clone())),
207 (&Terminal::PkK(ref key), 0) => Some(PkPkh::PlainPubkey(key.clone())),
208 (&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => {
209 keys.get(n).map(|key| PkPkh::PlainPubkey(key.clone()))
210 }
211 _ => None,
212 }
213 }
214}
215
216pub struct Iter<'a, Pk: 'a + MiniscriptKey, Ctx: 'a + ScriptContext> {
219 next: Option<&'a Miniscript<Pk, Ctx>>,
220 path: Vec<(&'a Miniscript<Pk, Ctx>, usize)>,
224}
225
226impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext> Iter<'a, Pk, Ctx> {
227 fn new(miniscript: &'a Miniscript<Pk, Ctx>) -> Self {
228 Iter {
229 next: Some(miniscript),
230 path: vec![],
231 }
232 }
233}
234
235impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext> Iterator for Iter<'a, Pk, Ctx> {
236 type Item = &'a Miniscript<Pk, Ctx>;
237
238 fn next(&mut self) -> Option<Self::Item> {
260 let mut curr = self.next;
261 if let None = curr {
262 while let Some((node, child)) = self.path.pop() {
263 curr = node.get_nth_child(child);
264 if curr.is_some() {
265 self.path.push((node, child + 1));
266 break;
267 }
268 }
269 }
270 if let Some(node) = curr {
271 self.next = node.get_nth_child(0);
272 self.path.push((node, 1));
273 }
274 curr
275 }
276}
277
278pub struct PkIter<'a, Pk: 'a + MiniscriptKey, Ctx: 'a + ScriptContext> {
281 node_iter: Iter<'a, Pk, Ctx>,
282 curr_node: Option<&'a Miniscript<Pk, Ctx>>,
283 key_index: usize,
284}
285
286impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext> PkIter<'a, Pk, Ctx> {
287 fn new(miniscript: &'a Miniscript<Pk, Ctx>) -> Self {
288 let mut iter = Iter::new(miniscript);
289 PkIter {
290 curr_node: iter.next(),
291 node_iter: iter,
292 key_index: 0,
293 }
294 }
295}
296
297impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext> Iterator for PkIter<'a, Pk, Ctx> {
298 type Item = Pk;
299
300 fn next(&mut self) -> Option<Self::Item> {
301 loop {
302 match self.curr_node {
303 None => break None,
304 Some(node) => match node.get_nth_pk(self.key_index) {
305 None => {
306 self.curr_node = self.node_iter.next();
307 self.key_index = 0;
308 continue;
309 }
310 Some(pk) => {
311 self.key_index += 1;
312 break Some(pk);
313 }
314 },
315 }
316 }
317 }
318}
319
320pub struct PkhIter<'a, Pk: 'a + MiniscriptKey, Ctx: 'a + ScriptContext> {
323 node_iter: Iter<'a, Pk, Ctx>,
324 curr_node: Option<&'a Miniscript<Pk, Ctx>>,
325 key_index: usize,
326}
327
328impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext> PkhIter<'a, Pk, Ctx> {
329 fn new(miniscript: &'a Miniscript<Pk, Ctx>) -> Self {
330 let mut iter = Iter::new(miniscript);
331 PkhIter {
332 curr_node: iter.next(),
333 node_iter: iter,
334 key_index: 0,
335 }
336 }
337}
338
339impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext> Iterator for PkhIter<'a, Pk, Ctx> {
340 type Item = Pk::Hash;
341
342 fn next(&mut self) -> Option<Self::Item> {
343 loop {
344 match self.curr_node {
345 None => break None,
346 Some(node) => match node.get_nth_pkh(self.key_index) {
347 None => {
348 self.curr_node = self.node_iter.next();
349 self.key_index = 0;
350 continue;
351 }
352 Some(pk) => {
353 self.key_index += 1;
354 break Some(pk);
355 }
356 },
357 }
358 }
359 }
360}
361
362#[derive(Clone, PartialEq, Eq, Debug)]
364pub enum PkPkh<Pk: MiniscriptKey> {
365 PlainPubkey(Pk),
367 HashedPubkey(Pk::Hash),
369}
370
371pub struct PkPkhIter<'a, Pk: 'a + MiniscriptKey, Ctx: 'a + ScriptContext> {
375 node_iter: Iter<'a, Pk, Ctx>,
376 curr_node: Option<&'a Miniscript<Pk, Ctx>>,
377 key_index: usize,
378}
379
380impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext> PkPkhIter<'a, Pk, Ctx> {
381 fn new(miniscript: &'a Miniscript<Pk, Ctx>) -> Self {
382 let mut iter = Iter::new(miniscript);
383 PkPkhIter {
384 curr_node: iter.next(),
385 node_iter: iter,
386 key_index: 0,
387 }
388 }
389
390 pub fn pk_only(self) -> Option<Vec<Pk>> {
402 let mut keys = vec![];
403 for item in self {
404 match item {
405 PkPkh::HashedPubkey(_) => return None,
406 PkPkh::PlainPubkey(key) => {
407 keys.push(key);
408 }
409 }
410 }
411 Some(keys)
412 }
413}
414
415impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext> Iterator for PkPkhIter<'a, Pk, Ctx> {
416 type Item = PkPkh<Pk>;
417
418 fn next(&mut self) -> Option<Self::Item> {
419 loop {
420 match self.curr_node {
421 None => break None,
422 Some(node) => match node.get_nth_pk_pkh(self.key_index) {
423 None => {
424 self.curr_node = self.node_iter.next();
425 self.key_index = 0;
426 continue;
427 }
428 Some(pk) => {
429 self.key_index += 1;
430 break Some(pk);
431 }
432 },
433 }
434 }
435 }
436}
437
438#[cfg(test)]
441pub mod test {
442 use super::{Miniscript, PkPkh};
443 use bitcoin;
444 use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d, Hash};
445 use bitcoin::secp256k1;
446 use miniscript::context::Segwitv0;
447
448 pub type TestData = (
449 Miniscript<bitcoin::PublicKey, Segwitv0>,
450 Vec<bitcoin::PublicKey>,
451 Vec<hash160::Hash>,
452 bool, );
454
455 pub fn gen_secp_pubkeys(n: usize) -> Vec<secp256k1::PublicKey> {
456 let mut ret = Vec::with_capacity(n);
457 let secp = secp256k1::Secp256k1::new();
458 let mut sk = [0; 32];
459
460 for i in 1..n + 1 {
461 sk[0] = i as u8;
462 sk[1] = (i >> 8) as u8;
463 sk[2] = (i >> 16) as u8;
464
465 ret.push(secp256k1::PublicKey::from_secret_key(
466 &secp,
467 &secp256k1::SecretKey::from_slice(&sk[..]).unwrap(),
468 ));
469 }
470 ret
471 }
472
473 pub fn gen_bitcoin_pubkeys(n: usize, compressed: bool) -> Vec<bitcoin::PublicKey> {
474 gen_secp_pubkeys(n)
475 .into_iter()
476 .map(|inner| bitcoin::PublicKey { inner, compressed })
477 .collect()
478 }
479
480 pub fn gen_testcases() -> Vec<TestData> {
481 let k = gen_bitcoin_pubkeys(10, true);
482 let h: Vec<hash160::Hash> = k
483 .iter()
484 .map(|pk| hash160::Hash::hash(&pk.to_bytes()))
485 .collect();
486
487 let preimage = vec![0xab as u8; 32];
488 let sha256_hash = sha256::Hash::hash(&preimage);
489 let sha256d_hash_rev = sha256d::Hash::hash(&preimage);
490 let mut sha256d_hash_bytes = sha256d_hash_rev.clone().into_inner();
491 sha256d_hash_bytes.reverse();
492 let sha256d_hash = sha256d::Hash::from_inner(sha256d_hash_bytes);
493 let hash160_hash = hash160::Hash::hash(&preimage);
494 let ripemd160_hash = ripemd160::Hash::hash(&preimage);
495
496 vec![
497 (ms_str!("after({})", 1000), vec![], vec![], false),
498 (ms_str!("older({})", 1000), vec![], vec![], false),
499 (ms_str!("sha256({})", sha256_hash), vec![], vec![], false),
500 (ms_str!("hash256({})", sha256d_hash), vec![], vec![], false),
501 (ms_str!("hash160({})", hash160_hash), vec![], vec![], false),
502 (
503 ms_str!("ripemd160({})", ripemd160_hash),
504 vec![],
505 vec![],
506 false,
507 ),
508 (ms_str!("c:pk_k({})", k[0]), vec![k[0]], vec![], true),
509 (ms_str!("c:pk_h({})", h[6]), vec![], vec![h[6]], true),
510 (
511 ms_str!("and_v(vc:pk_k({}),c:pk_h({}))", k[0], h[1]),
512 vec![k[0]],
513 vec![h[1]],
514 false,
515 ),
516 (
517 ms_str!("and_b(c:pk_k({}),sjtv:sha256({}))", k[0], sha256_hash),
518 vec![k[0]],
519 vec![],
520 false,
521 ),
522 (
523 ms_str!(
524 "andor(c:pk_k({}),jtv:sha256({}),c:pk_h({}))",
525 k[1],
526 sha256_hash,
527 h[2]
528 ),
529 vec![k[1]],
530 vec![h[2]],
531 false,
532 ),
533 (
534 ms_str!("multi(3,{},{},{},{},{})", k[9], k[8], k[7], k[0], k[1]),
535 vec![k[9], k[8], k[7], k[0], k[1]],
536 vec![],
537 true,
538 ),
539 (
540 ms_str!(
541 "thresh(3,c:pk_k({}),sc:pk_k({}),sc:pk_k({}),sc:pk_k({}),sc:pk_k({}))",
542 k[2],
543 k[3],
544 k[4],
545 k[5],
546 k[6]
547 ),
548 vec![k[2], k[3], k[4], k[5], k[6]],
549 vec![],
550 false,
551 ),
552 (
553 ms_str!(
554 "or_d(multi(2,{},{}),and_v(v:multi(2,{},{}),older(10000)))",
555 k[6],
556 k[7],
557 k[8],
558 k[9]
559 ),
560 vec![k[6], k[7], k[8], k[9]],
561 vec![],
562 false,
563 ),
564 (
565 ms_str!(
566 "or_d(multi(3,{},{},{},{},{}),\
567 and_v(v:thresh(2,c:pk_h({}),\
568 ac:pk_h({}),ac:pk_h({})),older(10000)))",
569 k[0],
570 k[2],
571 k[4],
572 k[6],
573 k[9],
574 h[8],
575 h[7],
576 h[0]
577 ),
578 vec![k[0], k[2], k[4], k[6], k[9]],
579 vec![h[8], h[7], h[0]],
580 false,
581 ),
582 ]
583 }
584
585 #[test]
586 fn get_keys() {
587 gen_testcases()
588 .into_iter()
589 .for_each(|(ms, k, _, test_top_level)| {
590 if !test_top_level {
591 return;
592 }
593 let ms = *ms.branches().first().unwrap_or(&&ms);
594 assert_eq!(ms.get_leaf_pk(), k);
595 })
596 }
597
598 #[test]
599 fn get_hashes() {
600 gen_testcases()
601 .into_iter()
602 .for_each(|(ms, k, h, test_top_level)| {
603 if !test_top_level {
604 return;
605 }
606 let ms = *ms.branches().first().unwrap_or(&&ms);
607 let mut all: Vec<hash160::Hash> = k
608 .iter()
609 .map(|p| hash160::Hash::hash(&p.to_bytes()))
610 .collect();
611 all.extend(h);
613 assert_eq!(ms.get_leaf_pkh(), all);
614 })
615 }
616
617 #[test]
618 fn get_pubkey_and_hashes() {
619 gen_testcases()
620 .into_iter()
621 .for_each(|(ms, k, h, test_top_level)| {
622 if !test_top_level {
623 return;
624 }
625 let ms = *ms.branches().first().unwrap_or(&&ms);
626 let r: Vec<PkPkh<bitcoin::PublicKey>> = if k.is_empty() {
627 h.into_iter().map(|h| PkPkh::HashedPubkey(h)).collect()
628 } else {
629 k.into_iter().map(|k| PkPkh::PlainPubkey(k)).collect()
630 };
631 assert_eq!(ms.get_leaf_pk_pkh(), r);
632 })
633 }
634
635 #[test]
636 fn find_keys() {
637 gen_testcases().into_iter().for_each(|(ms, k, _, _)| {
638 assert_eq!(ms.iter_pk().collect::<Vec<bitcoin::PublicKey>>(), k);
639 })
640 }
641
642 #[test]
643 fn find_hashes() {
644 gen_testcases().into_iter().for_each(|(ms, k, h, _)| {
645 let mut all: Vec<hash160::Hash> = k
646 .iter()
647 .map(|p| hash160::Hash::hash(&p.to_bytes()))
648 .collect();
649 all.extend(h);
651 assert_eq!(ms.iter_pkh().collect::<Vec<hash160::Hash>>(), all);
652 })
653 }
654
655 #[test]
656 fn find_pubkeys_and_hashes() {
657 gen_testcases().into_iter().for_each(|(ms, k, h, _)| {
658 let mut all: Vec<PkPkh<bitcoin::PublicKey>> =
659 k.into_iter().map(|k| PkPkh::PlainPubkey(k)).collect();
660 all.extend(h.into_iter().map(|h| PkPkh::HashedPubkey(h)));
661 assert_eq!(
662 ms.iter_pk_pkh().collect::<Vec<PkPkh<bitcoin::PublicKey>>>(),
663 all
664 );
665 })
666 }
667}