Skip to content

Commit 899269a

Browse files
committed
tr: Add Simplicity leaf to TapTree
Extends the tap iterator to handle both kinds of leaves. The iterator returns an enum that has to be split into either variant as required. For now all methods assume Miniscript and will panic if Simplicity is encountered. We will add Simplicity support to these methods in the next commits.
1 parent 3e7440d commit 899269a

File tree

2 files changed

+73
-8
lines changed

2 files changed

+73
-8
lines changed

src/descriptor/tr.rs

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ pub enum TapTree<Pk: MiniscriptKey, Ext: Extension = NoExt> {
3636
// in adding a LeafVersion with Leaf type here. All Miniscripts right now
3737
// are of Leafversion::default
3838
Leaf(Arc<Miniscript<Pk, Tap, Ext>>),
39+
/// A taproot leaf denoting a spending condition in terms of Simplicity
40+
SimplicityLeaf(Arc<simplicity::Policy<Pk>>),
3941
}
4042

4143
/// A taproot descriptor
@@ -117,7 +119,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> TapTree<Pk, Ext> {
117119
TapTree::Tree(ref left_tree, ref right_tree) => {
118120
1 + max(left_tree.taptree_height(), right_tree.taptree_height())
119121
}
120-
TapTree::Leaf(..) => 0,
122+
TapTree::Leaf(..) | TapTree::SimplicityLeaf(..) => 0,
121123
}
122124
}
123125

@@ -136,12 +138,30 @@ impl<Pk: MiniscriptKey, Ext: Extension> TapTree<Pk, Ext> {
136138
Q: MiniscriptKey,
137139
Ext: Extension,
138140
{
141+
struct SimTranslator<'a, T>(&'a mut T);
142+
143+
impl<'a, Pk, T, Q, Error> simplicity::Translator<Pk, Q, Error> for SimTranslator<'a, T>
144+
where
145+
Pk: MiniscriptKey,
146+
T: Translator<Pk, Q, Error>,
147+
Q: MiniscriptKey,
148+
{
149+
fn pk(&mut self, pk: &Pk) -> Result<Q, Error> {
150+
self.0.pk(pk)
151+
}
152+
153+
fn sha256(&mut self, sha256: &Pk::Sha256) -> Result<Q::Sha256, Error> {
154+
self.0.sha256(sha256)
155+
}
156+
}
157+
139158
let frag = match self {
140159
TapTree::Tree(l, r) => TapTree::Tree(
141160
Arc::new(l.translate_helper(t)?),
142161
Arc::new(r.translate_helper(t)?),
143162
),
144163
TapTree::Leaf(ms) => TapTree::Leaf(Arc::new(ms.translate_pk(t)?)),
164+
TapTree::SimplicityLeaf(sim) => TapTree::SimplicityLeaf(Arc::new(sim.translate(&mut SimTranslator(t))?))
145165
};
146166
Ok(frag)
147167
}
@@ -159,6 +179,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> TapTree<Pk, Ext> {
159179
Arc::new(r.translate_ext_helper(t)?),
160180
),
161181
TapTree::Leaf(ms) => TapTree::Leaf(Arc::new(ms.translate_ext(t)?)),
182+
TapTree::SimplicityLeaf(sim) => TapTree::SimplicityLeaf(Arc::clone(sim)),
162183
};
163184
Ok(frag)
164185
}
@@ -169,6 +190,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> fmt::Display for TapTree<Pk, Ext> {
169190
match self {
170191
TapTree::Tree(ref left, ref right) => write!(f, "{{{},{}}}", *left, *right),
171192
TapTree::Leaf(ref script) => write!(f, "{}", *script),
193+
TapTree::SimplicityLeaf(ref policy) => write!(f, "{}", policy),
172194
}
173195
}
174196
}
@@ -178,6 +200,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> fmt::Debug for TapTree<Pk, Ext> {
178200
match self {
179201
TapTree::Tree(ref left, ref right) => write!(f, "{{{:?},{:?}}}", *left, *right),
180202
TapTree::Leaf(ref script) => write!(f, "{:?}", *script),
203+
TapTree::SimplicityLeaf(ref policy) => write!(f, "{:?}", policy),
181204
}
182205
}
183206
}
@@ -244,7 +267,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> Tr<Pk, Ext> {
244267
} else {
245268
let mut builder = TaprootBuilder::new();
246269
for (depth, ms) in self.iter_scripts() {
247-
let script = ms.encode();
270+
let script = ms.as_miniscript().unwrap().encode();
248271
builder = builder
249272
.add_leaf(depth, script)
250273
.expect("Computing spend data on a valid Tree should always succeed");
@@ -263,7 +286,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> Tr<Pk, Ext> {
263286
/// Checks whether the descriptor is safe.
264287
pub fn sanity_check(&self) -> Result<(), Error> {
265288
for (_depth, ms) in self.iter_scripts() {
266-
ms.sanity_check()?;
289+
ms.as_miniscript().unwrap().sanity_check()?;
267290
}
268291
Ok(())
269292
}
@@ -293,6 +316,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> Tr<Pk, Ext> {
293316

294317
tree.iter()
295318
.filter_map(|(depth, ms)| {
319+
let ms = ms.as_miniscript().unwrap();
296320
let script_size = ms.script_size();
297321
let max_sat_elems = ms.max_satisfaction_witness_elements().ok()?;
298322
let max_sat_size = ms.max_satisfaction_size().ok()?;
@@ -338,6 +362,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> Tr<Pk, Ext> {
338362

339363
tree.iter()
340364
.filter_map(|(depth, ms)| {
365+
let ms = ms.as_miniscript().unwrap();
341366
let script_size = ms.script_size();
342367
let max_sat_elems = ms.max_satisfaction_witness_elements().ok()?;
343368
let max_sat_size = ms.max_satisfaction_size().ok()?;
@@ -404,8 +429,38 @@ impl<Pk: MiniscriptKey + ToPublicKey, Ext: ParseableExt> Tr<Pk, Ext> {
404429
}
405430
}
406431

407-
/// Iterator for Taproot structures
408-
/// Yields a pair of (depth, miniscript) in a depth first walk
432+
/// Script at a tap leaf.
433+
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
434+
pub enum TapLeafScript<'a, Pk: MiniscriptKey, Ext: Extension> {
435+
/// Miniscript leaf
436+
Miniscript(&'a Miniscript<Pk, Tap, Ext>),
437+
/// Simplicity leaf
438+
Simplicity(&'a simplicity::Policy<Pk>)
439+
}
440+
441+
impl<'a, Pk: MiniscriptKey, Ext: Extension> TapLeafScript<'a, Pk, Ext> {
442+
/// Get the Miniscript at the leaf, if it exists.
443+
pub fn as_miniscript(&self) -> Option<&'a Miniscript<Pk, Tap, Ext>> {
444+
match self {
445+
TapLeafScript::Miniscript(ms) => Some(ms),
446+
_ => None,
447+
}
448+
}
449+
450+
/// Get the Simplicity policy at the leaf, if it exists.
451+
pub fn as_simplicity(&self) -> Option<&'a simplicity::Policy<Pk>> {
452+
match self {
453+
TapLeafScript::Simplicity(sim) => Some(sim),
454+
_ => None,
455+
}
456+
}
457+
}
458+
459+
/// Iterator over the leaves of a tap tree.
460+
///
461+
/// Each leaf consists is a pair of (depth, script).
462+
/// The leaves are yielded in a depth-first walk.
463+
///
409464
/// For example, this tree:
410465
/// - N0 -
411466
/// / \\
@@ -426,7 +481,7 @@ where
426481
Pk: MiniscriptKey + 'a,
427482
Ext: Extension,
428483
{
429-
type Item = (usize, &'a Miniscript<Pk, Tap, Ext>);
484+
type Item = (usize, TapLeafScript<'a, Pk, Ext>);
430485

431486
fn next(&mut self) -> Option<Self::Item> {
432487
while let Some((depth, last)) = self.stack.pop() {
@@ -435,7 +490,12 @@ where
435490
self.stack.push((depth + 1, r));
436491
self.stack.push((depth + 1, l));
437492
}
438-
TapTree::Leaf(ref ms) => return Some((depth, ms)),
493+
TapTree::Leaf(ref ms) => {
494+
return Some((depth, TapLeafScript::Miniscript(ms)))
495+
},
496+
TapTree::SimplicityLeaf(ref sim) => {
497+
return Some((depth, TapLeafScript::Simplicity(sim)))
498+
}
439499
}
440500
}
441501
None
@@ -623,6 +683,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> Liftable<Pk> for TapTree<Pk, Ext> {
623683
Ok(Policy::Threshold(1, vec![lift_helper(l)?, lift_helper(r)?]))
624684
}
625685
TapTree::Leaf(ref leaf) => leaf.lift(),
686+
TapTree::SimplicityLeaf(..) => panic!("Cannot lift Simplicity policy to Miniscript semantic policy"),
626687
}
627688
}
628689

@@ -650,7 +711,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> ForEachKey<Pk> for Tr<Pk, Ext> {
650711
{
651712
let script_keys_res = self
652713
.iter_scripts()
653-
.all(|(_d, ms)| ms.for_each_key(&mut pred));
714+
.all(|(_d, ms)| ms.as_miniscript().unwrap().for_each_key(&mut pred));
654715
script_keys_res && pred(&self.internal_key)
655716
}
656717
}
@@ -729,6 +790,7 @@ where
729790
// map (lookup_control_block) from the satisfier here.
730791
let (mut min_wit, mut min_wit_len) = (None, None);
731792
for (depth, ms) in desc.iter_scripts() {
793+
let ms = ms.as_miniscript().unwrap();
732794
let mut wit = if allow_mall {
733795
match ms.satisfy_malleable(&satisfier) {
734796
Ok(wit) => wit,

src/psbt/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,9 @@ where
12901290
tr_derived.iter_scripts().zip(tr_xpk.iter_scripts())
12911291
{
12921292
debug_assert_eq!(_depth_der, depth);
1293+
let ms_derived = ms_derived.as_miniscript().unwrap();
1294+
let ms = ms.as_miniscript().unwrap();
1295+
12931296
let leaf_script = (ms_derived.encode(), LeafVersion::default());
12941297
let tapleaf_hash = TapLeafHash::from_script(&leaf_script.0, leaf_script.1);
12951298
builder = builder

0 commit comments

Comments
 (0)