1use crate::bitstream::{BitReader, BitWriter};
4use crate::error::Error;
5use crate::tag::Tag;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct Node {
10 pub tag: Tag,
12 pub body: Body,
14}
15
16#[derive(Debug, Clone, PartialEq, Eq)]
18pub enum Body {
19 Children(Vec<Node>),
21 Variable {
25 k: u8,
27 children: Vec<Node>,
29 },
30 MultiKeys {
35 k: u8,
37 indices: Vec<u8>,
40 },
41 Tr {
50 is_nums: bool,
52 key_index: u8,
55 tree: Option<Box<Node>>,
57 },
58 KeyArg {
62 index: u8,
64 },
65 Hash256Body([u8; 32]),
67 Hash160Body([u8; 20]),
69 Timelock(u32),
71 Empty,
73}
74
75pub fn write_node(w: &mut BitWriter, node: &Node, key_index_width: u8) -> Result<(), Error> {
80 node.tag.write(w);
81 match &node.body {
82 Body::KeyArg { index } => {
83 w.write_bits(u64::from(*index), key_index_width as usize);
84 }
85 Body::Children(children) => {
86 for c in children {
87 write_node(w, c, key_index_width)?;
88 }
89 }
90 Body::Variable { k, children } => {
91 if !(1..=32).contains(&(*k as u32)) {
93 return Err(Error::ThresholdOutOfRange { k: *k });
94 }
95 if !(1..=32).contains(&(children.len() as u32)) {
96 return Err(Error::ChildCountOutOfRange {
97 count: children.len(),
98 });
99 }
100 w.write_bits((*k - 1) as u64, 5);
101 w.write_bits((children.len() - 1) as u64, 5);
102 for c in children {
103 write_node(w, c, key_index_width)?;
104 }
105 }
106 Body::MultiKeys { k, indices } => {
107 if !(1..=32).contains(&(*k as u32)) {
109 return Err(Error::ThresholdOutOfRange { k: *k });
110 }
111 if !(1..=32).contains(&(indices.len() as u32)) {
112 return Err(Error::ChildCountOutOfRange {
113 count: indices.len(),
114 });
115 }
116 w.write_bits((*k - 1) as u64, 5);
117 w.write_bits((indices.len() - 1) as u64, 5);
118 for idx in indices {
119 w.write_bits(u64::from(*idx), key_index_width as usize);
120 }
121 }
122 Body::Tr {
123 is_nums,
124 key_index,
125 tree,
126 } => {
127 debug_assert!(
130 !(*is_nums && *key_index != 0),
131 "is_nums=true implies key_index=0 (no wire representation otherwise)"
132 );
133 w.write_bits(u64::from(*is_nums), 1);
134 if !*is_nums {
135 w.write_bits(u64::from(*key_index), key_index_width as usize);
136 }
137 w.write_bits(u64::from(tree.is_some()), 1);
138 if let Some(t) = tree {
139 write_node(w, t, key_index_width)?;
140 }
141 }
142 Body::Timelock(v) => {
143 w.write_bits(u64::from(*v), 32);
144 }
145 Body::Hash256Body(h) => {
146 for byte in h {
147 w.write_bits(u64::from(*byte), 8);
148 }
149 }
150 Body::Hash160Body(h) => {
151 for byte in h {
152 w.write_bits(u64::from(*byte), 8);
153 }
154 }
155 Body::Empty => {}
156 }
157 Ok(())
158}
159
160pub const MAX_DECODE_DEPTH: u8 = 128;
168
169pub fn read_node(r: &mut BitReader, key_index_width: u8) -> Result<Node, Error> {
179 read_node_with_depth(r, key_index_width, 0)
180}
181
182fn read_node_with_depth(r: &mut BitReader, key_index_width: u8, depth: u8) -> Result<Node, Error> {
186 if depth >= MAX_DECODE_DEPTH {
187 return Err(Error::DecodeRecursionDepthExceeded {
188 depth,
189 max: MAX_DECODE_DEPTH,
190 });
191 }
192 let tag = Tag::read(r)?;
193 let body = match tag {
194 Tag::PkK | Tag::PkH | Tag::Wpkh | Tag::Pkh => {
195 let index = r.read_bits(key_index_width as usize)? as u8;
196 Body::KeyArg { index }
197 }
198 Tag::Sh
199 | Tag::Wsh
200 | Tag::Check
201 | Tag::Verify
202 | Tag::Swap
203 | Tag::Alt
204 | Tag::DupIf
205 | Tag::NonZero
206 | Tag::ZeroNotEqual => {
207 let child = read_node_with_depth(r, key_index_width, depth + 1)?;
208 Body::Children(vec![child])
209 }
210 Tag::AndV | Tag::AndB | Tag::OrB | Tag::OrC | Tag::OrD | Tag::OrI => {
211 let l = read_node_with_depth(r, key_index_width, depth + 1)?;
212 let r2 = read_node_with_depth(r, key_index_width, depth + 1)?;
213 Body::Children(vec![l, r2])
214 }
215 Tag::AndOr => {
216 let a = read_node_with_depth(r, key_index_width, depth + 1)?;
217 let b = read_node_with_depth(r, key_index_width, depth + 1)?;
218 let c = read_node_with_depth(r, key_index_width, depth + 1)?;
219 Body::Children(vec![a, b, c])
220 }
221 Tag::TapTree => {
222 let l = read_node_with_depth(r, key_index_width, depth + 1)?;
223 let r2 = read_node_with_depth(r, key_index_width, depth + 1)?;
224 Body::Children(vec![l, r2])
225 }
226 Tag::Multi | Tag::SortedMulti | Tag::MultiA | Tag::SortedMultiA => {
227 let k = (r.read_bits(5)? + 1) as u8;
228 let count = (r.read_bits(5)? + 1) as usize;
229 if k as usize > count {
230 return Err(Error::KGreaterThanN { k, n: count });
231 }
232 let mut indices = Vec::with_capacity(count);
233 for _ in 0..count {
234 indices.push(r.read_bits(key_index_width as usize)? as u8);
235 }
236 Body::MultiKeys { k, indices }
237 }
238 Tag::Thresh => {
239 let k = (r.read_bits(5)? + 1) as u8;
240 let count = (r.read_bits(5)? + 1) as usize;
241 if k as usize > count {
242 return Err(Error::KGreaterThanN { k, n: count });
243 }
244 let mut children = Vec::with_capacity(count);
245 for _ in 0..count {
246 children.push(read_node_with_depth(r, key_index_width, depth + 1)?);
247 }
248 Body::Variable { k, children }
249 }
250 Tag::Tr => {
251 let is_nums = r.read_bits(1)? != 0;
254 let key_index = if is_nums {
255 0
256 } else {
257 r.read_bits(key_index_width as usize)? as u8
258 };
259 let has_tree = r.read_bits(1)? != 0;
260 let tree = if has_tree {
261 Some(Box::new(read_node_with_depth(
262 r,
263 key_index_width,
264 depth + 1,
265 )?))
266 } else {
267 None
268 };
269 Body::Tr {
270 is_nums,
271 key_index,
272 tree,
273 }
274 }
275 Tag::After | Tag::Older => {
276 let v = r.read_bits(32)? as u32;
277 Body::Timelock(v)
278 }
279 Tag::Sha256 => {
280 let mut h = [0u8; 32];
281 for byte in &mut h {
282 *byte = r.read_bits(8)? as u8;
283 }
284 Body::Hash256Body(h)
285 }
286 Tag::Hash160 => {
287 let mut h = [0u8; 20];
288 for byte in &mut h {
289 *byte = r.read_bits(8)? as u8;
290 }
291 Body::Hash160Body(h)
292 }
293 Tag::Hash256 => {
294 let mut h = [0u8; 32];
295 for byte in &mut h {
296 *byte = r.read_bits(8)? as u8;
297 }
298 Body::Hash256Body(h)
299 }
300 Tag::Ripemd160 | Tag::RawPkH => {
301 let mut h = [0u8; 20];
302 for byte in &mut h {
303 *byte = r.read_bits(8)? as u8;
304 }
305 Body::Hash160Body(h)
306 }
307 Tag::False | Tag::True => Body::Empty,
308 };
309 Ok(Node { tag, body })
310}
311
312#[cfg(test)]
313mod tests {
314 use super::*;
315 use crate::bitstream::{BitReader, BitWriter};
316
317 #[test]
318 fn key_arg_n1_zero_bits() {
319 let n = Node {
321 tag: Tag::PkK,
322 body: Body::KeyArg { index: 0 },
323 };
324 let mut w = BitWriter::new();
325 write_node(&mut w, &n, 0).unwrap();
326 assert_eq!(w.bit_len(), 6);
328 }
329
330 #[test]
331 fn key_arg_n3_two_bits() {
332 let n = Node {
334 tag: Tag::PkK,
335 body: Body::KeyArg { index: 2 },
336 };
337 let mut w = BitWriter::new();
338 write_node(&mut w, &n, 2).unwrap();
339 assert_eq!(w.bit_len(), 8);
341 }
342
343 #[test]
344 fn key_arg_round_trip() {
345 let n = Node {
346 tag: Tag::PkK,
347 body: Body::KeyArg { index: 1 },
348 };
349 let mut w = BitWriter::new();
350 write_node(&mut w, &n, 2).unwrap();
351 let bytes = w.into_bytes();
352 let mut r = BitReader::new(&bytes);
353 assert_eq!(read_node(&mut r, 2).unwrap(), n);
354 }
355
356 #[test]
357 fn wrapper_chain_v_c_pk_round_trip() {
358 let n = Node {
360 tag: Tag::Verify,
361 body: Body::Children(vec![Node {
362 tag: Tag::Check,
363 body: Body::Children(vec![Node {
364 tag: Tag::PkK,
365 body: Body::KeyArg { index: 0 },
366 }]),
367 }]),
368 };
369 let mut w = BitWriter::new();
370 write_node(&mut w, &n, 2).unwrap();
371 let bytes = w.into_bytes();
372 let mut r = BitReader::new(&bytes);
373 assert_eq!(read_node(&mut r, 2).unwrap(), n);
374 }
375
376 #[test]
377 fn sortedmulti_2of3_round_trip() {
378 let n = Node {
379 tag: Tag::SortedMulti,
380 body: Body::MultiKeys {
381 k: 2,
382 indices: vec![0, 1, 2],
383 },
384 };
385 let mut w = BitWriter::new();
386 write_node(&mut w, &n, 2).unwrap();
387 let bytes = w.into_bytes();
388 let mut r = BitReader::new(&bytes);
389 assert_eq!(read_node(&mut r, 2).unwrap(), n);
390 }
391
392 #[test]
396 fn sortedmulti_2of3_bit_cost() {
397 let n = Node {
398 tag: Tag::SortedMulti,
399 body: Body::MultiKeys {
400 k: 2,
401 indices: vec![0, 1, 2],
402 },
403 };
404 let mut w = BitWriter::new();
405 write_node(&mut w, &n, 2).unwrap();
406 assert_eq!(w.bit_len(), 22);
407 }
408
409 #[test]
411 fn multi_keys_body_round_trip() {
412 let n = Node {
413 tag: Tag::Multi,
414 body: Body::MultiKeys {
415 k: 2,
416 indices: vec![0, 1, 2],
417 },
418 };
419 let mut w = BitWriter::new();
420 write_node(&mut w, &n, 2).unwrap();
421 let bytes = w.into_bytes();
422 let mut r = BitReader::new(&bytes);
423 assert_eq!(read_node(&mut r, 2).unwrap(), n);
424 }
425
426 #[test]
428 fn sortedmulti_a_indices_round_trip() {
429 let n = Node {
430 tag: Tag::SortedMultiA,
431 body: Body::MultiKeys {
432 k: 2,
433 indices: vec![0, 1, 2],
434 },
435 };
436 let mut w = BitWriter::new();
437 write_node(&mut w, &n, 2).unwrap();
438 let bytes = w.into_bytes();
439 let mut r = BitReader::new(&bytes);
440 assert_eq!(read_node(&mut r, 2).unwrap(), n);
441 }
442
443 #[test]
444 fn tr_bip86_no_tree() {
445 let n = Node {
449 tag: Tag::Tr,
450 body: Body::Tr {
451 is_nums: false,
452 key_index: 0,
453 tree: None,
454 },
455 };
456 let mut w = BitWriter::new();
457 write_node(&mut w, &n, 0).unwrap();
458 assert_eq!(w.bit_len(), 8);
460 let bytes = w.into_bytes();
461 let mut r = BitReader::new(&bytes);
462 assert_eq!(read_node(&mut r, 0).unwrap(), n);
463 }
464
465 #[test]
466 fn thresh_2of3_with_pk_children() {
467 let n = Node {
469 tag: Tag::Thresh,
470 body: Body::Variable {
471 k: 2,
472 children: vec![
473 Node {
474 tag: Tag::PkK,
475 body: Body::KeyArg { index: 0 },
476 },
477 Node {
478 tag: Tag::PkK,
479 body: Body::KeyArg { index: 1 },
480 },
481 Node {
482 tag: Tag::PkK,
483 body: Body::KeyArg { index: 2 },
484 },
485 ],
486 },
487 };
488 let mut w = BitWriter::new();
489 write_node(&mut w, &n, 2).unwrap();
490 let bytes = w.into_bytes();
491 let mut r = BitReader::new(&bytes);
492 assert_eq!(read_node(&mut r, 2).unwrap(), n);
493 }
494
495 #[test]
496 fn tr_with_single_leaf() {
497 let n = Node {
499 tag: Tag::Tr,
500 body: Body::Tr {
501 is_nums: false,
502 key_index: 0,
503 tree: Some(Box::new(Node {
504 tag: Tag::MultiA,
505 body: Body::MultiKeys {
506 k: 2,
507 indices: vec![1, 2],
508 },
509 })),
510 },
511 };
512 let mut w = BitWriter::new();
513 write_node(&mut w, &n, 2).unwrap();
514 let bytes = w.into_bytes();
515 let mut r = BitReader::new(&bytes);
516 assert_eq!(read_node(&mut r, 2).unwrap(), n);
517 }
518
519 #[test]
522 fn tr_nums_flag_round_trip() {
523 let n = Node {
524 tag: Tag::Tr,
525 body: Body::Tr {
526 is_nums: true,
527 key_index: 0,
528 tree: None,
529 },
530 };
531 let mut w = BitWriter::new();
532 write_node(&mut w, &n, 2).unwrap();
533 let bytes = w.into_bytes();
534 let mut r = BitReader::new(&bytes);
535 assert_eq!(read_node(&mut r, 2).unwrap(), n);
536 }
537
538 #[test]
541 fn tr_is_nums_false_round_trip() {
542 let n = Node {
543 tag: Tag::Tr,
544 body: Body::Tr {
545 is_nums: false,
546 key_index: 2,
547 tree: None,
548 },
549 };
550 let mut w = BitWriter::new();
551 write_node(&mut w, &n, 2).unwrap();
552 let bytes = w.into_bytes();
553 let mut r = BitReader::new(&bytes);
554 assert_eq!(read_node(&mut r, 2).unwrap(), n);
555 }
556
557 #[test]
558 fn after_700_000_round_trip() {
559 let n = Node {
560 tag: Tag::After,
561 body: Body::Timelock(700_000),
562 };
563 let mut w = BitWriter::new();
564 write_node(&mut w, &n, 0).unwrap();
565 assert_eq!(w.bit_len(), 38);
567 let bytes = w.into_bytes();
568 let mut r = BitReader::new(&bytes);
569 assert_eq!(read_node(&mut r, 0).unwrap(), n);
570 }
571
572 #[test]
573 fn sha256_round_trip() {
574 let h = [0xab; 32];
575 let n = Node {
576 tag: Tag::Sha256,
577 body: Body::Hash256Body(h),
578 };
579 let mut w = BitWriter::new();
580 write_node(&mut w, &n, 0).unwrap();
581 assert_eq!(w.bit_len(), 262);
583 let bytes = w.into_bytes();
584 let mut r = BitReader::new(&bytes);
585 assert_eq!(read_node(&mut r, 0).unwrap(), n);
586 }
587
588 #[test]
589 fn hash160_round_trip() {
590 let h = [0xcd; 20];
591 let n = Node {
592 tag: Tag::Hash160,
593 body: Body::Hash160Body(h),
594 };
595 let mut w = BitWriter::new();
596 write_node(&mut w, &n, 0).unwrap();
597 assert_eq!(w.bit_len(), 166);
599 let bytes = w.into_bytes();
600 let mut r = BitReader::new(&bytes);
601 assert_eq!(read_node(&mut r, 0).unwrap(), n);
602 }
603
604 #[test]
605 fn hash256_round_trip() {
606 let h = [0xef; 32];
607 let n = Node {
608 tag: Tag::Hash256,
609 body: Body::Hash256Body(h),
610 };
611 let mut w = BitWriter::new();
612 write_node(&mut w, &n, 0).unwrap();
613 assert_eq!(w.bit_len(), 262);
615 let bytes = w.into_bytes();
616 let mut r = BitReader::new(&bytes);
617 assert_eq!(read_node(&mut r, 0).unwrap(), n);
618 }
619
620 #[test]
621 fn ripemd160_round_trip() {
622 let h = [0x42; 20];
623 let n = Node {
624 tag: Tag::Ripemd160,
625 body: Body::Hash160Body(h),
626 };
627 let mut w = BitWriter::new();
628 write_node(&mut w, &n, 0).unwrap();
629 let bytes = w.into_bytes();
630 let mut r = BitReader::new(&bytes);
631 assert_eq!(read_node(&mut r, 0).unwrap(), n);
632 }
633
634 #[test]
635 fn false_round_trip() {
636 let n = Node {
637 tag: Tag::False,
638 body: Body::Empty,
639 };
640 let mut w = BitWriter::new();
641 write_node(&mut w, &n, 0).unwrap();
642 assert_eq!(w.bit_len(), 6); let bytes = w.into_bytes();
644 let mut r = BitReader::new(&bytes);
645 assert_eq!(read_node(&mut r, 0).unwrap(), n);
646 }
647
648 #[test]
649 fn true_round_trip() {
650 let n = Node {
651 tag: Tag::True,
652 body: Body::Empty,
653 };
654 let mut w = BitWriter::new();
655 write_node(&mut w, &n, 0).unwrap();
656 let bytes = w.into_bytes();
657 let mut r = BitReader::new(&bytes);
658 assert_eq!(read_node(&mut r, 0).unwrap(), n);
659 }
660
661 #[test]
662 fn older_144_round_trip() {
663 let n = Node {
664 tag: Tag::Older,
665 body: Body::Timelock(144),
666 };
667 let mut w = BitWriter::new();
668 write_node(&mut w, &n, 0).unwrap();
669 let bytes = w.into_bytes();
670 let mut r = BitReader::new(&bytes);
671 assert_eq!(read_node(&mut r, 0).unwrap(), n);
672 }
673
674 #[test]
675 fn tr_nums_n_1_bare_round_trip() {
676 let n = Node {
681 tag: Tag::Tr,
682 body: Body::Tr {
683 is_nums: true,
684 key_index: 0,
685 tree: None,
686 },
687 };
688 let mut w = BitWriter::new();
689 write_node(&mut w, &n, 0).unwrap();
691 assert_eq!(w.bit_len(), 8);
693 let bytes = w.into_bytes();
694 let mut r = BitReader::new(&bytes);
695 assert_eq!(read_node(&mut r, 0).unwrap(), n);
696 }
697
698 #[test]
699 fn tr_nums_n_2_and_v_inheritance_round_trip() {
700 let n = Node {
704 tag: Tag::Tr,
705 body: Body::Tr {
706 is_nums: true,
707 key_index: 0,
708 tree: Some(Box::new(Node {
709 tag: Tag::AndV,
710 body: Body::Children(vec![
711 Node {
712 tag: Tag::Verify,
713 body: Body::Children(vec![Node {
714 tag: Tag::PkK,
715 body: Body::KeyArg { index: 0 },
716 }]),
717 },
718 Node {
719 tag: Tag::PkK,
720 body: Body::KeyArg { index: 1 },
721 },
722 ]),
723 })),
724 },
725 };
726 let mut w = BitWriter::new();
727 write_node(&mut w, &n, 1).unwrap();
729 let bytes = w.into_bytes();
730 let mut r = BitReader::new(&bytes);
731 assert_eq!(read_node(&mut r, 1).unwrap(), n);
732 }
733
734 #[test]
735 fn tr_nums_n_3_multi_a_2_of_3_round_trip() {
736 let n = Node {
740 tag: Tag::Tr,
741 body: Body::Tr {
742 is_nums: true,
743 key_index: 0,
744 tree: Some(Box::new(Node {
745 tag: Tag::MultiA,
746 body: Body::MultiKeys {
747 k: 2,
748 indices: vec![0, 1, 2],
749 },
750 })),
751 },
752 };
753 let mut w = BitWriter::new();
754 write_node(&mut w, &n, 2).unwrap();
755 let bytes = w.into_bytes();
756 let mut r = BitReader::new(&bytes);
757 assert_eq!(read_node(&mut r, 2).unwrap(), n);
758 }
759
760 #[test]
761 fn tr_nums_n_4_bare_round_trip() {
762 let n = Node {
766 tag: Tag::Tr,
767 body: Body::Tr {
768 is_nums: true,
769 key_index: 0,
770 tree: None,
771 },
772 };
773 let mut w = BitWriter::new();
774 write_node(&mut w, &n, 2).unwrap();
776 assert_eq!(w.bit_len(), 8);
778 let bytes = w.into_bytes();
779 let mut r = BitReader::new(&bytes);
780 assert_eq!(read_node(&mut r, 2).unwrap(), n);
781 }
782
783 #[test]
791 fn tap_tree_two_leaf_round_trip() {
792 let n = Node {
793 tag: Tag::Tr,
794 body: Body::Tr {
795 is_nums: false,
796 key_index: 0,
797 tree: Some(Box::new(Node {
798 tag: Tag::TapTree,
799 body: Body::Children(vec![
800 Node {
801 tag: Tag::PkK,
802 body: Body::KeyArg { index: 1 },
803 },
804 Node {
805 tag: Tag::PkK,
806 body: Body::KeyArg { index: 2 },
807 },
808 ]),
809 })),
810 },
811 };
812 let mut w = BitWriter::new();
813 write_node(&mut w, &n, 2).unwrap();
814 assert_eq!(w.bit_len(), 32, "2-leaf TapTree wire layout pin");
815 let bytes = w.into_bytes();
816 let mut r = BitReader::new(&bytes);
817 assert_eq!(read_node(&mut r, 2).unwrap(), n);
818 }
819
820 #[test]
824 fn tap_tree_nested_four_leaf_round_trip() {
825 let mk_branch = |a: u8, b: u8| Node {
826 tag: Tag::TapTree,
827 body: Body::Children(vec![
828 Node {
829 tag: Tag::PkK,
830 body: Body::KeyArg { index: a },
831 },
832 Node {
833 tag: Tag::PkK,
834 body: Body::KeyArg { index: b },
835 },
836 ]),
837 };
838 let n = Node {
839 tag: Tag::Tr,
840 body: Body::Tr {
841 is_nums: false,
842 key_index: 0,
843 tree: Some(Box::new(Node {
844 tag: Tag::TapTree,
845 body: Body::Children(vec![mk_branch(1, 2), mk_branch(3, 4)]),
846 })),
847 },
848 };
849 let mut w = BitWriter::new();
850 write_node(&mut w, &n, 3).unwrap();
852 let bytes = w.into_bytes();
853 let mut r = BitReader::new(&bytes);
854 assert_eq!(read_node(&mut r, 3).unwrap(), n);
855 }
856
857 #[test]
862 fn tap_tree_unbalanced_round_trip() {
863 let n = Node {
864 tag: Tag::Tr,
865 body: Body::Tr {
866 is_nums: false,
867 key_index: 0,
868 tree: Some(Box::new(Node {
869 tag: Tag::TapTree,
870 body: Body::Children(vec![
871 Node {
872 tag: Tag::PkK,
873 body: Body::KeyArg { index: 1 },
874 },
875 Node {
876 tag: Tag::TapTree,
877 body: Body::Children(vec![
878 Node {
879 tag: Tag::PkK,
880 body: Body::KeyArg { index: 2 },
881 },
882 Node {
883 tag: Tag::PkK,
884 body: Body::KeyArg { index: 3 },
885 },
886 ]),
887 },
888 ]),
889 })),
890 },
891 };
892 let mut w = BitWriter::new();
893 write_node(&mut w, &n, 2).unwrap();
895 let bytes = w.into_bytes();
896 let mut r = BitReader::new(&bytes);
897 assert_eq!(read_node(&mut r, 2).unwrap(), n);
898 }
899
900 #[test]
905 fn read_node_rejects_excessive_taptree_nesting() {
906 let mut left = Node {
907 tag: Tag::PkK,
908 body: Body::KeyArg { index: 0 },
909 };
910 for _ in 0..128 {
913 left = Node {
914 tag: Tag::TapTree,
915 body: Body::Children(vec![
916 left,
917 Node {
918 tag: Tag::PkK,
919 body: Body::KeyArg { index: 0 },
920 },
921 ]),
922 };
923 }
924 let mut w = BitWriter::new();
925 write_node(&mut w, &left, 0).unwrap();
926 let bytes = w.into_bytes();
927 let mut r = BitReader::new(&bytes);
928 let err = read_node(&mut r, 0).unwrap_err();
929 assert_eq!(
930 err,
931 Error::DecodeRecursionDepthExceeded {
932 depth: 128,
933 max: MAX_DECODE_DEPTH,
934 }
935 );
936 }
937
938 #[test]
941 fn read_node_rejects_excessive_andv_chain_nesting() {
942 let mut left = Node {
943 tag: Tag::PkK,
944 body: Body::KeyArg { index: 0 },
945 };
946 for _ in 0..128 {
949 left = Node {
950 tag: Tag::AndV,
951 body: Body::Children(vec![
952 left,
953 Node {
954 tag: Tag::PkK,
955 body: Body::KeyArg { index: 0 },
956 },
957 ]),
958 };
959 }
960 let mut w = BitWriter::new();
961 write_node(&mut w, &left, 0).unwrap();
962 let bytes = w.into_bytes();
963 let mut r = BitReader::new(&bytes);
964 let err = read_node(&mut r, 0).unwrap_err();
965 assert_eq!(
966 err,
967 Error::DecodeRecursionDepthExceeded {
968 depth: 128,
969 max: MAX_DECODE_DEPTH,
970 }
971 );
972 }
973
974 #[test]
977 fn read_node_accepts_max_depth_minus_one() {
978 let mut left = Node {
979 tag: Tag::PkK,
980 body: Body::KeyArg { index: 0 },
981 };
982 for _ in 0..127 {
984 left = Node {
985 tag: Tag::TapTree,
986 body: Body::Children(vec![
987 left,
988 Node {
989 tag: Tag::PkK,
990 body: Body::KeyArg { index: 0 },
991 },
992 ]),
993 };
994 }
995 let mut w = BitWriter::new();
996 write_node(&mut w, &left, 0).unwrap();
997 let bytes = w.into_bytes();
998 let mut r = BitReader::new(&bytes);
999 let decoded = read_node(&mut r, 0).unwrap();
1000 assert_eq!(decoded, left);
1001 }
1002}