1use core::{cmp, fmt, hash};
4
5use bitcoin::taproot::{TAPROOT_CONTROL_BASE_SIZE, TAPROOT_CONTROL_NODE_SIZE};
6use bitcoin::{opcodes, Address, Network, ScriptBuf, Weight};
7use sync::Arc;
8
9use super::checksum;
10use crate::descriptor::DefiniteDescriptorKey;
11use crate::expression::{self, FromTree};
12use crate::miniscript::satisfy::{Placeholder, Satisfaction, SchnorrSigType, Witness};
13use crate::miniscript::Miniscript;
14use crate::plan::AssetProvider;
15use crate::policy::semantic::Policy;
16use crate::policy::Liftable;
17use crate::prelude::*;
18use crate::util::{varint_len, witness_size};
19use crate::{
20 Error, ForEachKey, FromStrKey, MiniscriptKey, ParseError, Satisfier, ScriptContext, Tap,
21 Threshold, ToPublicKey, TranslateErr, Translator,
22};
23
24mod spend_info;
25mod taptree;
26
27pub use self::spend_info::{TrSpendInfo, TrSpendInfoIter, TrSpendInfoIterItem};
28pub use self::taptree::{TapTree, TapTreeDepthError, TapTreeIter, TapTreeIterItem};
29
30pub struct Tr<Pk: MiniscriptKey> {
32 internal_key: Pk,
34 tree: Option<TapTree<Pk>>,
36 spend_info: Mutex<Option<Arc<TrSpendInfo<Pk>>>>,
44}
45
46impl<Pk: MiniscriptKey> Clone for Tr<Pk> {
47 fn clone(&self) -> Self {
48 Self {
52 internal_key: self.internal_key.clone(),
53 tree: self.tree.clone(),
54 spend_info: Mutex::new(
55 self.spend_info
56 .lock()
57 .expect("Lock poisoned")
58 .as_ref()
59 .map(Arc::clone),
60 ),
61 }
62 }
63}
64
65impl<Pk: MiniscriptKey> PartialEq for Tr<Pk> {
66 fn eq(&self, other: &Self) -> bool {
67 self.internal_key == other.internal_key && self.tree == other.tree
68 }
69}
70
71impl<Pk: MiniscriptKey> Eq for Tr<Pk> {}
72
73impl<Pk: MiniscriptKey> PartialOrd for Tr<Pk> {
74 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { Some(self.cmp(other)) }
75}
76
77impl<Pk: MiniscriptKey> Ord for Tr<Pk> {
78 fn cmp(&self, other: &Self) -> cmp::Ordering {
79 match self.internal_key.cmp(&other.internal_key) {
80 cmp::Ordering::Equal => {}
81 ord => return ord,
82 }
83 self.tree.cmp(&other.tree)
84 }
85}
86
87impl<Pk: MiniscriptKey> hash::Hash for Tr<Pk> {
88 fn hash<H: hash::Hasher>(&self, state: &mut H) {
89 self.internal_key.hash(state);
90 self.tree.hash(state);
91 }
92}
93
94impl<Pk: MiniscriptKey> Tr<Pk> {
95 pub fn new(internal_key: Pk, tree: Option<TapTree<Pk>>) -> Result<Self, Error> {
97 Tap::check_pk(&internal_key)?;
98 Ok(Self { internal_key, tree, spend_info: Mutex::new(None) })
99 }
100
101 pub fn internal_key(&self) -> &Pk { &self.internal_key }
103
104 pub fn tap_tree(&self) -> Option<&TapTree<Pk>> { self.tree.as_ref() }
106
107 pub fn leaves(&self) -> TapTreeIter<'_, Pk> {
112 match self.tree {
113 Some(ref t) => t.leaves(),
114 None => TapTreeIter::empty(),
115 }
116 }
117
118 pub fn spend_info(&self) -> Arc<TrSpendInfo<Pk>>
129 where
130 Pk: ToPublicKey,
131 {
132 let mut lock = self.spend_info.lock().unwrap();
133 match *lock {
134 Some(ref res) => Arc::clone(res),
135 None => {
136 let arc = Arc::new(TrSpendInfo::from_tr(self));
137 *lock = Some(Arc::clone(&arc));
138 arc
139 }
140 }
141 }
142
143 pub fn sanity_check(&self) -> Result<(), Error> {
145 for leaf in self.leaves() {
146 leaf.miniscript().sanity_check()?;
147 }
148 Ok(())
149 }
150
151 pub fn max_weight_to_satisfy(&self) -> Result<Weight, Error> {
160 let tree = match self.tap_tree() {
161 None => {
162 let item_sig_size = 1 + 65;
165 let stack_varint_diff = varint_len(1) - varint_len(0);
167
168 return Ok(Weight::from_wu((stack_varint_diff + item_sig_size) as u64));
169 }
170 Some(tree) => tree,
172 };
173
174 let wu = tree
175 .leaves()
176 .filter_map(|leaf| {
177 let script_size = leaf.miniscript().script_size();
178 let max_sat_elems = leaf.miniscript().max_satisfaction_witness_elements().ok()?;
179 let max_sat_size = leaf.miniscript().max_satisfaction_size().ok()?;
180 let control_block_size = control_block_len(leaf.depth());
181
182 let stack_varint_diff = varint_len(max_sat_elems + 1) - varint_len(0);
184
185 Some(
186 stack_varint_diff +
187 max_sat_size +
189 varint_len(script_size) +
191 script_size +
192 varint_len(control_block_size) +
194 control_block_size,
195 )
196 })
197 .max()
198 .ok_or(Error::ImpossibleSatisfaction)?;
199
200 Ok(Weight::from_wu(wu as u64))
201 }
202
203 #[deprecated(
213 since = "10.0.0",
214 note = "Use max_weight_to_satisfy instead. The method to count bytes was redesigned and the results will differ from max_weight_to_satisfy. For more details check rust-bitcoin/rust-miniscript#476."
215 )]
216 pub fn max_satisfaction_weight(&self) -> Result<usize, Error> {
217 let tree = match self.tap_tree() {
218 None => return Ok(4 + 1 + 1 + 65),
221 Some(tree) => tree,
223 };
224
225 tree.leaves()
226 .filter_map(|leaf| {
227 let script_size = leaf.miniscript().script_size();
228 let max_sat_elems = leaf.miniscript().max_satisfaction_witness_elements().ok()?;
229 let max_sat_size = leaf.miniscript().max_satisfaction_size().ok()?;
230 let control_block_size = control_block_len(leaf.depth());
231 Some(
232 4 +
234 varint_len(max_sat_elems + 2) +
236 max_sat_size +
238 varint_len(script_size) +
240 script_size +
241 varint_len(control_block_size) +
243 control_block_size,
244 )
245 })
246 .max()
247 .ok_or(Error::ImpossibleSatisfaction)
248 }
249
250 pub fn translate_pk<T>(
252 &self,
253 translate: &mut T,
254 ) -> Result<Tr<T::TargetPk>, TranslateErr<T::Error>>
255 where
256 T: Translator<Pk>,
257 {
258 let tree = match &self.tree {
259 Some(tree) => Some(tree.translate_pk(translate)?),
260 None => None,
261 };
262 let translate_desc =
263 Tr::new(translate.pk(&self.internal_key)?, tree).map_err(TranslateErr::OuterError)?;
264 Ok(translate_desc)
265 }
266}
267
268impl<Pk: MiniscriptKey + ToPublicKey> Tr<Pk> {
269 pub fn script_pubkey(&self) -> ScriptBuf {
271 let output_key = self.spend_info().output_key();
272 let builder = bitcoin::blockdata::script::Builder::new();
273 builder
274 .push_opcode(opcodes::all::OP_PUSHNUM_1)
275 .push_slice(output_key.serialize())
276 .into_script()
277 }
278
279 pub fn address(&self, network: Network) -> Address {
281 let spend_info = self.spend_info();
282 Address::p2tr_tweaked(spend_info.output_key(), network)
283 }
284
285 pub fn get_satisfaction<S>(&self, satisfier: &S) -> Result<(Vec<Vec<u8>>, ScriptBuf), Error>
289 where
290 S: Satisfier<Pk>,
291 {
292 let satisfaction = best_tap_spend(self, satisfier, false )
293 .try_completing(satisfier)
294 .expect("the same satisfier should manage to complete the template");
295 if let Witness::Stack(stack) = satisfaction.stack {
296 Ok((stack, ScriptBuf::new()))
297 } else {
298 Err(Error::CouldNotSatisfy)
299 }
300 }
301
302 pub fn get_satisfaction_mall<S>(
306 &self,
307 satisfier: &S,
308 ) -> Result<(Vec<Vec<u8>>, ScriptBuf), Error>
309 where
310 S: Satisfier<Pk>,
311 {
312 let satisfaction = best_tap_spend(self, satisfier, true )
313 .try_completing(satisfier)
314 .expect("the same satisfier should manage to complete the template");
315 if let Witness::Stack(stack) = satisfaction.stack {
316 Ok((stack, ScriptBuf::new()))
317 } else {
318 Err(Error::CouldNotSatisfy)
319 }
320 }
321}
322
323impl Tr<DefiniteDescriptorKey> {
324 pub fn plan_satisfaction<P>(
326 &self,
327 provider: &P,
328 ) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
329 where
330 P: AssetProvider<DefiniteDescriptorKey>,
331 {
332 best_tap_spend(self, provider, false )
333 }
334
335 pub fn plan_satisfaction_mall<P>(
337 &self,
338 provider: &P,
339 ) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
340 where
341 P: AssetProvider<DefiniteDescriptorKey>,
342 {
343 best_tap_spend(self, provider, true )
344 }
345}
346
347impl<Pk: FromStrKey> core::str::FromStr for Tr<Pk> {
348 type Err = Error;
349
350 fn from_str(s: &str) -> Result<Self, Self::Err> {
351 let expr_tree = expression::Tree::from_str(s)?;
352 Self::from_tree(expr_tree.root())
353 }
354}
355
356impl<Pk: FromStrKey> crate::expression::FromTree for Tr<Pk> {
357 fn from_tree(root: expression::TreeIterItem) -> Result<Self, Error> {
358 use crate::expression::{Parens, ParseTreeError};
359
360 root.verify_toplevel("tr", 1..=2)
361 .map_err(From::from)
362 .map_err(Error::Parse)?;
363
364 let mut root_children = root.children();
365 let internal_key: Pk = root_children
366 .next()
367 .unwrap() .verify_terminal("internal key")
369 .map_err(Error::Parse)?;
370
371 let tap_tree = match root_children.next() {
372 None => return Tr::new(internal_key, None),
373 Some(tree) => tree,
374 };
375
376 let mut tree_builder = taptree::TapTreeBuilder::new();
377 let mut tap_tree_iter = tap_tree.pre_order_iter();
378 while let Some(node) = tap_tree_iter.next() {
381 if node.parens() == Parens::Curly {
382 if !node.name().is_empty() {
383 return Err(Error::Parse(ParseError::Tree(ParseTreeError::IncorrectName {
384 actual: node.name().to_owned(),
385 expected: "",
386 })));
387 }
388 node.verify_n_children("taptree branch", 2..=2)
389 .map_err(From::from)
390 .map_err(Error::Parse)?;
391 tree_builder.push_inner_node()?;
392 } else {
393 let script = Miniscript::from_tree(node)?;
394 if script.ty.corr.base != crate::miniscript::types::Base::B {
396 return Err(Error::NonTopLevel(format!("{:?}", script)));
397 };
398
399 tree_builder.push_leaf(script);
400 tap_tree_iter.skip_descendants();
401 }
402 }
403 Tr::new(internal_key, Some(tree_builder.finalize()))
404 }
405}
406
407impl<Pk: MiniscriptKey> fmt::Debug for Tr<Pk> {
408 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
409 match self.tree {
410 Some(ref s) => write!(f, "tr({:?},{:?})", self.internal_key, s),
411 None => write!(f, "tr({:?})", self.internal_key),
412 }
413 }
414}
415
416impl<Pk: MiniscriptKey> fmt::Display for Tr<Pk> {
417 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
418 use fmt::Write;
419 let mut wrapped_f = checksum::Formatter::new(f);
420 let key = &self.internal_key;
421 match self.tree {
422 Some(ref s) => write!(wrapped_f, "tr({},{})", key, s)?,
423 None => write!(wrapped_f, "tr({})", key)?,
424 }
425 wrapped_f.write_checksum_if_not_alt()
426 }
427}
428
429impl<Pk: MiniscriptKey> Liftable<Pk> for Tr<Pk> {
430 fn lift(&self) -> Result<Policy<Pk>, Error> {
431 match &self.tree {
432 Some(root) => Ok(Policy::Thresh(Threshold::or(
433 Arc::new(Policy::Key(self.internal_key.clone())),
434 Arc::new(root.lift()?),
435 ))),
436 None => Ok(Policy::Key(self.internal_key.clone())),
437 }
438 }
439}
440
441impl<Pk: MiniscriptKey> ForEachKey<Pk> for Tr<Pk> {
442 fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
443 let script_keys_res = self
444 .leaves()
445 .all(|leaf| leaf.miniscript().for_each_key(&mut pred));
446 script_keys_res && pred(&self.internal_key)
447 }
448}
449
450fn control_block_len(depth: u8) -> usize {
452 TAPROOT_CONTROL_BASE_SIZE + (depth as usize) * TAPROOT_CONTROL_NODE_SIZE
453}
454
455fn best_tap_spend<Pk, P>(
458 desc: &Tr<Pk>,
459 provider: &P,
460 allow_mall: bool,
461) -> Satisfaction<Placeholder<Pk>>
462where
463 Pk: ToPublicKey,
464 P: AssetProvider<Pk>,
465{
466 let spend_info = desc.spend_info();
467 if let Some(size) = provider.provider_lookup_tap_key_spend_sig(&desc.internal_key) {
469 Satisfaction {
470 stack: Witness::Stack(vec![Placeholder::SchnorrSigPk(
471 desc.internal_key.clone(),
472 SchnorrSigType::KeySpend { merkle_root: spend_info.merkle_root() },
473 size,
474 )]),
475 has_sig: true,
476 absolute_timelock: None,
477 relative_timelock: None,
478 }
479 } else {
480 let mut min_satisfaction = Satisfaction {
483 stack: Witness::Unavailable,
484 has_sig: false,
485 relative_timelock: None,
486 absolute_timelock: None,
487 };
488 let mut min_wit_len = None;
489 for leaf in spend_info.leaves() {
490 let mut satisfaction = if allow_mall {
491 match leaf.miniscript().build_template_mall(provider) {
492 s @ Satisfaction { stack: Witness::Stack(_), .. } => s,
493 _ => continue, }
495 } else {
496 match leaf.miniscript().build_template(provider) {
497 s @ Satisfaction { stack: Witness::Stack(_), .. } => s,
498 _ => continue, }
500 };
501 let wit = match satisfaction {
502 Satisfaction { stack: Witness::Stack(ref mut wit), .. } => wit,
503 _ => unreachable!(),
504 };
505
506 let script = ScriptBuf::from(leaf.script());
507 let control_block = leaf.control_block().clone();
508
509 wit.push(Placeholder::TapScript(script));
510 wit.push(Placeholder::TapControlBlock(control_block));
511
512 let wit_size = witness_size(wit);
513 if min_wit_len.is_some() && Some(wit_size) > min_wit_len {
514 continue;
515 } else {
516 min_satisfaction = satisfaction;
517 min_wit_len = Some(wit_size);
518 }
519 }
520
521 min_satisfaction
522 }
523}
524
525#[cfg(test)]
526mod tests {
527 use core::str::FromStr;
528
529 use super::*;
530
531 fn descriptor() -> String {
532 let desc = "tr(acc0, {
533 multi_a(3, acc10, acc11, acc12), {
534 and_v(
535 v:multi_a(2, acc10, acc11, acc12),
536 after(10)
537 ),
538 and_v(
539 v:multi_a(1, acc10, acc11, ac12),
540 after(100)
541 )
542 }
543 })";
544 desc.replace(&[' ', '\n'][..], "")
545 }
546
547 #[test]
548 fn for_each() {
549 let desc = descriptor();
550 let tr = Tr::<String>::from_str(&desc).unwrap();
551 assert!(!tr.for_each_key(|k| k.starts_with("acc")));
553 }
554
555 #[test]
556 fn tr_maximum_depth() {
557 let descriptor128 = "tr(X!,{pk(X1!),{pk(X2!),{pk(X3!),{pk(X4!),{pk(X5!),{pk(X6!),{pk(X7!),{pk(X8!),{pk(X9!),{pk(X10!),{pk(X11!),{pk(X12!),{pk(X13!),{pk(X14!),{pk(X15!),{pk(X16!),{pk(X17!),{pk(X18!),{pk(X19!),{pk(X20!),{pk(X21!),{pk(X22!),{pk(X23!),{pk(X24!),{pk(X25!),{pk(X26!),{pk(X27!),{pk(X28!),{pk(X29!),{pk(X30!),{pk(X31!),{pk(X32!),{pk(X33!),{pk(X34!),{pk(X35!),{pk(X36!),{pk(X37!),{pk(X38!),{pk(X39!),{pk(X40!),{pk(X41!),{pk(X42!),{pk(X43!),{pk(X44!),{pk(X45!),{pk(X46!),{pk(X47!),{pk(X48!),{pk(X49!),{pk(X50!),{pk(X51!),{pk(X52!),{pk(X53!),{pk(X54!),{pk(X55!),{pk(X56!),{pk(X57!),{pk(X58!),{pk(X59!),{pk(X60!),{pk(X61!),{pk(X62!),{pk(X63!),{pk(X64!),{pk(X65!),{pk(X66!),{pk(X67!),{pk(X68!),{pk(X69!),{pk(X70!),{pk(X71!),{pk(X72!),{pk(X73!),{pk(X74!),{pk(X75!),{pk(X76!),{pk(X77!),{pk(X78!),{pk(X79!),{pk(X80!),{pk(X81!),{pk(X82!),{pk(X83!),{pk(X84!),{pk(X85!),{pk(X86!),{pk(X87!),{pk(X88!),{pk(X89!),{pk(X90!),{pk(X91!),{pk(X92!),{pk(X93!),{pk(X94!),{pk(X95!),{pk(X96!),{pk(X97!),{pk(X98!),{pk(X99!),{pk(X100!),{pk(X101!),{pk(X102!),{pk(X103!),{pk(X104!),{pk(X105!),{pk(X106!),{pk(X107!),{pk(X108!),{pk(X109!),{pk(X110!),{pk(X111!),{pk(X112!),{pk(X113!),{pk(X114!),{pk(X115!),{pk(X116!),{pk(X117!),{pk(X118!),{pk(X119!),{pk(X120!),{pk(X121!),{pk(X122!),{pk(X123!),{pk(X124!),{pk(X125!),{pk(X126!),{pk(X127!),{pk(X128!),pk(X129)}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}})";
559 descriptor128.parse::<crate::Descriptor<String>>().unwrap();
560
561 let descriptor129 = "tr(X!,{pk(X1!),{pk(X2!),{pk(X3!),{pk(X4!),{pk(X5!),{pk(X6!),{pk(X7!),{pk(X8!),{pk(X9!),{pk(X10!),{pk(X11!),{pk(X12!),{pk(X13!),{pk(X14!),{pk(X15!),{pk(X16!),{pk(X17!),{pk(X18!),{pk(X19!),{pk(X20!),{pk(X21!),{pk(X22!),{pk(X23!),{pk(X24!),{pk(X25!),{pk(X26!),{pk(X27!),{pk(X28!),{pk(X29!),{pk(X30!),{pk(X31!),{pk(X32!),{pk(X33!),{pk(X34!),{pk(X35!),{pk(X36!),{pk(X37!),{pk(X38!),{pk(X39!),{pk(X40!),{pk(X41!),{pk(X42!),{pk(X43!),{pk(X44!),{pk(X45!),{pk(X46!),{pk(X47!),{pk(X48!),{pk(X49!),{pk(X50!),{pk(X51!),{pk(X52!),{pk(X53!),{pk(X54!),{pk(X55!),{pk(X56!),{pk(X57!),{pk(X58!),{pk(X59!),{pk(X60!),{pk(X61!),{pk(X62!),{pk(X63!),{pk(X64!),{pk(X65!),{pk(X66!),{pk(X67!),{pk(X68!),{pk(X69!),{pk(X70!),{pk(X71!),{pk(X72!),{pk(X73!),{pk(X74!),{pk(X75!),{pk(X76!),{pk(X77!),{pk(X78!),{pk(X79!),{pk(X80!),{pk(X81!),{pk(X82!),{pk(X83!),{pk(X84!),{pk(X85!),{pk(X86!),{pk(X87!),{pk(X88!),{pk(X89!),{pk(X90!),{pk(X91!),{pk(X92!),{pk(X93!),{pk(X94!),{pk(X95!),{pk(X96!),{pk(X97!),{pk(X98!),{pk(X99!),{pk(X100!),{pk(X101!),{pk(X102!),{pk(X103!),{pk(X104!),{pk(X105!),{pk(X106!),{pk(X107!),{pk(X108!),{pk(X109!),{pk(X110!),{pk(X111!),{pk(X112!),{pk(X113!),{pk(X114!),{pk(X115!),{pk(X116!),{pk(X117!),{pk(X118!),{pk(X119!),{pk(X120!),{pk(X121!),{pk(X122!),{pk(X123!),{pk(X124!),{pk(X125!),{pk(X126!),{pk(X127!),{pk(X128!),{pk(X129),pk(X130)}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}})";
563 assert!(matches!(
564 descriptor129
565 .parse::<crate::Descriptor::<String>>()
566 .unwrap_err(),
567 crate::Error::TapTreeDepthError(TapTreeDepthError),
568 ));
569 }
570}