1use std::marker::PhantomData;
10use std::sync::Arc;
11use std::{error, fmt};
12
13use elements::hashes::{hash160, ripemd160, sha256, Hash};
14
15use crate::elements::Sequence;
16use crate::extensions::ParseableExt;
17use crate::miniscript::lex::{Token as Tk, TokenIter};
18use crate::miniscript::limits::{MAX_BLOCK_WEIGHT, MAX_PUBKEYS_PER_MULTISIG};
19use crate::miniscript::types::extra_props::ExtData;
20use crate::miniscript::types::Type;
21use crate::miniscript::ScriptContext;
22#[cfg(doc)]
23use crate::Descriptor;
24use crate::{
25 bitcoin, hash256, AbsLockTime, Error, Extension, Miniscript, MiniscriptKey, NoExt, ToPublicKey,
26};
27
28pub trait ParseableKey: Sized + ToPublicKey + private::Sealed {
30 fn from_slice(sl: &[u8]) -> Result<Self, KeyParseError>;
32}
33
34impl ParseableKey for bitcoin::PublicKey {
35 fn from_slice(sl: &[u8]) -> Result<Self, KeyParseError> {
36 bitcoin::PublicKey::from_slice(sl).map_err(KeyParseError::FullKeyParseError)
37 }
38}
39
40impl ParseableKey for bitcoin::key::XOnlyPublicKey {
41 fn from_slice(sl: &[u8]) -> Result<Self, KeyParseError> {
42 bitcoin::key::XOnlyPublicKey::from_slice(sl).map_err(KeyParseError::XonlyKeyParseError)
43 }
44}
45
46#[derive(Debug, PartialEq, Eq)]
49pub enum KeyParseError {
50 FullKeyParseError(bitcoin::key::FromSliceError),
52 XonlyKeyParseError(bitcoin::secp256k1::Error),
54}
55
56impl fmt::Display for KeyParseError {
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 match self {
59 KeyParseError::FullKeyParseError(_e) => write!(f, "FullKey Parse Error"),
60 KeyParseError::XonlyKeyParseError(_e) => write!(f, "XonlyKey Parse Error"),
61 }
62 }
63}
64
65impl error::Error for KeyParseError {
66 fn cause(&self) -> Option<&(dyn error::Error + 'static)> {
67 match self {
68 KeyParseError::FullKeyParseError(e) => Some(e),
69 KeyParseError::XonlyKeyParseError(e) => Some(e),
70 }
71 }
72}
73
74mod private {
76
77 pub trait Sealed {}
78
79 impl Sealed for super::bitcoin::PublicKey {}
81 impl Sealed for super::bitcoin::key::XOnlyPublicKey {}
82}
83
84#[derive(Copy, Clone, Debug)]
85enum NonTerm {
86 Expression,
87 WExpression,
88 Swap,
89 MaybeAndV,
90 Alt,
91 Check,
92 DupIf,
93 Verify,
94 NonZero,
95 ZeroNotEqual,
96 AndV,
97 AndB,
98 Tern,
99 OrB,
100 OrD,
101 OrC,
102 ThreshW { k: usize, n: usize },
103 ThreshE { k: usize, n: usize },
104 EndIf,
106 EndIfNotIf,
108 EndIfElse,
110}
111#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
120pub enum Terminal<Pk: MiniscriptKey, Ctx: ScriptContext, Ext: Extension = NoExt> {
121 True,
123 False,
125 PkK(Pk),
128 PkH(Pk),
130 RawPkH(hash160::Hash),
136 After(AbsLockTime),
139 Older(Sequence),
141 Sha256(Pk::Sha256),
144 Hash256(Pk::Hash256),
146 Ripemd160(Pk::Ripemd160),
148 Hash160(Pk::Hash160),
150 Alt(Arc<Miniscript<Pk, Ctx, Ext>>),
153 Swap(Arc<Miniscript<Pk, Ctx, Ext>>),
155 Check(Arc<Miniscript<Pk, Ctx, Ext>>),
157 DupIf(Arc<Miniscript<Pk, Ctx, Ext>>),
159 Verify(Arc<Miniscript<Pk, Ctx, Ext>>),
161 NonZero(Arc<Miniscript<Pk, Ctx, Ext>>),
163 ZeroNotEqual(Arc<Miniscript<Pk, Ctx, Ext>>),
165 AndV(Arc<Miniscript<Pk, Ctx, Ext>>, Arc<Miniscript<Pk, Ctx, Ext>>),
168 AndB(Arc<Miniscript<Pk, Ctx, Ext>>, Arc<Miniscript<Pk, Ctx, Ext>>),
170 AndOr(
172 Arc<Miniscript<Pk, Ctx, Ext>>,
173 Arc<Miniscript<Pk, Ctx, Ext>>,
174 Arc<Miniscript<Pk, Ctx, Ext>>,
175 ),
176 OrB(Arc<Miniscript<Pk, Ctx, Ext>>, Arc<Miniscript<Pk, Ctx, Ext>>),
179 OrD(Arc<Miniscript<Pk, Ctx, Ext>>, Arc<Miniscript<Pk, Ctx, Ext>>),
181 OrC(Arc<Miniscript<Pk, Ctx, Ext>>, Arc<Miniscript<Pk, Ctx, Ext>>),
183 OrI(Arc<Miniscript<Pk, Ctx, Ext>>, Arc<Miniscript<Pk, Ctx, Ext>>),
185 Thresh(usize, Vec<Arc<Miniscript<Pk, Ctx, Ext>>>),
188 Multi(usize, Vec<Pk>),
190 MultiA(usize, Vec<Pk>),
192 Ext(Ext),
194}
195
196#[derive(Debug)]
198struct TerminalStack<Pk: MiniscriptKey, Ctx: ScriptContext, Ext: Extension>(
199 Vec<Miniscript<Pk, Ctx, Ext>>,
200);
201
202impl<Pk: MiniscriptKey, Ctx: ScriptContext, Ext: Extension> TerminalStack<Pk, Ctx, Ext> {
203 fn pop(&mut self) -> Option<Miniscript<Pk, Ctx, Ext>> {
205 self.0.pop()
206 }
207
208 fn reduce0(&mut self, ms: Terminal<Pk, Ctx, Ext>) -> Result<(), Error> {
210 let ty = Type::type_check(&ms)?;
211 let ext = ExtData::type_check(&ms)?;
212 let ms = Miniscript {
213 node: ms,
214 ty,
215 ext,
216 phantom: PhantomData,
217 };
218 Ctx::check_global_validity(&ms)?;
219 self.0.push(ms);
220 Ok(())
221 }
222
223 fn reduce1<F>(&mut self, wrap: F) -> Result<(), Error>
225 where
226 F: FnOnce(Arc<Miniscript<Pk, Ctx, Ext>>) -> Terminal<Pk, Ctx, Ext>,
227 {
228 let top = self.pop().unwrap();
229 let wrapped_ms = wrap(Arc::new(top));
230
231 self.reduce0(wrapped_ms)
232 }
233
234 fn reduce2<F>(&mut self, wrap: F) -> Result<(), Error>
236 where
237 F: FnOnce(
238 Arc<Miniscript<Pk, Ctx, Ext>>,
239 Arc<Miniscript<Pk, Ctx, Ext>>,
240 ) -> Terminal<Pk, Ctx, Ext>,
241 {
242 let left = self.pop().unwrap();
243 let right = self.pop().unwrap();
244
245 let wrapped_ms = wrap(Arc::new(left), Arc::new(right));
246
247 self.reduce0(wrapped_ms)
248 }
249}
250
251#[allow(unreachable_patterns)]
253pub fn parse<Ctx: ScriptContext, Ext: ParseableExt>(
254 tokens: &mut TokenIter<'_>,
255) -> Result<Miniscript<Ctx::Key, Ctx, Ext>, Error> {
256 let mut non_term = Vec::with_capacity(tokens.len());
257 let mut term = TerminalStack(Vec::with_capacity(tokens.len()));
258
259 non_term.push(NonTerm::MaybeAndV);
261 non_term.push(NonTerm::Expression);
262 loop {
263 if let Some(NonTerm::Expression) = non_term.last() {
265 if let Ok(ext) = Ext::from_token_iter(tokens) {
266 non_term.pop();
268 term.reduce0(Terminal::Ext(ext))?;
269 continue;
270 }
271 }
272 match non_term.pop() {
273 Some(NonTerm::Expression) => {
274 match_token!(
275 tokens,
276 Tk::Bytes33(pk) => {
278 let ret = Ctx::Key::from_slice(pk)
279 .map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?;
280 term.reduce0(Terminal::PkK(ret))?
281 },
282 Tk::Bytes65(pk) => {
283 let ret = Ctx::Key::from_slice(pk)
284 .map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?;
285 term.reduce0(Terminal::PkK(ret))?
286 },
287 Tk::Bytes32(pk) => {
300 let ret = Ctx::Key::from_slice(pk).map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?;
301 term.reduce0(Terminal::PkK(ret))?
302 },
303 Tk::CheckSig => {
305 non_term.push(NonTerm::Check);
306 non_term.push(NonTerm::Expression);
307 },
308 Tk::Verify => match_token!(
310 tokens,
311 Tk::Equal => match_token!(
312 tokens,
313 Tk::Hash20(hash) => match_token!(
314 tokens,
315 Tk::Hash160 => match_token!(
316 tokens,
317 Tk::Dup => {
318 term.reduce0(Terminal::RawPkH(
319 hash160::Hash::from_slice(hash).expect("valid size")
320 ))?
321 },
322 Tk::Verify, Tk::Equal, Tk::Num(32), Tk::Size => {
323 non_term.push(NonTerm::Verify);
324 term.reduce0(Terminal::Hash160(
325 hash160::Hash::from_slice(hash).expect("valid size")
326 ))?
327 },
328 ),
329 Tk::Ripemd160, Tk::Verify, Tk::Equal, Tk::Num(32), Tk::Size => {
330 non_term.push(NonTerm::Verify);
331 term.reduce0(Terminal::Ripemd160(
332 ripemd160::Hash::from_slice(hash).expect("valid size")
333 ))?
334 },
335 ),
336 Tk::Bytes32(hash) => match_token!(
338 tokens,
339 Tk::Sha256, Tk::Verify, Tk::Equal, Tk::Num(32), Tk::Size => {
340 non_term.push(NonTerm::Verify);
341 term.reduce0(Terminal::Sha256(
342 sha256::Hash::from_slice(hash).expect("valid size")
343 ))?
344 },
345 Tk::Hash256, Tk::Verify, Tk::Equal, Tk::Num(32), Tk::Size => {
346 non_term.push(NonTerm::Verify);
347 term.reduce0(Terminal::Hash256(
348 hash256::Hash::from_slice(hash).expect("valid size")
349 ))?
350 },
351 ),
352 Tk::Num(k) => {
353 non_term.push(NonTerm::Verify);
354 non_term.push(NonTerm::ThreshW {
355 k: k as usize,
356 n: 0
357 });
358 },
359 x => {
360 tokens.un_next(x);
361 tokens.un_next(Tk::Equal);
362 non_term.push(NonTerm::Verify);
363 non_term.push(NonTerm::Expression);
364 },
365 ),
366 x => {
367 tokens.un_next(x);
368 non_term.push(NonTerm::Verify);
369 non_term.push(NonTerm::Expression);
370 },
371 ),
372 Tk::ZeroNotEqual => {
373 non_term.push(NonTerm::ZeroNotEqual);
374 non_term.push(NonTerm::Expression);
375 },
376 Tk::CheckSequenceVerify, Tk::Num(n)
378 => term.reduce0(Terminal::Older(Sequence::from_consensus(n)))?,
379 Tk::CheckLockTimeVerify, Tk::Num(n)
380 => term.reduce0(Terminal::After(AbsLockTime::from_consensus(n)))?,
381 Tk::Equal => match_token!(
383 tokens,
384 Tk::Bytes32(hash) => match_token!(
385 tokens,
386 Tk::Sha256,
387 Tk::Verify,
388 Tk::Equal,
389 Tk::Num(32),
390 Tk::Size => term.reduce0(Terminal::Sha256(
391 sha256::Hash::from_slice(hash).expect("valid size")
392 ))?,
393 Tk::Hash256,
394 Tk::Verify,
395 Tk::Equal,
396 Tk::Num(32),
397 Tk::Size => term.reduce0(Terminal::Hash256(
398 hash256::Hash::from_slice(hash).expect("valid size")
399 ))?,
400 ),
401 Tk::Hash20(hash) => match_token!(
402 tokens,
403 Tk::Ripemd160,
404 Tk::Verify,
405 Tk::Equal,
406 Tk::Num(32),
407 Tk::Size => term.reduce0(Terminal::Ripemd160(
408 ripemd160::Hash::from_slice(hash).expect("valid size")
409 ))?,
410 Tk::Hash160,
411 Tk::Verify,
412 Tk::Equal,
413 Tk::Num(32),
414 Tk::Size => term.reduce0(Terminal::Hash160(
415 hash160::Hash::from_slice(hash).expect("valid size")
416 ))?,
417 ),
418 Tk::Num(k) => {
420 non_term.push(NonTerm::ThreshW {
421 k: k as usize,
422 n: 0
423 });
424 },
428 ),
429 Tk::Num(0) => term.reduce0(Terminal::False)?,
431 Tk::Num(1) => term.reduce0(Terminal::True)?,
432 Tk::EndIf => {
433 non_term.push(NonTerm::EndIf);
434 non_term.push(NonTerm::MaybeAndV);
435 non_term.push(NonTerm::Expression);
436 },
437 Tk::BoolAnd => {
439 non_term.push(NonTerm::AndB);
440 non_term.push(NonTerm::Expression);
441 non_term.push(NonTerm::WExpression);
442 },
443 Tk::BoolOr => {
444 non_term.push(NonTerm::OrB);
445 non_term.push(NonTerm::Expression);
446 non_term.push(NonTerm::WExpression);
447 },
448 Tk::CheckMultiSig, Tk::Num(n) => {
450 if n as usize > MAX_PUBKEYS_PER_MULTISIG {
451 return Err(Error::CmsTooManyKeys(n));
452 }
453 let mut keys = Vec::with_capacity(n as usize);
454 for _ in 0..n {
455 match_token!(
456 tokens,
457 Tk::Bytes33(pk) => keys.push(<Ctx::Key>::from_slice(pk)
458 .map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?),
459 Tk::Bytes65(pk) => keys.push(<Ctx::Key>::from_slice(pk)
460 .map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?),
461 );
462 }
463 let k = match_token!(
464 tokens,
465 Tk::Num(k) => k,
466 );
467 keys.reverse();
468 term.reduce0(Terminal::Multi(k as usize, keys))?;
469 },
470 Tk::NumEqual, Tk::Num(k) => {
472 if k > (MAX_BLOCK_WEIGHT/32) as u32 {
474 return Err(Error::MultiATooManyKeys((MAX_BLOCK_WEIGHT/32) as u32))
475 }
476 let mut keys = Vec::with_capacity(k as usize); while tokens.peek() == Some(&Tk::CheckSigAdd) {
478 match_token!(
479 tokens,
480 Tk::CheckSigAdd, Tk::Bytes32(pk) => keys.push(<Ctx::Key>::from_slice(pk)
481 .map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?),
482 );
483 }
484 match_token!(
486 tokens,
487 Tk::CheckSig, Tk::Bytes32(pk) => keys.push(<Ctx::Key>::from_slice(pk)
488 .map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?),
489 );
490 keys.reverse();
491 term.reduce0(Terminal::MultiA(k as usize, keys))?;
492 },
493 );
494 }
495 Some(NonTerm::MaybeAndV) => {
496 if is_and_v(tokens) {
498 non_term.push(NonTerm::AndV);
499 non_term.push(NonTerm::Expression);
500 }
501 }
502 Some(NonTerm::Swap) => {
503 match_token!(
505 tokens,
506 Tk::Swap => {},
507 );
508 term.reduce1(Terminal::Swap)?;
509 }
511 Some(NonTerm::Alt) => {
512 match_token!(
513 tokens,
514 Tk::ToAltStack => {},
515 );
516 term.reduce1(Terminal::Alt)?;
517 }
518 Some(NonTerm::Check) => term.reduce1(Terminal::Check)?,
519 Some(NonTerm::DupIf) => term.reduce1(Terminal::DupIf)?,
520 Some(NonTerm::Verify) => term.reduce1(Terminal::Verify)?,
521 Some(NonTerm::NonZero) => term.reduce1(Terminal::NonZero)?,
522 Some(NonTerm::ZeroNotEqual) => term.reduce1(Terminal::ZeroNotEqual)?,
523 Some(NonTerm::AndV) => {
524 if is_and_v(tokens) {
525 non_term.push(NonTerm::AndV);
526 non_term.push(NonTerm::MaybeAndV);
527 } else {
528 term.reduce2(Terminal::AndV)?
529 }
530 }
531 Some(NonTerm::AndB) => term.reduce2(Terminal::AndB)?,
532 Some(NonTerm::OrB) => term.reduce2(Terminal::OrB)?,
533 Some(NonTerm::OrC) => term.reduce2(Terminal::OrC)?,
534 Some(NonTerm::OrD) => term.reduce2(Terminal::OrD)?,
535 Some(NonTerm::Tern) => {
536 let a = term.pop().unwrap();
537 let b = term.pop().unwrap();
538 let c = term.pop().unwrap();
539 let wrapped_ms = Terminal::AndOr(Arc::new(a), Arc::new(c), Arc::new(b));
540
541 let ty = Type::type_check(&wrapped_ms)?;
542 let ext = ExtData::type_check(&wrapped_ms)?;
543
544 term.0.push(Miniscript {
545 node: wrapped_ms,
546 ty,
547 ext,
548 phantom: PhantomData,
549 });
550 }
551 Some(NonTerm::ThreshW { n, k }) => {
552 match_token!(
553 tokens,
554 Tk::Add => {
555 non_term.push(NonTerm::ThreshW { n: n + 1, k });
556 non_term.push(NonTerm::WExpression);
557 },
558 x => {
559 tokens.un_next(x);
560 non_term.push(NonTerm::ThreshE { n: n + 1, k });
561 non_term.push(NonTerm::Expression);
562 },
563 );
564 }
565 Some(NonTerm::ThreshE { n, k }) => {
566 let mut subs = Vec::with_capacity(n);
567 for _ in 0..n {
568 subs.push(Arc::new(term.pop().unwrap()));
569 }
570 term.reduce0(Terminal::Thresh(k, subs))?;
571 }
572 Some(NonTerm::EndIf) => {
573 match_token!(
574 tokens,
575 Tk::Else => {
576 non_term.push(NonTerm::EndIfElse);
577 non_term.push(NonTerm::MaybeAndV);
578 non_term.push(NonTerm::Expression);
579 },
580 Tk::If => match_token!(
581 tokens,
582 Tk::Dup => non_term.push(NonTerm::DupIf),
583 Tk::ZeroNotEqual, Tk::Size
584 => non_term.push(NonTerm::NonZero),
585 ),
586 Tk::NotIf => {
587 non_term.push(NonTerm::EndIfNotIf);
588 },
589 );
590 }
591 Some(NonTerm::EndIfNotIf) => {
592 match_token!(
593 tokens,
594 Tk::IfDup => non_term.push(NonTerm::OrD),
595 x => {
596 tokens.un_next(x);
597 non_term.push(NonTerm::OrC);
598 },
599 );
600 non_term.push(NonTerm::Expression);
601 }
602 Some(NonTerm::EndIfElse) => {
603 match_token!(
604 tokens,
605 Tk::If => {
606 term.reduce2(Terminal::OrI)?;
607 },
608 Tk::NotIf => {
609 non_term.push(NonTerm::Tern);
610 non_term.push(NonTerm::Expression);
611 },
612 );
613 }
614 Some(NonTerm::WExpression) => {
615 match_token!(tokens,
617 Tk::FromAltStack => { non_term.push(NonTerm::Alt);},
618 tok => { tokens.un_next(tok); non_term.push(NonTerm::Swap);},);
619 non_term.push(NonTerm::MaybeAndV);
620 non_term.push(NonTerm::Expression);
621 }
622 None => {
623 break;
625 }
626 }
627 }
628
629 assert_eq!(non_term.len(), 0);
630 assert_eq!(term.0.len(), 1);
631 Ok(term.pop().unwrap())
632}
633
634fn is_and_v(tokens: &mut TokenIter<'_>) -> bool {
635 !matches!(
636 tokens.peek(),
637 None | Some(&Tk::If)
638 | Some(&Tk::NotIf)
639 | Some(&Tk::Else)
640 | Some(&Tk::ToAltStack)
641 | Some(&Tk::Swap)
642 )
643}