1use core::cmp::{self, max};
3use core::str::FromStr;
4use core::{fmt, hash};
5
6use bitcoin::blockdata::opcodes;
7use bitcoin::util::taproot::{
8 LeafVersion, TaprootBuilder, TaprootSpendInfo, TAPROOT_CONTROL_BASE_SIZE,
9 TAPROOT_CONTROL_MAX_NODE_COUNT, TAPROOT_CONTROL_NODE_SIZE,
10};
11use bitcoin::{secp256k1, Address, Network, Script};
12use sync::Arc;
13
14use super::checksum::{self, verify_checksum};
15use crate::expression::{self, FromTree};
16use crate::miniscript::Miniscript;
17use crate::policy::semantic::Policy;
18use crate::policy::Liftable;
19use crate::prelude::*;
20use crate::util::{varint_len, witness_size};
21use crate::{
22 errstr, Error, ForEachKey, MiniscriptKey, Satisfier, Tap, ToPublicKey, TranslatePk, Translator,
23};
24
25#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
29pub enum TapTree<Pk: MiniscriptKey> {
30 Tree(Arc<TapTree<Pk>>, Arc<TapTree<Pk>>),
32 Leaf(Arc<Miniscript<Pk, Tap>>),
37}
38
39pub struct Tr<Pk: MiniscriptKey> {
41 internal_key: Pk,
43 tree: Option<TapTree<Pk>>,
45 spend_info: Mutex<Option<Arc<TaprootSpendInfo>>>,
53}
54
55impl<Pk: MiniscriptKey> Clone for Tr<Pk> {
56 fn clone(&self) -> Self {
57 Self {
61 internal_key: self.internal_key.clone(),
62 tree: self.tree.clone(),
63 spend_info: Mutex::new(
64 self.spend_info
65 .lock()
66 .expect("Lock poisoned")
67 .as_ref()
68 .map(Arc::clone),
69 ),
70 }
71 }
72}
73
74impl<Pk: MiniscriptKey> PartialEq for Tr<Pk> {
75 fn eq(&self, other: &Self) -> bool {
76 self.internal_key == other.internal_key && self.tree == other.tree
77 }
78}
79
80impl<Pk: MiniscriptKey> Eq for Tr<Pk> {}
81
82impl<Pk: MiniscriptKey> PartialOrd for Tr<Pk> {
83 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
84 match self.internal_key.partial_cmp(&other.internal_key) {
85 Some(cmp::Ordering::Equal) => {}
86 ord => return ord,
87 }
88 self.tree.partial_cmp(&other.tree)
89 }
90}
91
92impl<Pk: MiniscriptKey> Ord for Tr<Pk> {
93 fn cmp(&self, other: &Self) -> cmp::Ordering {
94 match self.internal_key.cmp(&other.internal_key) {
95 cmp::Ordering::Equal => {}
96 ord => return ord,
97 }
98 self.tree.cmp(&other.tree)
99 }
100}
101
102impl<Pk: MiniscriptKey> hash::Hash for Tr<Pk> {
103 fn hash<H: hash::Hasher>(&self, state: &mut H) {
104 self.internal_key.hash(state);
105 self.tree.hash(state);
106 }
107}
108
109impl<Pk: MiniscriptKey> TapTree<Pk> {
110 fn taptree_height(&self) -> usize {
114 match *self {
115 TapTree::Tree(ref left_tree, ref right_tree) => {
116 1 + max(left_tree.taptree_height(), right_tree.taptree_height())
117 }
118 TapTree::Leaf(..) => 0,
119 }
120 }
121
122 pub fn iter(&self) -> TapTreeIter<Pk> {
124 TapTreeIter {
125 stack: vec![(0, self)],
126 }
127 }
128
129 fn translate_helper<T, Q, Error>(&self, t: &mut T) -> Result<TapTree<Q>, Error>
131 where
132 T: Translator<Pk, Q, Error>,
133 Q: MiniscriptKey,
134 {
135 let frag = match self {
136 TapTree::Tree(l, r) => TapTree::Tree(
137 Arc::new(l.translate_helper(t)?),
138 Arc::new(r.translate_helper(t)?),
139 ),
140 TapTree::Leaf(ms) => TapTree::Leaf(Arc::new(ms.translate_pk(t)?)),
141 };
142 Ok(frag)
143 }
144}
145
146impl<Pk: MiniscriptKey> fmt::Display for TapTree<Pk> {
147 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
148 match self {
149 TapTree::Tree(ref left, ref right) => write!(f, "{{{},{}}}", *left, *right),
150 TapTree::Leaf(ref script) => write!(f, "{}", *script),
151 }
152 }
153}
154
155impl<Pk: MiniscriptKey> fmt::Debug for TapTree<Pk> {
156 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157 match self {
158 TapTree::Tree(ref left, ref right) => write!(f, "{{{:?},{:?}}}", *left, *right),
159 TapTree::Leaf(ref script) => write!(f, "{:?}", *script),
160 }
161 }
162}
163
164impl<Pk: MiniscriptKey> Tr<Pk> {
165 pub fn new(internal_key: Pk, tree: Option<TapTree<Pk>>) -> Result<Self, Error> {
167 let nodes = tree.as_ref().map(|t| t.taptree_height()).unwrap_or(0);
168
169 if nodes <= TAPROOT_CONTROL_MAX_NODE_COUNT {
170 Ok(Self {
171 internal_key,
172 tree,
173 spend_info: Mutex::new(None),
174 })
175 } else {
176 Err(Error::MaxRecursiveDepthExceeded)
177 }
178 }
179
180 pub fn internal_key(&self) -> &Pk {
182 &self.internal_key
183 }
184
185 pub fn taptree(&self) -> &Option<TapTree<Pk>> {
187 &self.tree
188 }
189
190 pub fn iter_scripts(&self) -> TapTreeIter<Pk> {
193 match self.tree {
194 Some(ref t) => t.iter(),
195 None => TapTreeIter { stack: vec![] },
196 }
197 }
198
199 pub fn spend_info(&self) -> Arc<TaprootSpendInfo>
205 where
206 Pk: ToPublicKey,
207 {
208 let read_lock = self.spend_info.lock().expect("Lock poisoned");
211 if let Some(ref spend_info) = *read_lock {
212 return Arc::clone(spend_info);
213 }
214 drop(read_lock);
215
216 let secp = secp256k1::Secp256k1::verification_only();
219 let data = if self.tree.is_none() {
221 TaprootSpendInfo::new_key_spend(&secp, self.internal_key.to_x_only_pubkey(), None)
222 } else {
223 let mut builder = TaprootBuilder::new();
224 for (depth, ms) in self.iter_scripts() {
225 let script = ms.encode();
226 builder = builder
227 .add_leaf(depth, script)
228 .expect("Computing spend data on a valid Tree should always succeed");
229 }
230 match builder.finalize(&secp, self.internal_key.to_x_only_pubkey()) {
232 Ok(data) => data,
233 Err(_) => unreachable!("We know the builder can be finalized"),
234 }
235 };
236 let spend_info = Arc::new(data);
237 *self.spend_info.lock().expect("Lock poisoned") = Some(Arc::clone(&spend_info));
238 spend_info
239 }
240
241 pub fn sanity_check(&self) -> Result<(), Error> {
243 for (_depth, ms) in self.iter_scripts() {
244 ms.sanity_check()?;
245 }
246 Ok(())
247 }
248
249 pub fn max_satisfaction_weight(&self) -> Result<usize, Error> {
259 let tree = match self.taptree() {
260 None => return Ok(4 + 1 + 1 + 65),
263 Some(tree) => tree,
265 };
266
267 tree.iter()
268 .filter_map(|(depth, ms)| {
269 let script_size = ms.script_size();
270 let max_sat_elems = ms.max_satisfaction_witness_elements().ok()?;
271 let max_sat_size = ms.max_satisfaction_size().ok()?;
272 let control_block_size = control_block_len(depth);
273 Some(
274 4 +
276 varint_len(max_sat_elems + 2) +
278 max_sat_size +
280 varint_len(script_size) +
282 script_size +
283 varint_len(control_block_size) +
285 control_block_size,
286 )
287 })
288 .max()
289 .ok_or(Error::ImpossibleSatisfaction)
290 }
291}
292
293impl<Pk: MiniscriptKey + ToPublicKey> Tr<Pk> {
294 pub fn script_pubkey(&self) -> Script {
296 let output_key = self.spend_info().output_key();
297 let builder = bitcoin::blockdata::script::Builder::new();
298 builder
299 .push_opcode(opcodes::all::OP_PUSHNUM_1)
300 .push_slice(&output_key.serialize())
301 .into_script()
302 }
303
304 pub fn address(&self, network: Network) -> Address {
306 let spend_info = self.spend_info();
307 Address::p2tr_tweaked(spend_info.output_key(), network)
308 }
309
310 pub fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
314 where
315 S: Satisfier<Pk>,
316 {
317 best_tap_spend(self, satisfier, false )
318 }
319
320 pub fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
324 where
325 S: Satisfier<Pk>,
326 {
327 best_tap_spend(self, satisfier, true )
328 }
329}
330
331#[derive(Debug, Clone)]
344pub struct TapTreeIter<'a, Pk: MiniscriptKey> {
345 stack: Vec<(u8, &'a TapTree<Pk>)>,
346}
347
348impl<'a, Pk> Iterator for TapTreeIter<'a, Pk>
349where
350 Pk: MiniscriptKey + 'a,
351{
352 type Item = (u8, &'a Miniscript<Pk, Tap>);
353
354 fn next(&mut self) -> Option<Self::Item> {
355 while !self.stack.is_empty() {
356 let (depth, last) = self.stack.pop().expect("Size checked above");
357 match &*last {
358 TapTree::Tree(l, r) => {
359 self.stack.push((depth + 1, r));
360 self.stack.push((depth + 1, l));
361 }
362 TapTree::Leaf(ref ms) => return Some((depth, ms)),
363 }
364 }
365 None
366 }
367}
368
369#[rustfmt::skip]
370impl_block_str!(
371 Tr<Pk>,
372 fn parse_tr_script_spend(tree: &expression::Tree,) -> Result<TapTree<Pk>, Error> {
374 match tree {
375 expression::Tree { name, args } if !name.is_empty() && args.is_empty() => {
376 let script = Miniscript::<Pk, Tap>::from_str(name)?;
377 Ok(TapTree::Leaf(Arc::new(script)))
378 }
379 expression::Tree { name, args } if name.is_empty() && args.len() == 2 => {
380 let left = Self::parse_tr_script_spend(&args[0])?;
381 let right = Self::parse_tr_script_spend(&args[1])?;
382 Ok(TapTree::Tree(Arc::new(left), Arc::new(right)))
383 }
384 _ => Err(Error::Unexpected(
385 "unknown format for script spending paths while parsing taproot descriptor"
386 .to_string(),
387 )),
388 }
389 }
390);
391
392impl_from_tree!(
393 Tr<Pk>,
394 fn from_tree(top: &expression::Tree) -> Result<Self, Error> {
395 if top.name == "tr" {
396 match top.args.len() {
397 1 => {
398 let key = &top.args[0];
399 if !key.args.is_empty() {
400 return Err(Error::Unexpected(format!(
401 "#{} script associated with `key-path` while parsing taproot descriptor",
402 key.args.len()
403 )));
404 }
405 Tr::new(expression::terminal(key, Pk::from_str)?, None)
406 }
407 2 => {
408 let key = &top.args[0];
409 if !key.args.is_empty() {
410 return Err(Error::Unexpected(format!(
411 "#{} script associated with `key-path` while parsing taproot descriptor",
412 key.args.len()
413 )));
414 }
415 let tree = &top.args[1];
416 let ret = Self::parse_tr_script_spend(tree)?;
417 Tr::new(expression::terminal(key, Pk::from_str)?, Some(ret))
418 }
419 _ => {
420 return Err(Error::Unexpected(format!(
421 "{}[#{} args] while parsing taproot descriptor",
422 top.name,
423 top.args.len()
424 )));
425 }
426 }
427 } else {
428 return Err(Error::Unexpected(format!(
429 "{}[#{} args] while parsing taproot descriptor",
430 top.name,
431 top.args.len()
432 )));
433 }
434 }
435);
436
437impl_from_str!(
438 Tr<Pk>,
439 type Err = Error;,
440 fn from_str(s: &str) -> Result<Self, Self::Err> {
441 let desc_str = verify_checksum(s)?;
442 let top = parse_tr_tree(desc_str)?;
443 Self::from_tree(&top)
444 }
445);
446
447impl<Pk: MiniscriptKey> fmt::Debug for Tr<Pk> {
448 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
449 match self.tree {
450 Some(ref s) => write!(f, "tr({:?},{:?})", self.internal_key, s),
451 None => write!(f, "tr({:?})", self.internal_key),
452 }
453 }
454}
455
456impl<Pk: MiniscriptKey> fmt::Display for Tr<Pk> {
457 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
458 use fmt::Write;
459 let mut wrapped_f = checksum::Formatter::new(f);
460 let key = &self.internal_key;
461 match self.tree {
462 Some(ref s) => write!(wrapped_f, "tr({},{})", key, s)?,
463 None => write!(wrapped_f, "tr({})", key)?,
464 }
465 wrapped_f.write_checksum_if_not_alt()
466 }
467}
468
469fn parse_tr_tree(s: &str) -> Result<expression::Tree, Error> {
471 for ch in s.bytes() {
472 if !ch.is_ascii() {
473 return Err(Error::Unprintable(ch));
474 }
475 }
476
477 if s.len() > 3 && &s[..3] == "tr(" && s.as_bytes()[s.len() - 1] == b')' {
478 let rest = &s[3..s.len() - 1];
479 if !rest.contains(',') {
480 let internal_key = expression::Tree {
481 name: rest,
482 args: vec![],
483 };
484 return Ok(expression::Tree {
485 name: "tr",
486 args: vec![internal_key],
487 });
488 }
489 let (key, script) = split_once(rest, ',')
491 .ok_or_else(|| Error::BadDescriptor("invalid taproot descriptor".to_string()))?;
492
493 let internal_key = expression::Tree {
494 name: key,
495 args: vec![],
496 };
497 if script.is_empty() {
498 return Ok(expression::Tree {
499 name: "tr",
500 args: vec![internal_key],
501 });
502 }
503 let (tree, rest) = expression::Tree::from_slice_delim(script, 1, '{')?;
504 if rest.is_empty() {
505 Ok(expression::Tree {
506 name: "tr",
507 args: vec![internal_key, tree],
508 })
509 } else {
510 Err(errstr(rest))
511 }
512 } else {
513 Err(Error::Unexpected("invalid taproot descriptor".to_string()))
514 }
515}
516
517fn split_once(inp: &str, delim: char) -> Option<(&str, &str)> {
518 if inp.is_empty() {
519 None
520 } else {
521 let mut found = inp.len();
522 for (idx, ch) in inp.chars().enumerate() {
523 if ch == delim {
524 found = idx;
525 break;
526 }
527 }
528 if found >= inp.len() - 1 {
530 Some((inp, ""))
531 } else {
532 Some((&inp[..found], &inp[found + 1..]))
533 }
534 }
535}
536
537impl<Pk: MiniscriptKey> Liftable<Pk> for TapTree<Pk> {
538 fn lift(&self) -> Result<Policy<Pk>, Error> {
539 fn lift_helper<Pk: MiniscriptKey>(s: &TapTree<Pk>) -> Result<Policy<Pk>, Error> {
540 match s {
541 TapTree::Tree(ref l, ref r) => {
542 Ok(Policy::Threshold(1, vec![lift_helper(l)?, lift_helper(r)?]))
543 }
544 TapTree::Leaf(ref leaf) => leaf.lift(),
545 }
546 }
547
548 let pol = lift_helper(self)?;
549 Ok(pol.normalized())
550 }
551}
552
553impl<Pk: MiniscriptKey> Liftable<Pk> for Tr<Pk> {
554 fn lift(&self) -> Result<Policy<Pk>, Error> {
555 match &self.tree {
556 Some(root) => Ok(Policy::Threshold(
557 1,
558 vec![Policy::Key(self.internal_key.clone()), root.lift()?],
559 )),
560 None => Ok(Policy::Key(self.internal_key.clone())),
561 }
562 }
563}
564
565impl<Pk: MiniscriptKey> ForEachKey<Pk> for Tr<Pk> {
566 fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
567 where
568 Pk: 'a,
569 {
570 let script_keys_res = self
571 .iter_scripts()
572 .all(|(_d, ms)| ms.for_each_key(&mut pred));
573 script_keys_res && pred(&self.internal_key)
574 }
575}
576
577impl<P, Q> TranslatePk<P, Q> for Tr<P>
578where
579 P: MiniscriptKey,
580 Q: MiniscriptKey,
581{
582 type Output = Tr<Q>;
583
584 fn translate_pk<T, E>(&self, translate: &mut T) -> Result<Self::Output, E>
585 where
586 T: Translator<P, Q, E>,
587 {
588 let translate_desc = Tr {
589 internal_key: translate.pk(&self.internal_key)?,
590 tree: match &self.tree {
591 Some(tree) => Some(tree.translate_helper(translate)?),
592 None => None,
593 },
594 spend_info: Mutex::new(None),
595 };
596 Ok(translate_desc)
597 }
598}
599
600fn control_block_len(depth: u8) -> usize {
602 TAPROOT_CONTROL_BASE_SIZE + (depth as usize) * TAPROOT_CONTROL_NODE_SIZE
603}
604
605fn best_tap_spend<Pk, S>(
608 desc: &Tr<Pk>,
609 satisfier: S,
610 allow_mall: bool,
611) -> Result<(Vec<Vec<u8>>, Script), Error>
612where
613 Pk: ToPublicKey,
614 S: Satisfier<Pk>,
615{
616 let spend_info = desc.spend_info();
617 if let Some(sig) = satisfier.lookup_tap_key_spend_sig() {
619 Ok((vec![sig.to_vec()], Script::new()))
620 } else {
621 let (mut min_wit, mut min_wit_len) = (None, None);
624 for (depth, ms) in desc.iter_scripts() {
625 let mut wit = if allow_mall {
626 match ms.satisfy_malleable(&satisfier) {
627 Ok(wit) => wit,
628 Err(..) => continue, }
630 } else {
631 match ms.satisfy(&satisfier) {
632 Ok(wit) => wit,
633 Err(..) => continue, }
635 };
636 let wit_size = witness_size(&wit)
640 + control_block_len(depth)
641 + ms.script_size()
642 + varint_len(ms.script_size());
643 if min_wit_len.is_some() && Some(wit_size) > min_wit_len {
644 continue;
645 } else {
646 let leaf_script = (ms.encode(), LeafVersion::TapScript);
647 let control_block = spend_info
648 .control_block(&leaf_script)
649 .expect("Control block must exist in script map for every known leaf");
650 wit.push(leaf_script.0.into_bytes()); wit.push(control_block.serialize());
654 min_wit = Some(wit);
656 min_wit_len = Some(wit_size);
657 }
658 }
659 match min_wit {
660 Some(wit) => Ok((wit, Script::new())),
661 None => Err(Error::CouldNotSatisfy), }
663 }
664}
665
666#[cfg(test)]
667mod tests {
668 use super::*;
669 use crate::ForEachKey;
670
671 #[test]
672 fn test_for_each() {
673 let desc = "tr(acc0, {
674 multi_a(3, acc10, acc11, acc12), {
675 and_v(
676 v:multi_a(2, acc10, acc11, acc12),
677 after(10)
678 ),
679 and_v(
680 v:multi_a(1, acc10, acc11, ac12),
681 after(100)
682 )
683 }
684 })";
685 let desc = desc.replace(&[' ', '\n'][..], "");
686 let tr = Tr::<String>::from_str(&desc).unwrap();
687 assert!(!tr.for_each_key(|k| k.starts_with("acc")));
689 }
690}