1use std::convert::TryInto;
4use std::str::FromStr;
5use std::{cmp, error, fmt};
6
7use bitcoin::key::XOnlyPublicKey;
8use bitcoin_miniscript::MiniscriptKey;
9use elements::opcodes::all::*;
10use elements::sighash::Prevouts;
11use elements::{opcodes, script, secp256k1_zkp as secp256k1, SchnorrSig, Transaction};
12
13use super::param::{ExtParamTranslator, TranslateExtParam};
14use super::{CovExtArgs, CsfsKey, ExtParam, FromTokenIterError, IdxExpr, ParseableExt, TxEnv};
15use crate::expression::{FromTree, Tree};
16use crate::extensions::check_sig_price_oracle_1;
17use crate::miniscript::context::ScriptContextError;
18use crate::miniscript::lex::{Token as Tk, TokenIter};
19use crate::miniscript::limits::MAX_STANDARD_P2WSH_STACK_ITEM_SIZE;
20use crate::miniscript::satisfy::{Satisfaction, Witness};
21use crate::miniscript::types::extra_props::{OpLimits, TimelockInfo};
22use crate::miniscript::types::{Base, Correctness, Dissat, ExtData, Input, Malleability};
23use crate::{
24 expression, interpreter, miniscript, script_num_size, Error, Extension, Satisfier, ToPublicKey,
25 TranslateExt,
26};
27
28#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone)]
39pub enum ExprInner<T: ExtParam> {
40 Const(i64),
44 CurrInputIdx,
47 Input(IdxExpr),
50 Output(IdxExpr),
53 InputIssue(IdxExpr),
59 InputReIssue(IdxExpr),
64
65 Add(Box<Expr<T>>, Box<Expr<T>>),
69 Sub(Box<Expr<T>>, Box<Expr<T>>),
72 Mul(Box<Expr<T>>, Box<Expr<T>>),
75 Div(Box<Expr<T>>, Box<Expr<T>>),
80 Mod(Box<Expr<T>>, Box<Expr<T>>),
84 BitAnd(Box<Expr<T>>, Box<Expr<T>>),
87 BitOr(Box<Expr<T>>, Box<Expr<T>>),
90 Xor(Box<Expr<T>>, Box<Expr<T>>),
93 Invert(Box<Expr<T>>),
97 Negate(Box<Expr<T>>),
100
101 PriceOracle1(T, u64),
107 PriceOracle1W(T, u64),
113}
114
115#[derive(Debug, Clone)]
118pub struct ExprIter<'a, T: ExtParam> {
119 stack: Vec<&'a ExprInner<T>>,
120}
121
122impl<'a, T: ExtParam> Iterator for ExprIter<'a, T> {
123 type Item = &'a ExprInner<T>;
124
125 fn next(&mut self) -> Option<Self::Item> {
126 while let Some(expr) = self.stack.pop() {
127 match expr {
128 ExprInner::Const(_)
129 | ExprInner::CurrInputIdx
130 | ExprInner::Input(_)
131 | ExprInner::Output(_)
132 | ExprInner::InputIssue(_)
133 | ExprInner::InputReIssue(_)
134 | ExprInner::PriceOracle1(_, _)
135 | ExprInner::PriceOracle1W(_, _) => return Some(expr),
136 ExprInner::Add(a, b)
137 | ExprInner::Sub(a, b)
138 | ExprInner::Mul(a, b)
139 | ExprInner::Div(a, b)
140 | ExprInner::Mod(a, b)
141 | ExprInner::BitAnd(a, b)
142 | ExprInner::BitOr(a, b)
143 | ExprInner::Xor(a, b) => {
144 self.stack.push(b.as_inner());
145 self.stack.push(a.as_inner());
146 }
147 ExprInner::Invert(a) | ExprInner::Negate(a) => {
148 self.stack.push(a.as_inner());
149 }
150 }
151 }
152 None
153 }
154}
155
156#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Clone)]
158pub struct Expr<T: ExtParam> {
159 inner: ExprInner<T>,
161 script_size: usize,
163 depth: usize,
165}
166
167impl<T: ExtParam> Expr<T> {
168 pub fn into_inner(self) -> ExprInner<T> {
170 self.inner
171 }
172
173 pub fn as_inner(&self) -> &ExprInner<T> {
175 &self.inner
176 }
177
178 pub fn script_size(&self) -> usize {
180 self.script_size
181 }
182
183 pub fn depth(&self) -> usize {
185 self.depth
186 }
187
188 pub fn from_inner(inner: ExprInner<T>) -> Self {
190 let (script_size, depth) = match &inner {
191 ExprInner::Const(_c) => (8 + 1, 0),
192 ExprInner::CurrInputIdx => (4, 0), ExprInner::Input(i) => (
194 i.script_size() + 3, 0,
196 ),
197 ExprInner::Output(i) => (
198 i.script_size() + 3, 0,
200 ),
201 ExprInner::InputIssue(i) => (
202 i.script_size() + 7, 0,
204 ),
205 ExprInner::InputReIssue(i) => (
206 i.script_size() + 7, 0,
208 ),
209 ExprInner::Add(x, y) => (
210 x.script_size + y.script_size + 3, cmp::max(x.depth, y.depth),
212 ),
213 ExprInner::Sub(x, y) => (
214 x.script_size + y.script_size + 3, cmp::max(x.depth, y.depth),
216 ),
217 ExprInner::Mul(x, y) => (
218 x.script_size + y.script_size + 3, cmp::max(x.depth, y.depth),
220 ),
221 ExprInner::Div(x, y) => (
222 x.script_size + y.script_size + 4, cmp::max(x.depth, y.depth),
224 ),
225 ExprInner::Mod(x, y) => (
226 x.script_size + y.script_size + 4, cmp::max(x.depth, y.depth),
228 ),
229 ExprInner::BitAnd(x, y) => (
230 x.script_size + y.script_size + 1, cmp::max(x.depth, y.depth),
232 ),
233 ExprInner::BitOr(x, y) => (
234 x.script_size + y.script_size + 1, cmp::max(x.depth, y.depth),
236 ),
237 ExprInner::Xor(x, y) => (
238 x.script_size + y.script_size + 1, cmp::max(x.depth, y.depth),
240 ),
241 ExprInner::Invert(x) => (
242 x.script_size + 1, x.depth + 1,
244 ),
245 ExprInner::Negate(x) => (
246 x.script_size + 3, x.depth + 1,
248 ),
249 ExprInner::PriceOracle1(_pk, _time) => (
250 (32 + 1) + (8 + 1) + 8, 0,
254 ),
255 ExprInner::PriceOracle1W(_pk, _time) => (
256 (32 + 1) + (8 + 1) + 11, 0,
260 ),
261 };
262 Self {
263 inner,
264 script_size,
265 depth,
266 }
267 }
268
269 pub fn iter_terminals(&self) -> impl Iterator<Item = &ExprInner<T>> {
271 ExprIter {
272 stack: vec![&self.inner],
273 }
274 }
275}
276
277#[derive(Debug, Clone, PartialEq, Eq)]
279pub enum TypeError {
280 PriceOracle1WFirst,
282 PriceOracle1Missing,
284}
285
286impl std::fmt::Display for TypeError {
287 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
288 match self {
289 TypeError::PriceOracle1WFirst => {
290 write!(f, "PriceOracle1W is the first element in the expression")
291 }
292 TypeError::PriceOracle1Missing => write!(
293 f,
294 "PriceOracle1 is *not* the first element in the expression"
295 ),
296 }
297 }
298}
299
300impl std::error::Error for TypeError {}
301
302impl Expr<CovExtArgs> {
303 fn eval(&self, env: &TxEnv, s: &mut interpreter::Stack) -> Result<i64, EvalError> {
305 match &self.inner {
306 ExprInner::Const(c) => Ok(*c),
307 ExprInner::CurrInputIdx => {
308 if env.idx >= env.spent_utxos.len() {
309 return Err(EvalError::UtxoIndexOutOfBounds(
310 env.idx,
311 env.spent_utxos.len(),
312 ));
313 }
314 env.spent_utxos[env.idx]
315 .value
316 .explicit()
317 .map(|x| x as i64) .ok_or(EvalError::NonExplicitInput(env.idx))
319 }
320 ExprInner::Input(i) => {
321 let i = i.eval(env)?;
322 if i >= env.spent_utxos.len() {
323 return Err(EvalError::UtxoIndexOutOfBounds(i, env.spent_utxos.len()));
324 }
325 env.spent_utxos[i]
326 .value
327 .explicit()
328 .map(|x| x as i64) .ok_or(EvalError::NonExplicitInput(i))
330 }
331 ExprInner::Output(i) => {
332 let i = i.eval(env)?;
333 if i >= env.tx.output.len() {
334 return Err(EvalError::OutputIndexOutOfBounds(i, env.tx.output.len()));
335 }
336 env.tx.output[i]
337 .value
338 .explicit()
339 .map(|x| x as i64) .ok_or(EvalError::NonExplicitOutput(i))
341 }
342 ExprInner::InputIssue(i) => {
343 let i = i.eval(env)?;
344 if i >= env.tx.input.len() {
345 return Err(EvalError::InputIndexOutOfBounds(i, env.tx.input.len()));
346 }
347 env.tx.input[i]
348 .asset_issuance
349 .amount
350 .explicit()
351 .map(|x| x as i64) .ok_or(EvalError::NonExplicitInputIssuance(i))
353 }
354 ExprInner::InputReIssue(i) => {
355 let i = i.eval(env)?;
356 if i >= env.tx.input.len() {
357 return Err(EvalError::InputIndexOutOfBounds(i, env.tx.input.len()));
358 }
359 env.tx.input[i]
360 .asset_issuance
361 .inflation_keys
362 .explicit()
363 .map(|x| x as i64) .ok_or(EvalError::NonExplicitInputReIssuance(i))
365 }
366 ExprInner::Add(x, y) => {
367 let x = x.eval(env, s)?;
368 let y = y.eval(env, s)?;
369 x.checked_add(y).ok_or(EvalError::AddOverflow(x, y))
370 }
371 ExprInner::Sub(x, y) => {
372 let x = x.eval(env, s)?;
373 let y = y.eval(env, s)?;
374 x.checked_sub(y).ok_or(EvalError::SubOverflow(x, y))
375 }
376 ExprInner::Mul(x, y) => {
377 let x = x.eval(env, s)?;
378 let y = y.eval(env, s)?;
379 x.checked_mul(y).ok_or(EvalError::MulOverflow(x, y))
380 }
381 ExprInner::Div(x, y) => {
382 let x = x.eval(env, s)?;
383 let y = y.eval(env, s)?;
384 x.checked_div_euclid(y).ok_or(EvalError::DivOverflow(x, y))
385 }
386 ExprInner::Mod(x, y) => {
387 let x = x.eval(env, s)?;
388 let y = y.eval(env, s)?;
389 x.checked_rem_euclid(y).ok_or(EvalError::ModOverflow(x, y))
390 }
391 ExprInner::BitAnd(x, y) => {
392 let x = x.eval(env, s)?;
393 let y = y.eval(env, s)?;
394 Ok(x & y)
395 }
396 ExprInner::BitOr(x, y) => {
397 let x = x.eval(env, s)?;
398 let y = y.eval(env, s)?;
399 Ok(x | y)
400 }
401 ExprInner::Xor(x, y) => {
402 let x = x.eval(env, s)?;
403 let y = y.eval(env, s)?;
404 Ok(x ^ y)
405 }
406 ExprInner::Invert(x) => {
407 let x = x.eval(env, s)?;
408 Ok(!x)
409 }
410 ExprInner::Negate(x) => {
411 let x = x.eval(env, s)?;
412 x.checked_neg().ok_or(EvalError::NegOverflow(x))
413 }
414 ExprInner::PriceOracle1(pk, timestamp) | ExprInner::PriceOracle1W(pk, timestamp) => {
415 let x_only_pk = if let CovExtArgs::XOnlyKey(pk) = pk {
416 pk.0
417 } else {
418 unreachable!("Construction ensures that Param is only of type XOnlyKey")
419 };
420 let price = s.pop().ok_or(EvalError::MissingPrice)?;
421 let price = price.try_push().map_err(|_| EvalError::Price8BytePush)?;
422 let price_u64 =
423 u64::from_le_bytes(price.try_into().map_err(|_| EvalError::Price8BytePush)?);
424
425 let time_signed = s.pop().ok_or(EvalError::MissingTimestamp)?;
426 let time_signed = time_signed
427 .try_push()
428 .map_err(|_| EvalError::Timstamp8BytePush)?;
429 let time_signed_u64 = u64::from_le_bytes(
430 time_signed
431 .try_into()
432 .map_err(|_| EvalError::Timstamp8BytePush)?,
433 );
434 let sig = s.pop().ok_or(EvalError::MissingOracleSignature)?;
435 let schnorr_sig_sl = sig.try_push().map_err(|_| EvalError::MalformedSig)?;
436 let schnorr_sig = secp256k1::schnorr::Signature::from_slice(schnorr_sig_sl)
437 .map_err(|_| EvalError::MalformedSig)?;
438 let secp = secp256k1::Secp256k1::verification_only();
439
440 if *timestamp < time_signed_u64 {
441 return Err(EvalError::TimestampInFuture);
442 }
443
444 if check_sig_price_oracle_1(&secp, &schnorr_sig, &x_only_pk, *timestamp, price_u64)
445 {
446 let price_i64 =
447 u64::try_into(price_u64).map_err(|_| EvalError::PriceOverflow)?;
448 Ok(price_i64)
449 } else {
450 Err(EvalError::InvalidSignature)
451 }
452 }
453 }
454 }
455
456 fn satisfy<Pk: MiniscriptKey + ToPublicKey>(
458 &self,
459 env: &TxEnv,
460 s: &dyn Satisfier<Pk>,
461 ) -> Result<(i64, Satisfaction), EvalError> {
462 match &self.inner {
463 ExprInner::Const(c) => Ok((*c, Satisfaction::empty())),
464 ExprInner::CurrInputIdx => {
465 if env.idx >= env.spent_utxos.len() {
466 return Err(EvalError::UtxoIndexOutOfBounds(
467 env.idx,
468 env.spent_utxos.len(),
469 ));
470 }
471 let res = env.spent_utxos[env.idx]
472 .value
473 .explicit()
474 .map(|x| x as i64) .ok_or(EvalError::NonExplicitInput(env.idx))?;
476 Ok((res, Satisfaction::empty()))
477 }
478 ExprInner::Input(i) => {
479 let i = i.eval(env)?;
480 if i >= env.spent_utxos.len() {
481 return Err(EvalError::UtxoIndexOutOfBounds(i, env.spent_utxos.len()));
482 }
483 let res = env.spent_utxos[i]
484 .value
485 .explicit()
486 .map(|x| x as i64) .ok_or(EvalError::NonExplicitInput(i))?;
488 Ok((res, Satisfaction::empty()))
489 }
490 ExprInner::Output(i) => {
491 let i = i.eval(env)?;
492 if i >= env.tx.output.len() {
493 return Err(EvalError::OutputIndexOutOfBounds(i, env.tx.output.len()));
494 }
495 let res = env.tx.output[i]
496 .value
497 .explicit()
498 .map(|x| x as i64) .ok_or(EvalError::NonExplicitOutput(i))?;
500 Ok((res, Satisfaction::empty()))
501 }
502 ExprInner::InputIssue(i) => {
503 let i = i.eval(env)?;
504 if i >= env.tx.input.len() {
505 return Err(EvalError::InputIndexOutOfBounds(i, env.tx.input.len()));
506 }
507 let res = env.tx.input[i]
508 .asset_issuance
509 .amount
510 .explicit()
511 .map(|x| x as i64) .ok_or(EvalError::NonExplicitInputIssuance(i))?;
513 Ok((res, Satisfaction::empty()))
514 }
515 ExprInner::InputReIssue(i) => {
516 let i = i.eval(env)?;
517 if i >= env.tx.input.len() {
518 return Err(EvalError::InputIndexOutOfBounds(i, env.tx.input.len()));
519 }
520 let res = env.tx.input[i]
521 .asset_issuance
522 .inflation_keys
523 .explicit()
524 .map(|x| x as i64) .ok_or(EvalError::NonExplicitInputReIssuance(i))?;
526 Ok((res, Satisfaction::empty()))
527 }
528 ExprInner::Add(x, y) => {
529 let (x, sat_x) = x.satisfy(env, s)?;
530 let (y, sat_y) = y.satisfy(env, s)?;
531 let res = x.checked_add(y).ok_or(EvalError::AddOverflow(x, y))?;
532 let sat = Satisfaction::combine(sat_y, sat_x);
533 Ok((res, sat))
534 }
535 ExprInner::Sub(x, y) => {
536 let (x, sat_x) = x.satisfy(env, s)?;
537 let (y, sat_y) = y.satisfy(env, s)?;
538 let res = x.checked_sub(y).ok_or(EvalError::SubOverflow(x, y))?;
539 let sat = Satisfaction::combine(sat_y, sat_x);
540 Ok((res, sat))
541 }
542 ExprInner::Mul(x, y) => {
543 let (x, sat_x) = x.satisfy(env, s)?;
544 let (y, sat_y) = y.satisfy(env, s)?;
545 let res = x.checked_mul(y).ok_or(EvalError::MulOverflow(x, y))?;
546 let sat = Satisfaction::combine(sat_y, sat_x);
547 Ok((res, sat))
548 }
549 ExprInner::Div(x, y) => {
550 let (x, sat_x) = x.satisfy(env, s)?;
551 let (y, sat_y) = y.satisfy(env, s)?;
552 let res = x
553 .checked_div_euclid(y)
554 .ok_or(EvalError::DivOverflow(x, y))?;
555 let sat = Satisfaction::combine(sat_y, sat_x);
556 Ok((res, sat))
557 }
558 ExprInner::Mod(x, y) => {
559 let (x, sat_x) = x.satisfy(env, s)?;
560 let (y, sat_y) = y.satisfy(env, s)?;
561 let res = x
562 .checked_rem_euclid(y)
563 .ok_or(EvalError::ModOverflow(x, y))?;
564 let sat = Satisfaction::combine(sat_y, sat_x);
565 Ok((res, sat))
566 }
567 ExprInner::BitAnd(x, y) => {
568 let (x, sat_x) = x.satisfy(env, s)?;
569 let (y, sat_y) = y.satisfy(env, s)?;
570 let sat = Satisfaction::combine(sat_y, sat_x);
571 Ok((x & y, sat))
572 }
573 ExprInner::BitOr(x, y) => {
574 let (x, sat_x) = x.satisfy(env, s)?;
575 let (y, sat_y) = y.satisfy(env, s)?;
576 let sat = Satisfaction::combine(sat_y, sat_x);
577 Ok((x | y, sat))
578 }
579 ExprInner::Xor(x, y) => {
580 let (x, sat_x) = x.satisfy(env, s)?;
581 let (y, sat_y) = y.satisfy(env, s)?;
582 let sat = Satisfaction::combine(sat_y, sat_x);
583 Ok((x ^ y, sat))
584 }
585 ExprInner::Invert(x) => {
586 let (x, sat_x) = x.satisfy(env, s)?;
587 Ok((!x, sat_x))
588 }
589 ExprInner::Negate(x) => {
590 let (x, sat_x) = x.satisfy(env, s)?;
591 let res = x.checked_neg().ok_or(EvalError::NegOverflow(x))?;
592 Ok((res, sat_x))
593 }
594 ExprInner::PriceOracle1(pk, time) | ExprInner::PriceOracle1W(pk, time) => {
595 let pk = if let CovExtArgs::XOnlyKey(xpk) = pk {
596 xpk.0
597 } else {
598 unreachable!("PriceOracle1 constructed with only xonly key")
599 };
600 match s.lookup_price_oracle_sig(&pk, *time) {
601 Some((sig, price, time)) => {
602 let wit = Witness::Stack(vec![
603 sig.as_ref().to_vec(),
604 time.to_le_bytes().to_vec(),
605 price.to_le_bytes().to_vec(),
606 ]);
607 let sat = Satisfaction {
608 stack: wit,
609 has_sig: false, };
611 Ok((price, sat))
612 }
613 None => Err(EvalError::MissingOracleSignature),
614 }
615 }
616 }
617 }
618
619 fn push_to_builder(&self, builder: script::Builder) -> script::Builder {
621 match &self.inner {
622 ExprInner::Const(c) => builder.push_slice(&c.to_le_bytes()),
623 ExprInner::CurrInputIdx => builder
624 .push_opcode(OP_PUSHCURRENTINPUTINDEX)
625 .push_opcode(OP_INSPECTINPUTVALUE)
626 .push_int(1)
627 .push_opcode(OP_EQUALVERIFY),
628 ExprInner::Input(i) => i
629 .push_to_builder(builder)
630 .push_opcode(OP_INSPECTINPUTVALUE)
631 .push_int(1)
632 .push_opcode(OP_EQUALVERIFY),
633 ExprInner::Output(i) => i
634 .push_to_builder(builder)
635 .push_opcode(OP_INSPECTOUTPUTVALUE)
636 .push_int(1)
637 .push_opcode(OP_EQUALVERIFY),
638 ExprInner::InputIssue(i) => i
639 .push_to_builder(builder)
640 .push_opcode(OP_INSPECTINPUTISSUANCE)
641 .push_opcode(OP_DROP)
642 .push_opcode(OP_DROP)
643 .push_int(1)
644 .push_opcode(OP_EQUALVERIFY)
645 .push_opcode(OP_NIP)
646 .push_opcode(OP_NIP),
647 ExprInner::InputReIssue(i) => i
648 .push_to_builder(builder)
649 .push_opcode(OP_INSPECTINPUTISSUANCE)
650 .push_opcode(OP_DROP)
651 .push_opcode(OP_DROP)
652 .push_opcode(OP_DROP)
653 .push_opcode(OP_DROP)
654 .push_int(1)
655 .push_opcode(OP_EQUALVERIFY),
656 ExprInner::Add(x, y) => {
657 let builder = x.push_to_builder(builder);
658 let builder = y.push_to_builder(builder);
659 builder
660 .push_opcode(OP_ADD64)
661 .push_int(1)
662 .push_opcode(OP_EQUALVERIFY)
663 }
664 ExprInner::Sub(x, y) => {
665 let builder = x.push_to_builder(builder);
666 let builder = y.push_to_builder(builder);
667 builder
668 .push_opcode(OP_SUB64)
669 .push_int(1)
670 .push_opcode(OP_EQUALVERIFY)
671 }
672 ExprInner::Mul(x, y) => {
673 let builder = x.push_to_builder(builder);
674 let builder = y.push_to_builder(builder);
675 builder
676 .push_opcode(OP_MUL64)
677 .push_int(1)
678 .push_opcode(OP_EQUALVERIFY)
679 }
680 ExprInner::Div(x, y) => {
681 let builder = x.push_to_builder(builder);
682 let builder = y.push_to_builder(builder);
683 builder
684 .push_opcode(OP_DIV64)
685 .push_int(1)
686 .push_opcode(OP_EQUALVERIFY)
687 .push_opcode(OP_NIP)
688 }
689 ExprInner::Mod(x, y) => {
690 let builder = x.push_to_builder(builder);
691 let builder = y.push_to_builder(builder);
692 builder
693 .push_opcode(OP_DIV64)
694 .push_int(1)
695 .push_opcode(OP_EQUALVERIFY)
696 .push_opcode(OP_DROP)
697 }
698 ExprInner::BitAnd(x, y) => {
699 let builder = x.push_to_builder(builder);
700 let builder = y.push_to_builder(builder);
701 builder.push_opcode(OP_AND)
702 }
703 ExprInner::BitOr(x, y) => {
704 let builder = x.push_to_builder(builder);
705 let builder = y.push_to_builder(builder);
706 builder.push_opcode(OP_OR)
707 }
708 ExprInner::Xor(x, y) => {
709 let builder = x.push_to_builder(builder);
710 let builder = y.push_to_builder(builder);
711 builder.push_opcode(OP_XOR)
712 }
713 ExprInner::Invert(x) => x.push_to_builder(builder).push_opcode(OP_INVERT),
714 ExprInner::Negate(x) => x
715 .push_to_builder(builder)
716 .push_opcode(OP_NEG64)
717 .push_int(1)
718 .push_opcode(OP_EQUALVERIFY),
719 ExprInner::PriceOracle1(pk, t) => {
720 let xpk = if let CovExtArgs::XOnlyKey(xpk) = pk {
721 xpk.0
722 } else {
723 unreachable!("PriceOracle1 constructor ensures that CovExtArgs is XOnlyKey");
724 };
725 builder
727 .push_opcode(OP_2DUP)
728 .push_opcode(OP_TOALTSTACK)
729 .push_slice(&t.to_le_bytes())
730 .push_opcode(OP_GREATERTHANOREQUAL64)
731 .push_opcode(OP_VERIFY)
732 .push_opcode(OP_CAT)
733 .push_opcode(OP_SHA256)
734 .push_slice(&xpk.serialize())
735 .push_opcode(OP_CHECKSIGFROMSTACKVERIFY)
736 .push_opcode(OP_FROMALTSTACK)
737 }
738 ExprInner::PriceOracle1W(pk, t) => {
739 let xpk = if let CovExtArgs::XOnlyKey(xpk) = pk {
740 xpk.0
741 } else {
742 unreachable!("PriceOracle1 constructor ensures that CovExtArgs is XOnlyKey");
743 };
744 builder
746 .push_opcode(OP_TOALTSTACK)
747 .push_opcode(OP_2DUP)
748 .push_opcode(OP_TOALTSTACK)
749 .push_slice(&t.to_le_bytes())
750 .push_opcode(OP_GREATERTHANOREQUAL64)
751 .push_opcode(OP_VERIFY)
752 .push_opcode(OP_CAT)
753 .push_opcode(OP_SHA256)
754 .push_slice(&xpk.serialize())
755 .push_opcode(OP_CHECKSIGFROMSTACKVERIFY)
756 .push_opcode(OP_FROMALTSTACK)
757 .push_opcode(OP_FROMALTSTACK)
758 .push_opcode(OP_SWAP)
759 }
760 }
761 }
762
763 fn from_tokens(tokens: &[Tk], end_pos: usize) -> Option<(Self, usize)> {
766 let tks = tokens;
767 let e = end_pos; if let Some(Tk::Bytes8(bytes)) = tks.get(e.checked_sub(1)?) {
776 let mut le_bytes = [0u8; 8];
777 le_bytes.copy_from_slice(bytes);
778 let expr = Expr::from_inner(ExprInner::Const(i64::from_le_bytes(le_bytes)));
779 Some((expr, e - 1))
780 } else if let Some(Tk::Invert) = tks.get(e.checked_sub(1)?) {
781 let (x, end_pos) = Self::from_tokens(tokens, e - 1)?;
782 let expr = Expr::from_inner(ExprInner::Invert(Box::new(x)));
783 Some((expr, end_pos))
784 } else if let Some(Tk::And) = tks.get(e.checked_sub(1)?) {
785 let (y, end_pos) = Self::from_tokens(tokens, e - 1)?;
786 let (x, end_pos) = Self::from_tokens(tokens, end_pos)?;
787 let expr = Expr::from_inner(ExprInner::BitAnd(Box::new(x), Box::new(y)));
788 Some((expr, end_pos))
789 } else if let Some(Tk::Or) = tks.get(e.checked_sub(1)?) {
790 let (y, end_pos) = Self::from_tokens(tokens, e - 1)?;
791 let (x, end_pos) = Self::from_tokens(tokens, end_pos)?;
792 let expr = Expr::from_inner(ExprInner::BitOr(Box::new(x), Box::new(y)));
793 Some((expr, end_pos))
794 } else if let Some(Tk::Xor) = tks.get(e.checked_sub(1)?) {
795 let (y, end_pos) = Self::from_tokens(tokens, e - 1)?;
796 let (x, end_pos) = Self::from_tokens(tokens, end_pos)?;
797 let expr = Expr::from_inner(ExprInner::Xor(Box::new(x), Box::new(y)));
798 Some((expr, end_pos))
799 } else if let Some(&[Tk::Neg64, Tk::Num(1), Tk::Equal, Tk::Verify]) =
800 tks.get(e.checked_sub(4)?..e)
801 {
802 let (x, end_pos) = Self::from_tokens(tokens, e - 4)?;
803 let expr = Expr::from_inner(ExprInner::Negate(Box::new(x)));
804 Some((expr, end_pos))
805 } else if let Some(&[Tk::Add64, Tk::Num(1), Tk::Equal, Tk::Verify]) =
806 tks.get(e.checked_sub(4)?..e)
807 {
808 let (y, end_pos) = Self::from_tokens(tokens, e - 4)?;
809 let (x, end_pos) = Self::from_tokens(tokens, end_pos)?;
810 let expr = Expr::from_inner(ExprInner::Add(Box::new(x), Box::new(y)));
811 Some((expr, end_pos))
812 } else if let Some(&[Tk::Sub64, Tk::Num(1), Tk::Equal, Tk::Verify]) =
813 tks.get(e.checked_sub(4)?..e)
814 {
815 let (y, end_pos) = Self::from_tokens(tokens, e - 4)?;
816 let (x, end_pos) = Self::from_tokens(tokens, end_pos)?;
817 let expr = Expr::from_inner(ExprInner::Sub(Box::new(x), Box::new(y)));
818 Some((expr, end_pos))
819 } else if let Some(&[Tk::Mul64, Tk::Num(1), Tk::Equal, Tk::Verify]) =
820 tks.get(e.checked_sub(4)?..e)
821 {
822 let (y, end_pos) = Self::from_tokens(tokens, e - 4)?;
823 let (x, end_pos) = Self::from_tokens(tokens, end_pos)?;
824 let expr = Expr::from_inner(ExprInner::Mul(Box::new(x), Box::new(y)));
825 Some((expr, end_pos))
826 } else if let Some(&[Tk::CurrInp, Tk::InpValue, Tk::Num(1), Tk::Equal, Tk::Verify]) =
827 tks.get(e.checked_sub(5)?..e)
828 {
829 Some((Expr::from_inner(ExprInner::CurrInputIdx), e - 5))
830 } else if let Some(&[Tk::Div64, Tk::Num(1), Tk::Equal, Tk::Verify, Tk::Nip]) =
831 tks.get(e.checked_sub(5)?..e)
832 {
833 let (y, end_pos) = Self::from_tokens(tokens, e - 5)?;
834 let (x, end_pos) = Self::from_tokens(tokens, end_pos)?;
835 let expr = Expr::from_inner(ExprInner::Div(Box::new(x), Box::new(y)));
836 Some((expr, end_pos))
837 } else if let Some(&[Tk::Div64, Tk::Num(1), Tk::Equal, Tk::Verify, Tk::Drop]) =
838 tks.get(e.checked_sub(5)?..e)
839 {
840 let (y, end_pos) = Self::from_tokens(tokens, e - 5)?;
841 let (x, end_pos) = Self::from_tokens(tokens, end_pos)?;
842 let expr = Expr::from_inner(ExprInner::Mod(Box::new(x), Box::new(y)));
843 Some((expr, end_pos))
844 } else if let Some(&[Tk::InpValue, Tk::Num(1), Tk::Equal, Tk::Verify]) =
845 tks.get(e.checked_sub(4)?..e)
846 {
847 let (i, e) = IdxExpr::from_tokens(tks, e - 4)?;
848 Some((Expr::from_inner(ExprInner::Input(i)), e))
849 } else if let Some(&[Tk::OutValue, Tk::Num(1), Tk::Equal, Tk::Verify]) =
850 tks.get(e.checked_sub(4)?..e)
851 {
852 let (i, e) = IdxExpr::from_tokens(tks, e - 4)?;
853 Some((Expr::from_inner(ExprInner::Output(i)), e))
854 } else if let Some(
855 &[Tk::InpIssue, Tk::Drop, Tk::Drop, Tk::Num(1), Tk::Equal, Tk::Verify, Tk::Nip, Tk::Nip],
856 ) = tks.get(e.checked_sub(8)?..e)
857 {
858 let (i, e) = IdxExpr::from_tokens(tks, e - 8)?;
859 Some((Expr::from_inner(ExprInner::InputIssue(i)), e))
860 } else if let Some(
861 &[Tk::InpIssue, Tk::Drop, Tk::Drop, Tk::Drop, Tk::Drop, Tk::Num(1), Tk::Equal, Tk::Verify],
862 ) = tks.get(e.checked_sub(8)?..e)
863 {
864 let (i, e) = IdxExpr::from_tokens(tks, e - 8)?;
865 Some((Expr::from_inner(ExprInner::InputReIssue(i)), e))
866 } else if let Some(
867 &[Tk::Dup2, Tk::ToAltStack, Tk::Bytes8(time), Tk::Geq64, Tk::Verify, Tk::Cat, Tk::Sha256, Tk::Bytes32(xpk), Tk::CheckSigFromStackVerify, Tk::FromAltStack],
868 ) = tks.get(e.checked_sub(10)?..e)
869 {
870 let time = u64::from_le_bytes(time.try_into().expect("8 bytes"));
871 let xpk = XOnlyPublicKey::from_slice(xpk).ok()?;
872 let key = CovExtArgs::csfs_key(xpk);
873 let expr = Expr::from_inner(ExprInner::PriceOracle1(key, time));
874 Some((expr, e - 10))
875 } else if let Some(
876 &[Tk::ToAltStack, Tk::Dup2, Tk::ToAltStack, Tk::Bytes8(time), Tk::Geq64, Tk::Verify, Tk::Cat, Tk::Sha256, Tk::Bytes32(xpk), Tk::CheckSigFromStackVerify, Tk::FromAltStack, Tk::FromAltStack, Tk::Swap],
877 ) = tks.get(e.checked_sub(13)?..e)
878 {
879 let time = u64::from_le_bytes(time.try_into().expect("8 bytes"));
880 let xpk = XOnlyPublicKey::from_slice(xpk).ok()?;
881 let key = CovExtArgs::csfs_key(xpk);
882 let expr = Expr::from_inner(ExprInner::PriceOracle1W(key, time));
883 Some((expr, e - 13))
884 } else {
885 None
886 }
887 }
888}
889
890#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Debug)]
900pub enum ArithInner<T: ExtParam> {
901 Eq(Expr<T>, Expr<T>),
904 Lt(Expr<T>, Expr<T>),
907 Leq(Expr<T>, Expr<T>),
910 Gt(Expr<T>, Expr<T>),
913 Geq(Expr<T>, Expr<T>),
916}
917
918#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Clone)]
924pub struct Arith<T: ExtParam> {
925 expr: ArithInner<T>,
927}
928
929impl<T: ExtParam> Arith<T> {
930 pub fn new(expr: ArithInner<T>) -> Result<Self, TypeError> {
932 {
933 let (a, b) = match &expr {
935 ArithInner::Eq(ref a, ref b)
936 | ArithInner::Lt(ref a, ref b)
937 | ArithInner::Leq(ref a, ref b)
938 | ArithInner::Gt(ref a, ref b)
939 | ArithInner::Geq(ref a, ref b) => (a, b),
940 };
941 let mut iter = a.iter_terminals();
942 if let Some(ExprInner::PriceOracle1W(_, _)) = iter.next() {
943 return Err(TypeError::PriceOracle1WFirst);
944 }
945 if iter.any(|x| matches!(x, ExprInner::PriceOracle1(..))) {
947 return Err(TypeError::PriceOracle1Missing);
948 }
949 if b.iter_terminals()
951 .any(|x| matches!(x, ExprInner::PriceOracle1(..)))
952 {
953 return Err(TypeError::PriceOracle1Missing);
954 }
955 }
956 Ok(Arith { expr })
957 }
958
959 pub fn inner(&self) -> &ArithInner<T> {
961 &self.expr
962 }
963}
964
965impl<T: ExtParam> Arith<T> {
966 pub fn depth(&self) -> usize {
968 match &self.expr {
969 ArithInner::Eq(x, y)
970 | ArithInner::Lt(x, y)
971 | ArithInner::Leq(x, y)
972 | ArithInner::Gt(x, y)
973 | ArithInner::Geq(x, y) => cmp::max(x.depth, y.depth),
974 }
975 }
976
977 pub fn script_size(&self) -> usize {
979 match &self.expr {
980 ArithInner::Eq(x, y)
981 | ArithInner::Lt(x, y)
982 | ArithInner::Leq(x, y)
983 | ArithInner::Gt(x, y)
984 | ArithInner::Geq(x, y) => x.script_size + y.script_size + 1,
985 }
986 }
987}
988
989impl Arith<CovExtArgs> {
990 pub fn eval(&self, env: &TxEnv, s: &mut interpreter::Stack) -> Result<bool, EvalError> {
992 let res = match &self.expr {
993 ArithInner::Eq(x, y) => x.eval(env, s)? == y.eval(env, s)?,
994 ArithInner::Lt(x, y) => x.eval(env, s)? < y.eval(env, s)?,
995 ArithInner::Leq(x, y) => x.eval(env, s)? <= y.eval(env, s)?,
996 ArithInner::Gt(x, y) => x.eval(env, s)? > y.eval(env, s)?,
997 ArithInner::Geq(x, y) => x.eval(env, s)? >= y.eval(env, s)?,
998 };
999 Ok(res)
1000 }
1001
1002 pub fn satisfy_helper<Pk: ToPublicKey>(
1008 &self,
1009 env: &TxEnv,
1010 sat: &dyn Satisfier<Pk>,
1011 ) -> Result<Satisfaction, EvalError> {
1012 let (res, sat_a, sat_b) = match &self.expr {
1013 ArithInner::Eq(a, b) => {
1014 let (a, sat_a) = a.satisfy(env, sat)?;
1015 let (b, sat_b) = b.satisfy(env, sat)?;
1016 (a == b, sat_a, sat_b)
1017 }
1018 ArithInner::Lt(a, b) => {
1019 let (a, sat_a) = a.satisfy(env, sat)?;
1020 let (b, sat_b) = b.satisfy(env, sat)?;
1021 (a < b, sat_a, sat_b)
1022 }
1023 ArithInner::Leq(a, b) => {
1024 let (a, sat_a) = a.satisfy(env, sat)?;
1025 let (b, sat_b) = b.satisfy(env, sat)?;
1026 (a <= b, sat_a, sat_b)
1027 }
1028 ArithInner::Gt(a, b) => {
1029 let (a, sat_a) = a.satisfy(env, sat)?;
1030 let (b, sat_b) = b.satisfy(env, sat)?;
1031 (a > b, sat_a, sat_b)
1032 }
1033 ArithInner::Geq(a, b) => {
1034 let (a, sat_a) = a.satisfy(env, sat)?;
1035 let (b, sat_b) = b.satisfy(env, sat)?;
1036 (a >= b, sat_a, sat_b)
1037 }
1038 };
1039 if res {
1040 Ok(Satisfaction::combine(sat_b, sat_a))
1041 } else {
1042 Ok(Satisfaction::impossible())
1043 }
1044 }
1045
1046 pub fn push_to_builder(&self, builder: script::Builder) -> script::Builder {
1048 match &self.expr {
1049 ArithInner::Eq(x, y) => {
1050 let builder = x.push_to_builder(builder);
1051 let builder = y.push_to_builder(builder);
1052 builder.push_opcode(OP_EQUAL)
1053 }
1054 ArithInner::Lt(x, y) => {
1055 let builder = x.push_to_builder(builder);
1056 let builder = y.push_to_builder(builder);
1057 builder.push_opcode(OP_LESSTHAN64)
1058 }
1059 ArithInner::Leq(x, y) => {
1060 let builder = x.push_to_builder(builder);
1061 let builder = y.push_to_builder(builder);
1062 builder.push_opcode(OP_LESSTHANOREQUAL64)
1063 }
1064 ArithInner::Gt(x, y) => {
1065 let builder = x.push_to_builder(builder);
1066 let builder = y.push_to_builder(builder);
1067 builder.push_opcode(OP_GREATERTHAN64)
1068 }
1069 ArithInner::Geq(x, y) => {
1070 let builder = x.push_to_builder(builder);
1071 let builder = y.push_to_builder(builder);
1072 builder.push_opcode(OP_GREATERTHANOREQUAL64)
1073 }
1074 }
1075 }
1076
1077 fn from_tokens(tokens: &[Tk]) -> Option<(Self, usize)> {
1084 let last_opcode = tokens.last()?;
1085 let (y, pos) = Expr::from_tokens(tokens, tokens.len() - 1)?;
1086 let (x, pos) = Expr::from_tokens(tokens, pos)?;
1087 let (inner, pos) = match last_opcode {
1088 Tk::Equal => (ArithInner::Eq(x, y), pos),
1089 Tk::Le64 => (ArithInner::Lt(x, y), pos),
1090 Tk::Leq64 => (ArithInner::Leq(x, y), pos),
1091 Tk::Ge64 => (ArithInner::Gt(x, y), pos),
1092 Tk::Geq64 => (ArithInner::Geq(x, y), pos),
1093 _ => return None,
1094 };
1095 Some((Arith::new(inner).ok()?, pos))
1096 }
1097}
1098
1099impl<T: ExtParam> fmt::Display for Expr<T> {
1100 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1101 match &self.inner {
1102 ExprInner::Const(c) => write!(f, "{}", c),
1103 ExprInner::CurrInputIdx => write!(f, "curr_inp_v"),
1104 ExprInner::Input(i) => write!(f, "inp_v({})", i),
1105 ExprInner::Output(i) => write!(f, "out_v({})", i),
1106 ExprInner::InputIssue(i) => write!(f, "inp_issue_v({})", i),
1107 ExprInner::InputReIssue(i) => write!(f, "inp_reissue_v({})", i),
1108 ExprInner::Add(x, y) => write!(f, "add({},{})", x, y),
1109 ExprInner::Sub(x, y) => write!(f, "sub({},{})", x, y),
1110 ExprInner::Mul(x, y) => write!(f, "mul({},{})", x, y),
1111 ExprInner::Div(x, y) => write!(f, "div({},{})", x, y),
1112 ExprInner::Mod(x, y) => write!(f, "mod({},{})", x, y),
1113 ExprInner::BitAnd(x, y) => write!(f, "bitand({},{})", x, y), ExprInner::BitOr(x, y) => write!(f, "bitor({},{})", x, y),
1115 ExprInner::Xor(x, y) => write!(f, "bitxor({},{})", x, y),
1116 ExprInner::Invert(x) => write!(f, "bitinv({})", x),
1117 ExprInner::Negate(x) => write!(f, "neg({})", x),
1118 ExprInner::PriceOracle1(pk, t) => write!(f, "price_oracle1({},{})", pk, t),
1119 ExprInner::PriceOracle1W(pk, t) => write!(f, "price_oracle1_w({},{})", pk, t), }
1121 }
1122}
1123
1124impl<T: ExtParam> fmt::Debug for Expr<T> {
1125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1126 match &self.inner {
1127 ExprInner::Const(c) => write!(f, "{:?}", c),
1128 ExprInner::CurrInputIdx => write!(f, "curr_inp_v"),
1129 ExprInner::Input(i) => write!(f, "inp_v({:?})", i),
1130 ExprInner::Output(i) => write!(f, "out_v({:?})", i),
1131 ExprInner::InputIssue(i) => write!(f, "inp_issue_v({:?})", i),
1132 ExprInner::InputReIssue(i) => write!(f, "inp_reissue_v({:?})", i),
1133 ExprInner::Add(x, y) => write!(f, "add({:?},{:?})", x, y),
1134 ExprInner::Sub(x, y) => write!(f, "sub({:?},{:?})", x, y),
1135 ExprInner::Mul(x, y) => write!(f, "mul({:?},{:?})", x, y),
1136 ExprInner::Div(x, y) => write!(f, "div({:?},{:?})", x, y),
1137 ExprInner::Mod(x, y) => write!(f, "mod({:?},{:?})", x, y),
1138 ExprInner::BitAnd(x, y) => write!(f, "bitand({:?},{:?})", x, y), ExprInner::BitOr(x, y) => write!(f, "bitor({:?},{:?})", x, y),
1140 ExprInner::Xor(x, y) => write!(f, "bitxor({:?},{:?})", x, y),
1141 ExprInner::Invert(x) => write!(f, "bitinv({:?})", x),
1142 ExprInner::Negate(x) => write!(f, "neg({:?})", x),
1143 ExprInner::PriceOracle1(pk, t) => write!(f, "price_oracle1({:?},{:?})", pk, t),
1144 ExprInner::PriceOracle1W(pk, t) => write!(f, "price_oracle1_w({:?},{:?})", pk, t), }
1146 }
1147}
1148
1149impl<T: ExtParam> FromStr for Expr<T> {
1150 type Err = Error;
1151
1152 fn from_str(s: &str) -> Result<Self, Self::Err> {
1153 let top = expression::Tree::from_str(s)?;
1154 Self::from_tree(&top)
1155 }
1156}
1157
1158impl<T: ExtParam> FromTree for Box<Expr<T>> {
1159 fn from_tree(top: &expression::Tree<'_>) -> Result<Self, Error> {
1160 expression::FromTree::from_tree(top).map(Box::new)
1161 }
1162}
1163
1164impl<T: ExtParam> FromTree for Expr<T> {
1165 fn from_tree(top: &expression::Tree<'_>) -> Result<Self, Error> {
1166 fn unary<F, T: ExtParam>(top: &expression::Tree<'_>, frag: F) -> Result<Expr<T>, Error>
1167 where
1168 F: FnOnce(Box<Expr<T>>) -> ExprInner<T>,
1169 {
1170 let l: Expr<T> = FromTree::from_tree(&top.args[0])?;
1171 Ok(Expr::from_inner(frag(Box::new(l))))
1172 }
1173
1174 fn binary<F, T: ExtParam>(top: &expression::Tree<'_>, frag: F) -> Result<Expr<T>, Error>
1175 where
1176 F: FnOnce(Box<Expr<T>>, Box<Expr<T>>) -> ExprInner<T>,
1177 {
1178 let l: Expr<T> = FromTree::from_tree(&top.args[0])?;
1179 let r: Expr<T> = FromTree::from_tree(&top.args[1])?;
1180 Ok(Expr::from_inner(frag(Box::new(l), Box::new(r))))
1181 }
1182 match (top.name, top.args.len()) {
1183 ("inp_v", 1) => Ok(Expr::from_inner(expression::unary(top, ExprInner::Input)?)),
1184 ("curr_inp_v", 0) => Ok(Expr::from_inner(ExprInner::CurrInputIdx)),
1185 ("out_v", 1) => Ok(Expr::from_inner(expression::unary(top, ExprInner::Output)?)),
1186 ("inp_issue_v", 1) => Ok(Expr::from_inner(expression::unary(
1187 top,
1188 ExprInner::InputIssue,
1189 )?)),
1190 ("inp_reissue_v", 1) => Ok(Expr::from_inner(expression::unary(
1191 top,
1192 ExprInner::InputReIssue,
1193 )?)),
1194 ("price_oracle1", 2) | ("price_oracle1_w", 2) => {
1195 if !top.args[0].args.is_empty() || !top.args[1].args.is_empty() {
1196 return Err(Error::Unexpected(String::from(
1197 "price_oracle1 expects 2 terminal arguments",
1198 )));
1199 }
1200 let pk = T::arg_from_str(top.args[0].name, top.name, 0)?;
1201 let t: u64 = expression::parse_num::<u64>(top.args[1].name)?;
1202 if top.name == "price_oracle1" {
1203 Ok(Expr::from_inner(ExprInner::PriceOracle1(pk, t)))
1204 } else {
1205 Ok(Expr::from_inner(ExprInner::PriceOracle1W(pk, t)))
1206 }
1207 }
1208 ("add", 2) => binary(top, ExprInner::Add),
1209 ("sub", 2) => binary(top, ExprInner::Sub),
1210 ("mul", 2) => binary(top, ExprInner::Mul),
1211 ("div", 2) => binary(top, ExprInner::Div),
1212 ("mod", 2) => binary(top, ExprInner::Mod),
1213 ("bitand", 2) => binary(top, ExprInner::BitAnd),
1214 ("bitor", 2) => binary(top, ExprInner::BitOr),
1215 ("bitxor", 2) => binary(top, ExprInner::Xor),
1216 ("bitinv", 1) => unary(top, ExprInner::Invert),
1217 ("neg", 1) => unary(top, ExprInner::Negate),
1218 (_num, 0) => {
1219 Ok(Expr {
1220 inner: expression::terminal(top, expression::parse_num::<i64>)
1221 .map(ExprInner::Const)?,
1222 script_size: 8 + 1, depth: 0,
1224 })
1225 }
1226 _ => Err(Error::Unexpected(format!(
1227 "{}({} args) while parsing Extension",
1228 top.name,
1229 top.args.len(),
1230 ))),
1231 }
1232 }
1233}
1234
1235impl<T: ExtParam> FromStr for ArithInner<T> {
1236 type Err = Error;
1237
1238 fn from_str(s: &str) -> Result<Self, Self::Err> {
1239 let top = expression::Tree::from_str(s)?;
1240 Self::from_tree(&top)
1241 }
1242}
1243
1244impl<T: ExtParam> FromStr for Arith<T> {
1245 type Err = Error;
1246
1247 fn from_str(s: &str) -> Result<Self, Self::Err> {
1248 let inner = ArithInner::from_str(s)?;
1249 Arith::new(inner).map_err(|_| Error::Unexpected(String::from("Arith::new")))
1250 }
1251}
1252
1253impl<T: ExtParam> FromTree for Box<ArithInner<T>> {
1254 fn from_tree(top: &expression::Tree<'_>) -> Result<Self, Error> {
1255 ArithInner::from_tree(top).map(Box::new)
1256 }
1257}
1258
1259impl<T: ExtParam> FromTree for ArithInner<T> {
1260 fn from_tree(top: &expression::Tree<'_>) -> Result<Self, Error> {
1261 match (top.name, top.args.len()) {
1262 ("num64_eq", 2) => expression::binary(top, ArithInner::Eq),
1264 ("num64_geq", 2) => expression::binary(top, ArithInner::Geq),
1265 ("num64_gt", 2) => expression::binary(top, ArithInner::Gt),
1266 ("num64_lt", 2) => expression::binary(top, ArithInner::Lt),
1267 ("num64_leq", 2) => expression::binary(top, ArithInner::Leq),
1268 _ => Err(Error::Unexpected(format!(
1269 "{}({} args) while parsing Extension",
1270 top.name,
1271 top.args.len(),
1272 ))),
1273 }
1274 }
1275}
1276
1277impl<T: ExtParam> fmt::Display for Arith<T> {
1278 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1279 match &self.expr {
1280 ArithInner::Eq(x, y) => write!(f, "num64_eq({},{})", x, y),
1281 ArithInner::Leq(x, y) => write!(f, "num64_leq({},{})", x, y),
1282 ArithInner::Lt(x, y) => write!(f, "num64_lt({},{})", x, y),
1283 ArithInner::Geq(x, y) => write!(f, "num64_geq({},{})", x, y),
1284 ArithInner::Gt(x, y) => write!(f, "num64_gt({},{})", x, y),
1285 }
1286 }
1287}
1288
1289impl<T: ExtParam> fmt::Debug for Arith<T> {
1290 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1291 match &self.expr {
1292 ArithInner::Eq(x, y) => write!(f, "num64_eq({:?},{:?})", x, y),
1293 ArithInner::Leq(x, y) => write!(f, "num64_leq({:?},{:?})", x, y),
1294 ArithInner::Lt(x, y) => write!(f, "num64_lt({:?},{:?})", x, y),
1295 ArithInner::Geq(x, y) => write!(f, "num64_geq({:?},{:?})", x, y),
1296 ArithInner::Gt(x, y) => write!(f, "num64_gt({:?},{:?})", x, y),
1297 }
1298 }
1299}
1300
1301impl<T: ExtParam> Extension for Arith<T> {
1302 fn corr_prop(&self) -> Correctness {
1303 Correctness {
1304 base: Base::B,
1305 input: Input::Zero, dissatisfiable: false, unit: true,
1308 }
1309 }
1310
1311 fn mall_prop(&self) -> Malleability {
1312 Malleability {
1313 dissat: Dissat::None, safe: false, non_malleable: true, }
1318 }
1319
1320 fn extra_prop(&self) -> ExtData {
1321 ExtData {
1322 pk_cost: self.script_size(), has_free_verify: false,
1324 stack_elem_count_sat: Some(0),
1325 stack_elem_count_dissat: Some(0),
1326 max_sat_size: Some((0, 0)),
1327 max_dissat_size: Some((0, 0)),
1328 timelock_info: TimelockInfo::default(),
1329 exec_stack_elem_count_sat: Some(self.depth()),
1330 exec_stack_elem_count_dissat: Some(self.depth()),
1331 ops: OpLimits {
1332 count: 0,
1335 sat: Some(0),
1336 nsat: Some(0),
1337 },
1338 }
1339 }
1340
1341 fn script_size(&self) -> usize {
1342 self.script_size()
1343 }
1344
1345 fn segwit_ctx_checks(&self) -> Result<(), miniscript::context::ScriptContextError> {
1346 Err(ScriptContextError::ExtensionError(
1348 "Arith opcodes only available in Taproot".to_string(),
1349 ))
1350 }
1351
1352 fn from_name_tree(
1353 name: &str,
1354 children: &[expression::Tree<'_>],
1355 ) -> Result<Self, FromTokenIterError> {
1356 let tree = Tree {
1357 name,
1358 args: children.to_vec(), };
1361 let inner = ArithInner::from_tree(&tree).map_err(|_| FromTokenIterError)?;
1362 Arith::new(inner).map_err(|_e| FromTokenIterError)
1363 }
1364}
1365
1366impl ParseableExt for Arith<CovExtArgs> {
1367 fn satisfy<Pk, S>(&self, sat: &S) -> Satisfaction
1368 where
1369 Pk: ToPublicKey,
1370 S: Satisfier<Pk>,
1371 {
1372 let (tx, utxos, curr_idx) = match (
1373 sat.lookup_tx(),
1374 sat.lookup_spent_utxos(),
1375 sat.lookup_curr_inp(),
1376 ) {
1377 (Some(tx), Some(utxos), Some(curr_idx)) => (tx, utxos, curr_idx),
1378 _ => return Satisfaction::impossible(),
1379 };
1380 let env = match TxEnv::new(tx, utxos, curr_idx) {
1381 Some(env) => env,
1382 None => return Satisfaction::impossible(),
1383 };
1384 self.satisfy_helper(&env, sat)
1385 .unwrap_or(Satisfaction::empty())
1386 }
1387
1388 fn dissatisfy<Pk, S>(&self, _sat: &S) -> Satisfaction
1389 where
1390 Pk: ToPublicKey,
1391 S: Satisfier<Pk>,
1392 {
1393 Satisfaction::impossible()
1395 }
1396
1397 fn push_to_builder(&self, builder: elements::script::Builder) -> elements::script::Builder {
1398 self.push_to_builder(builder)
1399 }
1400
1401 fn from_token_iter(tokens: &mut TokenIter<'_>) -> Result<Self, FromTokenIterError> {
1402 let len = tokens.len();
1403 match Self::from_tokens(tokens.as_inner_mut()) {
1404 Some((res, last_pos)) => {
1405 tokens.advance(len - last_pos).ok_or(FromTokenIterError)?;
1406 Ok(res)
1407 }
1408 None => Err(FromTokenIterError),
1409 }
1410 }
1411
1412 fn evaluate(
1413 &self,
1414 stack: &mut interpreter::Stack,
1415 txenv: Option<&TxEnv>,
1416 ) -> Result<bool, interpreter::Error> {
1417 let txenv = txenv
1418 .as_ref()
1419 .ok_or(interpreter::Error::ArithError(EvalError::TxEnvNotPresent))?;
1420
1421 match self.eval(txenv, stack) {
1422 Ok(true) => {
1423 stack.push(interpreter::Element::Satisfied);
1424 Ok(true)
1425 }
1426 Ok(false) => {
1427 stack.push(interpreter::Element::Dissatisfied);
1428 Ok(false)
1429 }
1430 Err(e) => Err(interpreter::Error::ArithError(e)),
1431 }
1432 }
1433}
1434
1435#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone)]
1437pub enum EvalError {
1438 TxEnvNotPresent,
1440 UtxoIndexOutOfBounds(usize, usize),
1442 NonExplicitInput(usize),
1444 OutputIndexOutOfBounds(usize, usize),
1446 NonExplicitOutput(usize),
1448 InputIndexOutOfBounds(usize, usize),
1450 NonExplicitInputIssuance(usize),
1452 NonExplicitInputReIssuance(usize),
1454 AddOverflow(i64, i64),
1456 SubOverflow(i64, i64),
1458 MulOverflow(i64, i64),
1460 DivOverflow(i64, i64),
1462 ModOverflow(i64, i64),
1464 NegOverflow(i64),
1466 MissingPrice,
1468 Price8BytePush,
1470 MissingTimestamp,
1472 Timstamp8BytePush,
1474 MissingOracleSignature,
1476 MalformedSig,
1478 TimestampInFuture,
1480 InvalidSignature,
1482 PriceOverflow,
1484}
1485
1486impl error::Error for EvalError {}
1487
1488impl fmt::Display for EvalError {
1489 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1490 match self {
1491 EvalError::UtxoIndexOutOfBounds(i, len) => {
1492 write!(f, "Utxo index {} out of bounds {}", i, len)
1493 }
1494 EvalError::NonExplicitInput(i) => write!(f, "Non explicit input {}", i),
1495 EvalError::OutputIndexOutOfBounds(i, len) => {
1496 write!(f, "Output index {} out of bounds {}", i, len)
1497 }
1498 EvalError::NonExplicitOutput(i) => {
1499 write!(f, "Non explicit output amount at index {}", i)
1500 }
1501 EvalError::InputIndexOutOfBounds(i, len) => {
1502 write!(f, "Input index {} out of bounds {}", i, len)
1503 }
1504 EvalError::NonExplicitInputIssuance(i) => {
1505 write!(f, "Non explicit input issuance amount at index {}", i)
1506 }
1507 EvalError::NonExplicitInputReIssuance(i) => {
1508 write!(f, "Non explicit input reissuance amount at index {}", i)
1509 }
1510 EvalError::AddOverflow(x, y) => write!(f, "Add overflow {} {}", x, y),
1511 EvalError::SubOverflow(x, y) => write!(f, "Sub overflow {} {}", x, y),
1512 EvalError::MulOverflow(x, y) => write!(f, "Mul overflow {} {}", x, y),
1513 EvalError::DivOverflow(x, y) => write!(f, "Div overflow {} {}", x, y),
1514 EvalError::ModOverflow(x, y) => write!(f, "Mod overflow {} {}", x, y),
1515 EvalError::NegOverflow(x) => write!(f, "Neg overflow {}", x),
1516 EvalError::TxEnvNotPresent => write!(
1517 f,
1518 "Transaction must be supplied to extension to arithmetic evaluation"
1519 ),
1520 EvalError::MissingPrice => write!(f, "Missing price"),
1521 EvalError::Price8BytePush => write!(f, "Price 8 byte push"),
1522 EvalError::MissingTimestamp => write!(f, "Missing timestamp"),
1523 EvalError::Timstamp8BytePush => write!(f, "Timestamp 8 byte push"),
1524 EvalError::MissingOracleSignature => write!(f, "Missing price oracle signature"),
1525 EvalError::MalformedSig => write!(f, "Malformed price oracle signature"),
1526 EvalError::TimestampInFuture => write!(f, "Oracle Timestamp in future"),
1527 EvalError::InvalidSignature => write!(f, "Invalid price oracle signature"),
1528 EvalError::PriceOverflow => write!(f, "Price overflow (must be 64 bit integer)"),
1529 }
1530 }
1531}
1532
1533impl<PArg, QArg> TranslateExtParam<PArg, QArg> for Arith<PArg>
1534where
1535 PArg: ExtParam,
1536 QArg: ExtParam,
1537{
1538 type Output = Arith<QArg>;
1539
1540 fn translate_ext<T, E>(&self, t: &mut T) -> Result<Self::Output, E>
1541 where
1542 T: ExtParamTranslator<PArg, QArg, E>,
1543 {
1544 let res = match &self.expr {
1545 ArithInner::Eq(a, b) => ArithInner::Eq(a.translate_ext(t)?, b.translate_ext(t)?),
1546 ArithInner::Lt(a, b) => ArithInner::Lt(a.translate_ext(t)?, b.translate_ext(t)?),
1547 ArithInner::Leq(a, b) => ArithInner::Leq(a.translate_ext(t)?, b.translate_ext(t)?),
1548 ArithInner::Gt(a, b) => ArithInner::Gt(a.translate_ext(t)?, b.translate_ext(t)?),
1549 ArithInner::Geq(a, b) => ArithInner::Geq(a.translate_ext(t)?, b.translate_ext(t)?),
1550 };
1551 Ok(Arith::new(res).expect("Type check must succeed"))
1552 }
1553}
1554
1555impl<PArg, QArg> TranslateExtParam<PArg, QArg> for Expr<PArg>
1556where
1557 PArg: ExtParam,
1558 QArg: ExtParam,
1559{
1560 type Output = Expr<QArg>;
1561
1562 fn translate_ext<T, E>(&self, t: &mut T) -> Result<Self::Output, E>
1563 where
1564 T: ExtParamTranslator<PArg, QArg, E>,
1565 {
1566 match &self.inner {
1567 ExprInner::Const(c) => Ok(Expr::from_inner(ExprInner::Const(*c))),
1568 ExprInner::CurrInputIdx => Ok(Expr::from_inner(ExprInner::CurrInputIdx)),
1569 ExprInner::Input(i) => Ok(Expr::from_inner(ExprInner::Input(i.clone()))),
1570 ExprInner::Output(i) => Ok(Expr::from_inner(ExprInner::Output(i.clone()))),
1571 ExprInner::InputIssue(i) => Ok(Expr::from_inner(ExprInner::InputIssue(i.clone()))),
1572 ExprInner::InputReIssue(i) => Ok(Expr::from_inner(ExprInner::InputReIssue(i.clone()))),
1573 ExprInner::Add(a, b) => Ok(Expr::from_inner(ExprInner::Add(
1574 Box::new(a.translate_ext(t)?),
1575 Box::new(b.translate_ext(t)?),
1576 ))),
1577 ExprInner::Sub(a, b) => Ok(Expr::from_inner(ExprInner::Sub(
1578 Box::new(a.translate_ext(t)?),
1579 Box::new(b.translate_ext(t)?),
1580 ))),
1581 ExprInner::Mul(a, b) => Ok(Expr::from_inner(ExprInner::Mul(
1582 Box::new(a.translate_ext(t)?),
1583 Box::new(b.translate_ext(t)?),
1584 ))),
1585 ExprInner::Div(a, b) => Ok(Expr::from_inner(ExprInner::Div(
1586 Box::new(a.translate_ext(t)?),
1587 Box::new(b.translate_ext(t)?),
1588 ))),
1589 ExprInner::Mod(a, b) => Ok(Expr::from_inner(ExprInner::Mod(
1590 Box::new(a.translate_ext(t)?),
1591 Box::new(b.translate_ext(t)?),
1592 ))),
1593 ExprInner::BitAnd(a, b) => Ok(Expr::from_inner(ExprInner::BitAnd(
1594 Box::new(a.translate_ext(t)?),
1595 Box::new(b.translate_ext(t)?),
1596 ))),
1597 ExprInner::BitOr(a, b) => Ok(Expr::from_inner(ExprInner::BitOr(
1598 Box::new(a.translate_ext(t)?),
1599 Box::new(b.translate_ext(t)?),
1600 ))),
1601 ExprInner::Xor(a, b) => Ok(Expr::from_inner(ExprInner::Xor(
1602 Box::new(a.translate_ext(t)?),
1603 Box::new(b.translate_ext(t)?),
1604 ))),
1605 ExprInner::Invert(a) => Ok(Expr::from_inner(ExprInner::Invert(Box::new(
1606 a.translate_ext(t)?,
1607 )))),
1608 ExprInner::Negate(a) => Ok(Expr::from_inner(ExprInner::Negate(Box::new(
1609 a.translate_ext(t)?,
1610 )))),
1611 ExprInner::PriceOracle1(pk, time) => {
1612 Ok(Expr::from_inner(ExprInner::PriceOracle1(t.ext(pk)?, *time)))
1613 }
1614 ExprInner::PriceOracle1W(pk, time) => Ok(Expr::from_inner(ExprInner::PriceOracle1W(
1615 t.ext(pk)?,
1616 *time,
1617 ))),
1618 }
1619 }
1620}
1621
1622#[cfg(test)]
1623mod tests {
1624 use bitcoin::hashes::Hash;
1625 use bitcoin::key::XOnlyPublicKey;
1626
1627 use super::*;
1628 use crate::extensions::check_sig_price_oracle_1;
1629 use crate::test_utils::{StrExtTranslator, StrXOnlyKeyTranslator};
1630 use crate::{CovenantExt, Miniscript, Segwitv0, Tap, TranslatePk};
1631
1632 #[test]
1633 fn test_index_ops_with_arith() {
1634 _arith_parse("num64_eq(out_v(idx_sub(5,curr_idx)),inp_v(idx_add(0,curr_idx)))");
1636 _arith_parse("num64_eq(out_v(idx_mul(5,curr_idx)),inp_v(idx_div(0,curr_idx)))");
1637
1638 _arith_parse(
1639 "num64_eq(inp_issue_v(idx_sub(5,curr_idx)),inp_reissue_v(idx_add(0,curr_idx)))",
1640 );
1641 _arith_parse(
1642 "num64_eq(inp_issue_v(idx_sub(5,curr_idx)),inp_reissue_v(idx_add(0,curr_idx)))",
1643 );
1644 }
1645
1646 #[test]
1647 fn arith_parse() {
1648 _arith_parse("num64_geq(sub(mul(1,0),mul(0,curr_inp_v)),0)");
1649 _arith_parse("num64_gt(curr_inp_v,mul(1,out_v(0)))");
1650 _arith_parse("num64_eq(8,8)");
1652 _arith_parse("num64_gt(9223372036854775807,9223372036854775806)"); _arith_parse("num64_eq(-8,-8)"); _arith_parse("num64_gt(-8,-9)");
1657 _arith_parse("num64_geq(-8,-8)");
1658 _arith_parse("num64_leq(-8,-7)");
1659 _arith_parse("num64_lt(-8,-7)");
1660
1661 _arith_parse("num64_eq(inp_v(0),100)");
1663 _arith_parse("num64_eq(out_v(0),100)");
1664 _arith_parse("num64_eq(inp_issue_v(0),100)");
1665 _arith_parse("num64_eq(inp_reissue_v(0),100)");
1666 _arith_parse("num64_eq(inp_v(0),out_v(0))");
1667 _arith_parse("num64_eq(inp_issue_v(1),inp_reissue_v(1))");
1668
1669 _arith_parse("num64_eq(add(4,3),mul(1,7))");
1671 _arith_parse("num64_eq(sub(3,3),div(0,9))");
1672 _arith_parse("num64_eq(mod(9,3),0)");
1673 _arith_parse("num64_eq(bitand(0,134),0)");
1674 _arith_parse("num64_eq(bitor(1,3),3)");
1675 _arith_parse("num64_eq(bitxor(1,3),2)");
1676 _arith_parse("num64_eq(bitinv(0),-9223372036854775808)");
1677 _arith_parse("num64_eq(neg(1),-1)");
1678
1679 _arith_parse("and_v(v:pk(K),num64_gt(8,7))");
1681 _arith_parse(
1682 "and_v(v:pk(K),num64_eq(mul(inp_v(0),out_v(1)),sub(add(3,inp_issue_v(1)),-9)))",
1683 );
1684
1685 _arith_parse("num64_eq(price_oracle1(K,123213),28004)");
1687 _arith_parse("num64_eq(price_oracle1(K,123213),price_oracle1_w(K,4318743))");
1688 _arith_parse(
1689 "and_v(v:pk(K),num64_eq(mul(inp_v(0),out_v(1)),sub(add(3,inp_issue_v(1)),price_oracle1_w(K,123213))))",
1690 );
1691 _arith_parse("and_v(v:pk(X2),num64_eq(add(price_oracle1(K,1),0),50000))");
1692 }
1693
1694 fn _arith_parse(s: &str) {
1695 type MsExtStr = Miniscript<String, Tap, CovenantExt<String>>;
1696 type MsExt = Miniscript<XOnlyPublicKey, Tap, CovenantExt<CovExtArgs>>;
1697 type MsExtSegwitv0 = Miniscript<String, Segwitv0, CovenantExt<String>>;
1698
1699 assert!(MsExtSegwitv0::from_str_insane(s).is_err());
1701
1702 let ms = MsExtStr::from_str_insane(s).unwrap();
1703 assert_eq!(ms.to_string(), s);
1705 let mut t = StrXOnlyKeyTranslator::default();
1706 let mut ext_t = StrExtTranslator::default();
1707 ext_t.ext_map.insert(
1708 String::from("K"),
1709 CovExtArgs::csfs_key(
1710 XOnlyPublicKey::from_str(
1711 "c304c3b5805eecff054c319c545dc6ac2ad44eb70f79dd9570e284c5a62c0f9e",
1712 )
1713 .unwrap(),
1714 ),
1715 );
1716 let ms = ms.translate_pk(&mut t).unwrap();
1718 let ms = TranslateExt::translate_ext(&ms, &mut ext_t).unwrap();
1719 assert_eq!(ms, MsExt::parse_insane(&ms.encode()).unwrap());
1721 }
1722
1723 #[test]
1724 fn test_fuji_fixed_signs() {
1725 let sig = elements::secp256k1_zkp::schnorr::Signature::from_str("8fc6e217b0e1d3481855cdb97cfe333999d4cf48b9f58b4f299ad86fd768a345e97a953d6efa1ca5971f18810deedcfddc4c2bd4e8f9d1431c1ad6ebafa013a9").unwrap();
1727 let pk = elements::secp256k1_zkp::XOnlyPublicKey::from_str(
1728 "c304c3b5805eecff054c319c545dc6ac2ad44eb70f79dd9570e284c5a62c0f9e",
1729 )
1730 .unwrap();
1731
1732 let timestamp: u64 = 1679531858733;
1733 let price: u64 = 27365;
1734 let secp = elements::secp256k1_zkp::Secp256k1::new();
1735 assert!(check_sig_price_oracle_1(&secp, &sig, &pk, timestamp, price))
1736 }
1737}