elements_miniscript/descriptor/
sortedmulti.rs1use std::fmt;
10use std::marker::PhantomData;
11use std::str::FromStr;
12
13use elements::script;
14
15use crate::miniscript::context::ScriptContext;
16use crate::miniscript::decode::Terminal;
17use crate::miniscript::limits::MAX_PUBKEYS_PER_MULTISIG;
18use crate::miniscript::{self};
19use crate::{
20 errstr, expression, policy, script_num_size, Error, ForEachKey, Miniscript, MiniscriptKey,
21 Satisfier, ToPublicKey, Translator,
22};
23
24#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
26pub struct SortedMultiVec<Pk: MiniscriptKey, Ctx: ScriptContext> {
27 pub k: usize,
29 pub pks: Vec<Pk>,
31 pub(crate) phantom: PhantomData<Ctx>,
33}
34
35impl<Pk: MiniscriptKey, Ctx: ScriptContext> SortedMultiVec<Pk, Ctx> {
36 pub fn new(k: usize, pks: Vec<Pk>) -> Result<Self, Error> {
40 if pks.len() > MAX_PUBKEYS_PER_MULTISIG {
42 return Err(Error::BadDescriptor("Too many public keys".to_string()));
43 }
44
45 let term: miniscript::decode::Terminal<Pk, Ctx> = Terminal::Multi(k, pks.clone());
50 let ms = Miniscript::from_ast(term)?;
51
52 Ctx::check_local_validity(&ms)?;
55
56 Ok(Self {
57 k,
58 pks,
59 phantom: PhantomData,
60 })
61 }
62 pub fn from_tree(tree: &expression::Tree<'_>) -> Result<Self, Error>
64 where
65 Pk: FromStr,
66 <Pk as FromStr>::Err: ToString,
67 {
68 if tree.args.is_empty() {
69 return Err(errstr("no arguments given for sortedmulti"));
70 }
71 let k = expression::parse_num::<u32>(tree.args[0].name)?;
72 if k > (tree.args.len() - 1) as u32 {
73 return Err(errstr(
74 "higher threshold than there were keys in sortedmulti",
75 ));
76 }
77 let pks: Result<Vec<Pk>, _> = tree.args[1..]
78 .iter()
79 .map(|sub| expression::terminal(sub, Pk::from_str))
80 .collect();
81
82 pks.map(|pks| SortedMultiVec::new(k as usize, pks))?
83 }
84
85 pub fn translate_pk<T, Q, FuncError>(
89 &self,
90 t: &mut T,
91 ) -> Result<SortedMultiVec<Q, Ctx>, FuncError>
92 where
93 T: Translator<Pk, Q, FuncError>,
94 Q: MiniscriptKey,
95 {
96 let pks: Result<Vec<Q>, _> = self.pks.iter().map(|pk| t.pk(pk)).collect();
97 Ok(SortedMultiVec {
98 k: self.k,
99 pks: pks?,
100 phantom: PhantomData,
101 })
102 }
103}
104
105impl<Pk: MiniscriptKey, Ctx: ScriptContext> ForEachKey<Pk> for SortedMultiVec<Pk, Ctx> {
106 fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
107 where
108 Pk: 'a,
109 {
110 self.pks.iter().all(pred)
111 }
112}
113
114impl<Pk: MiniscriptKey, Ctx: ScriptContext> SortedMultiVec<Pk, Ctx> {
115 pub fn sanity_check(&self) -> Result<(), Error> {
117 let ms: Miniscript<Pk, Ctx> =
118 Miniscript::from_ast(Terminal::Multi(self.k, self.pks.clone()))
119 .expect("Must typecheck");
120 ms.sanity_check()?;
122 Ok(())
123 }
124}
125
126impl<Pk: MiniscriptKey, Ctx: ScriptContext> SortedMultiVec<Pk, Ctx> {
127 pub fn sorted_node(&self) -> Terminal<Pk, Ctx>
129 where
130 Pk: ToPublicKey,
131 {
132 let mut pks = self.pks.clone();
133 pks.sort_by(|a, b| {
135 a.to_public_key()
136 .inner
137 .serialize()
138 .partial_cmp(&b.to_public_key().inner.serialize())
139 .unwrap()
140 });
141 Terminal::Multi(self.k, pks)
142 }
143
144 pub fn encode(&self) -> script::Script
146 where
147 Pk: ToPublicKey,
148 {
149 self.sorted_node()
150 .encode(script::Builder::new())
151 .into_script()
152 }
153
154 pub fn satisfy<S>(&self, satisfier: S) -> Result<Vec<Vec<u8>>, Error>
157 where
158 Pk: ToPublicKey,
159 S: Satisfier<Pk>,
160 {
161 let ms = Miniscript::from_ast(self.sorted_node()).expect("Multi node typecheck");
162 ms.satisfy(satisfier)
163 }
164
165 pub fn script_size(&self) -> usize {
173 script_num_size(self.k)
174 + 1
175 + script_num_size(self.pks.len())
176 + self.pks.iter().map(|pk| Ctx::pk_len(pk)).sum::<usize>()
177 }
178
179 pub fn max_satisfaction_witness_elements(&self) -> usize {
188 2 + self.k
189 }
190
191 pub fn max_satisfaction_size(&self) -> usize {
200 1 + 73 * self.k
201 }
202}
203
204impl<Pk: MiniscriptKey, Ctx: ScriptContext> policy::Liftable<Pk> for SortedMultiVec<Pk, Ctx> {
205 fn lift(&self) -> Result<policy::semantic::Policy<Pk>, Error> {
206 let ret = policy::semantic::Policy::Threshold(
207 self.k,
208 self.pks
209 .iter()
210 .map(|k| policy::semantic::Policy::Key(k.clone()))
211 .collect(),
212 );
213 Ok(ret)
214 }
215}
216
217impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Debug for SortedMultiVec<Pk, Ctx> {
218 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
219 fmt::Display::fmt(self, f)
220 }
221}
222
223impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Display for SortedMultiVec<Pk, Ctx> {
224 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
225 write!(f, "sortedmulti({}", self.k)?;
226 for k in &self.pks {
227 write!(f, ",{}", k)?;
228 }
229 f.write_str(")")
230 }
231}
232
233#[cfg(test)]
234mod tests {
235 use bitcoin::secp256k1::PublicKey;
236
237 use super::*;
238 use crate::miniscript::context::Legacy;
239
240 #[test]
241 fn too_many_pubkeys() {
242 let pk = PublicKey::from_str(
244 "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443",
245 )
246 .unwrap();
247
248 let over = 1 + MAX_PUBKEYS_PER_MULTISIG;
249
250 let mut pks = Vec::new();
251 for _ in 0..over {
252 pks.push(pk);
253 }
254
255 let res: Result<SortedMultiVec<PublicKey, Legacy>, Error> = SortedMultiVec::new(0, pks);
256 let error = res.expect_err("constructor should err");
257
258 match error {
259 Error::BadDescriptor(_) => {} other => panic!("unexpected error: {:?}", other),
261 }
262 }
263}