Skip to content

Commit 9de17fc

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 3335434 commit 9de17fc

File tree

4 files changed

+138
-70
lines changed

4 files changed

+138
-70
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: 52 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,43 @@ 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?
165+
.into_iter()
166+
.map(|sub| Arc::new(sub))
167+
.collect();
168+
Semantic::Threshold(k, semantic_subs)
160169
}
170+
Terminal::Multi(k, ref keys) | Terminal::MultiA(k, ref keys) => Semantic::Threshold(
171+
k,
172+
keys.iter()
173+
.map(|k| Arc::new(Semantic::Key(k.clone())))
174+
.collect(),
175+
),
161176
}
162177
.normalized();
163178
Ok(ret)
@@ -197,17 +212,31 @@ impl<Pk: MiniscriptKey> Liftable<Pk> for Concrete<Pk> {
197212
Concrete::Ripemd160(ref h) => Semantic::Ripemd160(h.clone()),
198213
Concrete::Hash160(ref h) => Semantic::Hash160(h.clone()),
199214
Concrete::And(ref subs) => {
200-
let semantic_subs: Result<_, Error> = subs.iter().map(Liftable::lift).collect();
201-
Semantic::Threshold(2, semantic_subs?)
215+
let semantic_subs: Result<Vec<Semantic<Pk>>, Error> =
216+
subs.iter().map(Liftable::lift).collect();
217+
let semantic_subs = semantic_subs?
218+
.into_iter()
219+
.map(|sub| Arc::new(sub))
220+
.collect();
221+
Semantic::Threshold(2, semantic_subs)
202222
}
203223
Concrete::Or(ref subs) => {
204-
let semantic_subs: Result<_, Error> =
224+
let semantic_subs: Result<Vec<Semantic<Pk>>, Error> =
205225
subs.iter().map(|(_p, sub)| sub.lift()).collect();
206-
Semantic::Threshold(1, semantic_subs?)
226+
let semantic_subs = semantic_subs?
227+
.into_iter()
228+
.map(|sub| Arc::new(sub))
229+
.collect();
230+
Semantic::Threshold(1, semantic_subs)
207231
}
208232
Concrete::Threshold(k, ref subs) => {
209-
let semantic_subs: Result<_, Error> = subs.iter().map(Liftable::lift).collect();
210-
Semantic::Threshold(k, semantic_subs?)
233+
let semantic_subs: Result<Vec<Semantic<Pk>>, Error> =
234+
subs.iter().map(Liftable::lift).collect();
235+
let semantic_subs = semantic_subs?
236+
.into_iter()
237+
.map(|sub| Arc::new(sub))
238+
.collect();
239+
Semantic::Threshold(k, semantic_subs)
211240
}
212241
}
213242
.normalized();
@@ -346,14 +375,14 @@ mod tests {
346375
Semantic::Threshold(
347376
1,
348377
vec![
349-
Semantic::Threshold(
378+
Arc::new(Semantic::Threshold(
350379
2,
351380
vec![
352-
Semantic::Key(key_a),
353-
Semantic::Older(Sequence::from_height(42))
381+
Arc::new(Semantic::Key(key_a)),
382+
Arc::new(Semantic::Older(Sequence::from_height(42)))
354383
]
355-
),
356-
Semantic::Key(key_b)
384+
)),
385+
Arc::new(Semantic::Key(key_b))
357386
]
358387
),
359388
ms_str.lift().unwrap()

0 commit comments

Comments
 (0)