1use core::fmt;
10use core::marker::PhantomData;
11#[cfg(feature = "std")]
12use std::error;
13
14use qtum::constants::MAX_BLOCK_WEIGHT;
15use qtum::hashes::{hash160, ripemd160, sha256, Hash};
16use qtum::Sequence;
17use sync::Arc;
18
19use crate::miniscript::lex::{Token as Tk, TokenIter};
20use crate::miniscript::limits::MAX_PUBKEYS_PER_MULTISIG;
21use crate::miniscript::types::extra_props::ExtData;
22use crate::miniscript::types::{Property, Type};
23use crate::miniscript::ScriptContext;
24use crate::prelude::*;
25#[cfg(doc)]
26use crate::Descriptor;
27use crate::{qtum, hash256, AbsLockTime, Error, Miniscript, MiniscriptKey, ToPublicKey};
28
29fn return_none<T>(_: usize) -> Option<T> {
30 None
31}
32
33pub trait ParseableKey: Sized + ToPublicKey + private::Sealed {
35 fn from_slice(sl: &[u8]) -> Result<Self, KeyParseError>;
37}
38
39impl ParseableKey for qtum::PublicKey {
40 fn from_slice(sl: &[u8]) -> Result<Self, KeyParseError> {
41 qtum::PublicKey::from_slice(sl).map_err(KeyParseError::FullKeyParseError)
42 }
43}
44
45impl ParseableKey for qtum::secp256k1::XOnlyPublicKey {
46 fn from_slice(sl: &[u8]) -> Result<Self, KeyParseError> {
47 qtum::secp256k1::XOnlyPublicKey::from_slice(sl)
48 .map_err(KeyParseError::XonlyKeyParseError)
49 }
50}
51
52#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
54pub enum KeyParseError {
55 FullKeyParseError(qtum::key::Error),
57 XonlyKeyParseError(qtum::secp256k1::Error),
59}
60
61impl fmt::Display for KeyParseError {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 match self {
64 KeyParseError::FullKeyParseError(_e) => write!(f, "FullKey Parse Error"),
65 KeyParseError::XonlyKeyParseError(_e) => write!(f, "XonlyKey Parse Error"),
66 }
67 }
68}
69
70#[cfg(feature = "std")]
71impl error::Error for KeyParseError {
72 fn cause(&self) -> Option<&(dyn error::Error + 'static)> {
73 match self {
74 KeyParseError::FullKeyParseError(e) => Some(e),
75 KeyParseError::XonlyKeyParseError(e) => Some(e),
76 }
77 }
78}
79
80mod private {
82
83 pub trait Sealed {}
84
85 impl Sealed for super::qtum::PublicKey {}
87 impl Sealed for super::qtum::secp256k1::XOnlyPublicKey {}
88}
89
90#[derive(Copy, Clone, Debug)]
91enum NonTerm {
92 Expression,
93 WExpression,
94 Swap,
95 MaybeAndV,
96 Alt,
97 Check,
98 DupIf,
99 Verify,
100 NonZero,
101 ZeroNotEqual,
102 AndV,
103 AndB,
104 Tern,
105 OrB,
106 OrD,
107 OrC,
108 ThreshW { k: usize, n: usize },
109 ThreshE { k: usize, n: usize },
110 EndIf,
112 EndIfNotIf,
114 EndIfElse,
116}
117#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
126pub enum Terminal<Pk: MiniscriptKey, Ctx: ScriptContext> {
127 True,
129 False,
131 PkK(Pk),
134 PkH(Pk),
136 RawPkH(hash160::Hash),
142 After(AbsLockTime),
145 Older(Sequence),
147 Sha256(Pk::Sha256),
150 Hash256(Pk::Hash256),
152 Ripemd160(Pk::Ripemd160),
154 Hash160(Pk::Hash160),
156 Alt(Arc<Miniscript<Pk, Ctx>>),
159 Swap(Arc<Miniscript<Pk, Ctx>>),
161 Check(Arc<Miniscript<Pk, Ctx>>),
163 DupIf(Arc<Miniscript<Pk, Ctx>>),
165 Verify(Arc<Miniscript<Pk, Ctx>>),
167 NonZero(Arc<Miniscript<Pk, Ctx>>),
169 ZeroNotEqual(Arc<Miniscript<Pk, Ctx>>),
171 AndV(Arc<Miniscript<Pk, Ctx>>, Arc<Miniscript<Pk, Ctx>>),
174 AndB(Arc<Miniscript<Pk, Ctx>>, Arc<Miniscript<Pk, Ctx>>),
176 AndOr(
178 Arc<Miniscript<Pk, Ctx>>,
179 Arc<Miniscript<Pk, Ctx>>,
180 Arc<Miniscript<Pk, Ctx>>,
181 ),
182 OrB(Arc<Miniscript<Pk, Ctx>>, Arc<Miniscript<Pk, Ctx>>),
185 OrD(Arc<Miniscript<Pk, Ctx>>, Arc<Miniscript<Pk, Ctx>>),
187 OrC(Arc<Miniscript<Pk, Ctx>>, Arc<Miniscript<Pk, Ctx>>),
189 OrI(Arc<Miniscript<Pk, Ctx>>, Arc<Miniscript<Pk, Ctx>>),
191 Thresh(usize, Vec<Arc<Miniscript<Pk, Ctx>>>),
194 Multi(usize, Vec<Pk>),
196 MultiA(usize, Vec<Pk>),
198}
199
200macro_rules! match_token {
201 ($tokens:expr => $sub:expr,) => { $sub };
203 ($tokens:expr, $($first:pat $(,$rest:pat)* => $sub:expr,)*) => {
205 match $tokens.next() {
206 $(
207 Some($first) => match_token!($tokens $(,$rest)* => $sub,),
208 )*
209 Some(other) => return Err(Error::Unexpected(other.to_string())),
210 None => return Err(Error::UnexpectedStart),
211 }
212 };
213}
214
215#[derive(Debug)]
217struct TerminalStack<Pk: MiniscriptKey, Ctx: ScriptContext>(Vec<Miniscript<Pk, Ctx>>);
218
219impl<Pk: MiniscriptKey, Ctx: ScriptContext> TerminalStack<Pk, Ctx> {
220 fn pop(&mut self) -> Option<Miniscript<Pk, Ctx>> {
222 self.0.pop()
223 }
224
225 fn reduce0(&mut self, ms: Terminal<Pk, Ctx>) -> Result<(), Error> {
227 let ty = Type::type_check(&ms, return_none)?;
228 let ext = ExtData::type_check(&ms, return_none)?;
229 let ms = Miniscript {
230 node: ms,
231 ty,
232 ext,
233 phantom: PhantomData,
234 };
235 Ctx::check_global_validity(&ms)?;
236 self.0.push(ms);
237 Ok(())
238 }
239
240 fn reduce1<F>(&mut self, wrap: F) -> Result<(), Error>
242 where
243 F: FnOnce(Arc<Miniscript<Pk, Ctx>>) -> Terminal<Pk, Ctx>,
244 {
245 let top = self.pop().unwrap();
246 let wrapped_ms = wrap(Arc::new(top));
247
248 let ty = Type::type_check(&wrapped_ms, return_none)?;
249 let ext = ExtData::type_check(&wrapped_ms, return_none)?;
250 let ms = Miniscript {
251 node: wrapped_ms,
252 ty,
253 ext,
254 phantom: PhantomData,
255 };
256 Ctx::check_global_validity(&ms)?;
257 self.0.push(ms);
258 Ok(())
259 }
260
261 fn reduce2<F>(&mut self, wrap: F) -> Result<(), Error>
263 where
264 F: FnOnce(Arc<Miniscript<Pk, Ctx>>, Arc<Miniscript<Pk, Ctx>>) -> Terminal<Pk, Ctx>,
265 {
266 let left = self.pop().unwrap();
267 let right = self.pop().unwrap();
268
269 let wrapped_ms = wrap(Arc::new(left), Arc::new(right));
270
271 let ty = Type::type_check(&wrapped_ms, return_none)?;
272 let ext = ExtData::type_check(&wrapped_ms, return_none)?;
273 let ms = Miniscript {
274 node: wrapped_ms,
275 ty,
276 ext,
277 phantom: PhantomData,
278 };
279 Ctx::check_global_validity(&ms)?;
280 self.0.push(ms);
281 Ok(())
282 }
283}
284
285#[allow(unreachable_patterns)]
287pub fn parse<Ctx: ScriptContext>(
288 tokens: &mut TokenIter,
289) -> Result<Miniscript<Ctx::Key, Ctx>, Error> {
290 let mut non_term = Vec::with_capacity(tokens.len());
291 let mut term = TerminalStack(Vec::with_capacity(tokens.len()));
292
293 non_term.push(NonTerm::MaybeAndV);
295 non_term.push(NonTerm::Expression);
296 loop {
297 match non_term.pop() {
298 Some(NonTerm::Expression) => {
299 match_token!(
300 tokens,
301 Tk::Bytes33(pk) => {
303 let ret = Ctx::Key::from_slice(pk)
304 .map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?;
305 term.reduce0(Terminal::PkK(ret))?
306 },
307 Tk::Bytes65(pk) => {
308 let ret = Ctx::Key::from_slice(pk)
309 .map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?;
310 term.reduce0(Terminal::PkK(ret))?
311 },
312 Tk::Bytes32(pk) => {
325 let ret = Ctx::Key::from_slice(pk).map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?;
326 term.reduce0(Terminal::PkK(ret))?
327 },
328 Tk::CheckSig => {
330 non_term.push(NonTerm::Check);
331 non_term.push(NonTerm::Expression);
332 },
333 Tk::Verify => match_token!(
335 tokens,
336 Tk::Equal => match_token!(
337 tokens,
338 Tk::Hash20(hash) => match_token!(
339 tokens,
340 Tk::Hash160 => match_token!(
341 tokens,
342 Tk::Dup => {
343 term.reduce0(Terminal::RawPkH(
344 hash160::Hash::from_slice(hash).expect("valid size")
345 ))?
346 },
347 Tk::Verify, Tk::Equal, Tk::Num(32), Tk::Size => {
348 non_term.push(NonTerm::Verify);
349 term.reduce0(Terminal::Hash160(
350 hash160::Hash::from_slice(hash).expect("valid size")
351 ))?
352 },
353 ),
354 Tk::Ripemd160, Tk::Verify, Tk::Equal, Tk::Num(32), Tk::Size => {
355 non_term.push(NonTerm::Verify);
356 term.reduce0(Terminal::Ripemd160(
357 ripemd160::Hash::from_slice(hash).expect("valid size")
358 ))?
359 },
360 ),
361 Tk::Bytes32(hash) => match_token!(
363 tokens,
364 Tk::Sha256, Tk::Verify, Tk::Equal, Tk::Num(32), Tk::Size => {
365 non_term.push(NonTerm::Verify);
366 term.reduce0(Terminal::Sha256(
367 sha256::Hash::from_slice(hash).expect("valid size")
368 ))?
369 },
370 Tk::Hash256, Tk::Verify, Tk::Equal, Tk::Num(32), Tk::Size => {
371 non_term.push(NonTerm::Verify);
372 term.reduce0(Terminal::Hash256(
373 hash256::Hash::from_slice(hash).expect("valid size")
374 ))?
375 },
376 ),
377 Tk::Num(k) => {
378 non_term.push(NonTerm::Verify);
379 non_term.push(NonTerm::ThreshW {
380 k: k as usize,
381 n: 0
382 });
383 },
384 ),
385 x => {
386 tokens.un_next(x);
387 non_term.push(NonTerm::Verify);
388 non_term.push(NonTerm::Expression);
389 },
390 ),
391 Tk::ZeroNotEqual => {
392 non_term.push(NonTerm::ZeroNotEqual);
393 non_term.push(NonTerm::Expression);
394 },
395 Tk::CheckSequenceVerify, Tk::Num(n)
397 => term.reduce0(Terminal::Older(Sequence::from_consensus(n)))?,
398 Tk::CheckLockTimeVerify, Tk::Num(n)
399 => term.reduce0(Terminal::After(AbsLockTime::from_consensus(n)))?,
400 Tk::Equal => match_token!(
402 tokens,
403 Tk::Bytes32(hash) => match_token!(
404 tokens,
405 Tk::Sha256,
406 Tk::Verify,
407 Tk::Equal,
408 Tk::Num(32),
409 Tk::Size => term.reduce0(Terminal::Sha256(
410 sha256::Hash::from_slice(hash).expect("valid size")
411 ))?,
412 Tk::Hash256,
413 Tk::Verify,
414 Tk::Equal,
415 Tk::Num(32),
416 Tk::Size => term.reduce0(Terminal::Hash256(
417 hash256::Hash::from_slice(hash).expect("valid size")
418 ))?,
419 ),
420 Tk::Hash20(hash) => match_token!(
421 tokens,
422 Tk::Ripemd160,
423 Tk::Verify,
424 Tk::Equal,
425 Tk::Num(32),
426 Tk::Size => term.reduce0(Terminal::Ripemd160(
427 ripemd160::Hash::from_slice(hash).expect("valid size")
428 ))?,
429 Tk::Hash160,
430 Tk::Verify,
431 Tk::Equal,
432 Tk::Num(32),
433 Tk::Size => term.reduce0(Terminal::Hash160(
434 hash160::Hash::from_slice(hash).expect("valid size")
435 ))?,
436 ),
437 Tk::Num(k) => {
439 non_term.push(NonTerm::ThreshW {
440 k: k as usize,
441 n: 0
442 });
443 },
447 ),
448 Tk::Num(0) => term.reduce0(Terminal::False)?,
450 Tk::Num(1) => term.reduce0(Terminal::True)?,
451 Tk::EndIf => {
452 non_term.push(NonTerm::EndIf);
453 non_term.push(NonTerm::MaybeAndV);
454 non_term.push(NonTerm::Expression);
455 },
456 Tk::BoolAnd => {
458 non_term.push(NonTerm::AndB);
459 non_term.push(NonTerm::Expression);
460 non_term.push(NonTerm::WExpression);
461 },
462 Tk::BoolOr => {
463 non_term.push(NonTerm::OrB);
464 non_term.push(NonTerm::Expression);
465 non_term.push(NonTerm::WExpression);
466 },
467 Tk::CheckMultiSig, Tk::Num(n) => {
469 if n as usize > MAX_PUBKEYS_PER_MULTISIG {
470 return Err(Error::CmsTooManyKeys(n));
471 }
472 let mut keys = Vec::with_capacity(n as usize);
473 for _ in 0..n {
474 match_token!(
475 tokens,
476 Tk::Bytes33(pk) => keys.push(<Ctx::Key>::from_slice(pk)
477 .map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?),
478 Tk::Bytes65(pk) => keys.push(<Ctx::Key>::from_slice(pk)
479 .map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?),
480 );
481 }
482 let k = match_token!(
483 tokens,
484 Tk::Num(k) => k,
485 );
486 keys.reverse();
487 term.reduce0(Terminal::Multi(k as usize, keys))?;
488 },
489 Tk::NumEqual, Tk::Num(k) => {
491 if k > MAX_BLOCK_WEIGHT/32 {
493 return Err(Error::MultiATooManyKeys(MAX_BLOCK_WEIGHT/32))
494 }
495 let mut keys = Vec::with_capacity(k as usize); while tokens.peek() == Some(&Tk::CheckSigAdd) {
497 match_token!(
498 tokens,
499 Tk::CheckSigAdd, Tk::Bytes32(pk) => keys.push(<Ctx::Key>::from_slice(pk)
500 .map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?),
501 );
502 }
503 match_token!(
505 tokens,
506 Tk::CheckSig, Tk::Bytes32(pk) => keys.push(<Ctx::Key>::from_slice(pk)
507 .map_err(|e| Error::PubKeyCtxError(e, Ctx::name_str()))?),
508 );
509 keys.reverse();
510 term.reduce0(Terminal::MultiA(k as usize, keys))?;
511 },
512 );
513 }
514 Some(NonTerm::MaybeAndV) => {
515 if is_and_v(tokens) {
517 non_term.push(NonTerm::AndV);
518 non_term.push(NonTerm::Expression);
519 }
520 }
521 Some(NonTerm::Swap) => {
522 match_token!(
524 tokens,
525 Tk::Swap => {},
526 );
527 term.reduce1(Terminal::Swap)?;
528 }
530 Some(NonTerm::Alt) => {
531 match_token!(
532 tokens,
533 Tk::ToAltStack => {},
534 );
535 term.reduce1(Terminal::Alt)?;
536 }
537 Some(NonTerm::Check) => term.reduce1(Terminal::Check)?,
538 Some(NonTerm::DupIf) => term.reduce1(Terminal::DupIf)?,
539 Some(NonTerm::Verify) => term.reduce1(Terminal::Verify)?,
540 Some(NonTerm::NonZero) => term.reduce1(Terminal::NonZero)?,
541 Some(NonTerm::ZeroNotEqual) => term.reduce1(Terminal::ZeroNotEqual)?,
542 Some(NonTerm::AndV) => {
543 if is_and_v(tokens) {
544 non_term.push(NonTerm::AndV);
545 non_term.push(NonTerm::MaybeAndV);
546 } else {
547 term.reduce2(Terminal::AndV)?
548 }
549 }
550 Some(NonTerm::AndB) => term.reduce2(Terminal::AndB)?,
551 Some(NonTerm::OrB) => term.reduce2(Terminal::OrB)?,
552 Some(NonTerm::OrC) => term.reduce2(Terminal::OrC)?,
553 Some(NonTerm::OrD) => term.reduce2(Terminal::OrD)?,
554 Some(NonTerm::Tern) => {
555 let a = term.pop().unwrap();
556 let b = term.pop().unwrap();
557 let c = term.pop().unwrap();
558 let wrapped_ms = Terminal::AndOr(Arc::new(a), Arc::new(c), Arc::new(b));
559
560 let ty = Type::type_check(&wrapped_ms, return_none)?;
561 let ext = ExtData::type_check(&wrapped_ms, return_none)?;
562
563 term.0.push(Miniscript {
564 node: wrapped_ms,
565 ty,
566 ext,
567 phantom: PhantomData,
568 });
569 }
570 Some(NonTerm::ThreshW { n, k }) => {
571 match_token!(
572 tokens,
573 Tk::Add => {
574 non_term.push(NonTerm::ThreshW { n: n + 1, k });
575 non_term.push(NonTerm::WExpression);
576 },
577 x => {
578 tokens.un_next(x);
579 non_term.push(NonTerm::ThreshE { n: n + 1, k });
580 non_term.push(NonTerm::Expression);
581 },
582 );
583 }
584 Some(NonTerm::ThreshE { n, k }) => {
585 let mut subs = Vec::with_capacity(n);
586 for _ in 0..n {
587 subs.push(Arc::new(term.pop().unwrap()));
588 }
589 term.reduce0(Terminal::Thresh(k, subs))?;
590 }
591 Some(NonTerm::EndIf) => {
592 match_token!(
593 tokens,
594 Tk::Else => {
595 non_term.push(NonTerm::EndIfElse);
596 non_term.push(NonTerm::MaybeAndV);
597 non_term.push(NonTerm::Expression);
598 },
599 Tk::If => match_token!(
600 tokens,
601 Tk::Dup => non_term.push(NonTerm::DupIf),
602 Tk::ZeroNotEqual, Tk::Size
603 => non_term.push(NonTerm::NonZero),
604 ),
605 Tk::NotIf => {
606 non_term.push(NonTerm::EndIfNotIf);
607 },
608 );
609 }
610 Some(NonTerm::EndIfNotIf) => {
611 match_token!(
612 tokens,
613 Tk::IfDup => non_term.push(NonTerm::OrD),
614 x => {
615 tokens.un_next(x);
616 non_term.push(NonTerm::OrC);
617 },
618 );
619 non_term.push(NonTerm::Expression);
620 }
621 Some(NonTerm::EndIfElse) => {
622 match_token!(
623 tokens,
624 Tk::If => {
625 term.reduce2(Terminal::OrI)?;
626 },
627 Tk::NotIf => {
628 non_term.push(NonTerm::Tern);
629 non_term.push(NonTerm::Expression);
630 },
631 );
632 }
633 Some(NonTerm::WExpression) => {
634 match_token!(tokens,
636 Tk::FromAltStack => { non_term.push(NonTerm::Alt);},
637 tok => { tokens.un_next(tok); non_term.push(NonTerm::Swap);},);
638 non_term.push(NonTerm::MaybeAndV);
639 non_term.push(NonTerm::Expression);
640 }
641 None => {
642 break;
644 }
645 }
646 }
647
648 assert_eq!(non_term.len(), 0);
649 assert_eq!(term.0.len(), 1);
650 Ok(term.pop().unwrap())
651}
652
653fn is_and_v(tokens: &mut TokenIter) -> bool {
654 match tokens.peek() {
655 None
656 | Some(&Tk::If)
657 | Some(&Tk::NotIf)
658 | Some(&Tk::Else)
659 | Some(&Tk::ToAltStack)
660 | Some(&Tk::Swap) => false,
661 _ => true,
662 }
663}