Skip to content

Commit cbbc582

Browse files
committed
Add Arc to the semantic::Policy::Thresh vector
In preparation for removing recursive algorithms in the `semantic` module add an `Arc` wrapper around the policies in the `Thresh` vector. Note we use the more explicit `Arc::new` instead of `into` because a lot of these should be removed when we remove recursion, later it may be necessary to check that we are not creating new references when a clone will suffice, the explicit `Arc::new` is easier to check. In tests however just use `into`.
1 parent a4d8261 commit cbbc582

File tree

4 files changed

+127
-71
lines changed

4 files changed

+127
-71
lines changed

src/descriptor/sortedmulti.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::miniscript::limits::MAX_PUBKEYS_PER_MULTISIG;
1717
use crate::miniscript::satisfy::{Placeholder, Satisfaction};
1818
use crate::plan::AssetProvider;
1919
use crate::prelude::*;
20+
use crate::sync::Arc;
2021
use crate::{
2122
errstr, expression, policy, script_num_size, Error, ForEachKey, Miniscript, MiniscriptKey,
2223
Satisfier, ToPublicKey, TranslateErr, Translator,
@@ -201,7 +202,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> policy::Liftable<Pk> for SortedMulti
201202
self.k,
202203
self.pks
203204
.iter()
204-
.map(|k| policy::semantic::Policy::Key(k.clone()))
205+
.map(|k| Arc::new(policy::semantic::Policy::Key(k.clone())))
205206
.collect(),
206207
);
207208
Ok(ret)

src/descriptor/tr.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -620,9 +620,10 @@ impl<Pk: MiniscriptKey> Liftable<Pk> for TapTree<Pk> {
620620
fn lift(&self) -> Result<Policy<Pk>, Error> {
621621
fn lift_helper<Pk: MiniscriptKey>(s: &TapTree<Pk>) -> Result<Policy<Pk>, Error> {
622622
match *s {
623-
TapTree::Tree { ref left, ref right, height: _ } => {
624-
Ok(Policy::Threshold(1, vec![lift_helper(left)?, lift_helper(right)?]))
625-
}
623+
TapTree::Tree { ref left, ref right, height: _ } => Ok(Policy::Threshold(
624+
1,
625+
vec![Arc::new(lift_helper(left)?), Arc::new(lift_helper(right)?)],
626+
)),
626627
TapTree::Leaf(ref leaf) => leaf.lift(),
627628
}
628629
}
@@ -635,9 +636,13 @@ impl<Pk: MiniscriptKey> Liftable<Pk> for TapTree<Pk> {
635636
impl<Pk: MiniscriptKey> Liftable<Pk> for Tr<Pk> {
636637
fn lift(&self) -> Result<Policy<Pk>, Error> {
637638
match &self.tree {
638-
Some(root) => {
639-
Ok(Policy::Threshold(1, vec![Policy::Key(self.internal_key.clone()), root.lift()?]))
640-
}
639+
Some(root) => Ok(Policy::Threshold(
640+
1,
641+
vec![
642+
Arc::new(Policy::Key(self.internal_key.clone())),
643+
Arc::new(root.lift()?),
644+
],
645+
)),
641646
None => Ok(Policy::Key(self.internal_key.clone())),
642647
}
643648
}

src/policy/mod.rs

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub use self::semantic::Policy as Semantic;
2323
use crate::descriptor::Descriptor;
2424
use crate::miniscript::{Miniscript, ScriptContext};
2525
use crate::sync::Arc;
26-
use crate::{Error, MiniscriptKey, Terminal};
26+
use crate::{Error, MiniscriptKey, Terminal, Vec};
2727

2828
/// Policy entailment algorithm maximum number of terminals allowed.
2929
const ENTAILMENT_MAX_TERMINALS: usize = 20;
@@ -136,28 +136,40 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Liftable<Pk> for Terminal<Pk, Ctx> {
136136
| Terminal::NonZero(ref sub)
137137
| Terminal::ZeroNotEqual(ref sub) => sub.node.lift()?,
138138
Terminal::AndV(ref left, ref right) | Terminal::AndB(ref left, ref right) => {
139-
Semantic::Threshold(2, vec![left.node.lift()?, right.node.lift()?])
139+
Semantic::Threshold(
140+
2,
141+
vec![Arc::new(left.node.lift()?), Arc::new(right.node.lift()?)],
142+
)
140143
}
141144
Terminal::AndOr(ref a, ref b, ref c) => Semantic::Threshold(
142145
1,
143146
vec![
144-
Semantic::Threshold(2, vec![a.node.lift()?, b.node.lift()?]),
145-
c.node.lift()?,
147+
Arc::new(Semantic::Threshold(
148+
2,
149+
vec![Arc::new(a.node.lift()?), Arc::new(b.node.lift()?)],
150+
)),
151+
Arc::new(c.node.lift()?),
146152
],
147153
),
148154
Terminal::OrB(ref left, ref right)
149155
| Terminal::OrD(ref left, ref right)
150156
| Terminal::OrC(ref left, ref right)
151-
| Terminal::OrI(ref left, ref right) => {
152-
Semantic::Threshold(1, vec![left.node.lift()?, right.node.lift()?])
153-
}
157+
| Terminal::OrI(ref left, ref right) => Semantic::Threshold(
158+
1,
159+
vec![Arc::new(left.node.lift()?), Arc::new(right.node.lift()?)],
160+
),
154161
Terminal::Thresh(k, ref subs) => {
155-
let semantic_subs: Result<_, Error> = subs.iter().map(|s| s.node.lift()).collect();
156-
Semantic::Threshold(k, semantic_subs?)
157-
}
158-
Terminal::Multi(k, ref keys) | Terminal::MultiA(k, ref keys) => {
159-
Semantic::Threshold(k, keys.iter().map(|k| Semantic::Key(k.clone())).collect())
162+
let semantic_subs: Result<Vec<Semantic<Pk>>, Error> =
163+
subs.iter().map(|s| s.node.lift()).collect();
164+
let semantic_subs = semantic_subs?.into_iter().map(Arc::new).collect();
165+
Semantic::Threshold(k, semantic_subs)
160166
}
167+
Terminal::Multi(k, ref keys) | Terminal::MultiA(k, ref keys) => Semantic::Threshold(
168+
k,
169+
keys.iter()
170+
.map(|k| Arc::new(Semantic::Key(k.clone())))
171+
.collect(),
172+
),
161173
}
162174
.normalized();
163175
Ok(ret)
@@ -197,17 +209,22 @@ impl<Pk: MiniscriptKey> Liftable<Pk> for Concrete<Pk> {
197209
Concrete::Ripemd160(ref h) => Semantic::Ripemd160(h.clone()),
198210
Concrete::Hash160(ref h) => Semantic::Hash160(h.clone()),
199211
Concrete::And(ref subs) => {
200-
let semantic_subs: Result<_, Error> = subs.iter().map(Liftable::lift).collect();
201-
Semantic::Threshold(2, semantic_subs?)
212+
let semantic_subs: Result<Vec<Semantic<Pk>>, Error> =
213+
subs.iter().map(Liftable::lift).collect();
214+
let semantic_subs = semantic_subs?.into_iter().map(Arc::new).collect();
215+
Semantic::Threshold(2, semantic_subs)
202216
}
203217
Concrete::Or(ref subs) => {
204-
let semantic_subs: Result<_, Error> =
218+
let semantic_subs: Result<Vec<Semantic<Pk>>, Error> =
205219
subs.iter().map(|(_p, sub)| sub.lift()).collect();
206-
Semantic::Threshold(1, semantic_subs?)
220+
let semantic_subs = semantic_subs?.into_iter().map(Arc::new).collect();
221+
Semantic::Threshold(1, semantic_subs)
207222
}
208223
Concrete::Threshold(k, ref subs) => {
209-
let semantic_subs: Result<_, Error> = subs.iter().map(Liftable::lift).collect();
210-
Semantic::Threshold(k, semantic_subs?)
224+
let semantic_subs: Result<Vec<Semantic<Pk>>, Error> =
225+
subs.iter().map(Liftable::lift).collect();
226+
let semantic_subs = semantic_subs?.into_iter().map(Arc::new).collect();
227+
Semantic::Threshold(k, semantic_subs)
211228
}
212229
}
213230
.normalized();
@@ -346,14 +363,14 @@ mod tests {
346363
Semantic::Threshold(
347364
1,
348365
vec![
349-
Semantic::Threshold(
366+
Arc::new(Semantic::Threshold(
350367
2,
351368
vec![
352-
Semantic::Key(key_a),
353-
Semantic::Older(Sequence::from_height(42))
369+
Arc::new(Semantic::Key(key_a)),
370+
Arc::new(Semantic::Older(Sequence::from_height(42)))
354371
]
355-
),
356-
Semantic::Key(key_b)
372+
)),
373+
Arc::new(Semantic::Key(key_b))
357374
]
358375
),
359376
ms_str.lift().unwrap()

0 commit comments

Comments
 (0)