diff --git a/src/miniscript/mod.rs b/src/miniscript/mod.rs index 4d580c94b..559f0e286 100644 --- a/src/miniscript/mod.rs +++ b/src/miniscript/mod.rs @@ -654,12 +654,12 @@ mod tests { let pkk_ms: Miniscript = Miniscript { node: Terminal::Check(Arc::new(Miniscript { node: Terminal::PkK(DummyKey), - ty: Type::from_pk_k(), - ext: types::extra_props::ExtData::from_pk_k(), + ty: Type::from_pk_k::(), + ext: types::extra_props::ExtData::from_pk_k::(), phantom: PhantomData, })), - ty: Type::cast_check(Type::from_pk_k()).unwrap(), - ext: ExtData::cast_check(ExtData::from_pk_k()).unwrap(), + ty: Type::cast_check(Type::from_pk_k::()).unwrap(), + ext: ExtData::cast_check(ExtData::from_pk_k::()).unwrap(), phantom: PhantomData, }; string_rtt(pkk_ms, "[B/onduesm]c:[K/onduesm]pk_k(DummyKey)", "pk()"); @@ -667,12 +667,12 @@ mod tests { let pkh_ms: Miniscript = Miniscript { node: Terminal::Check(Arc::new(Miniscript { node: Terminal::PkH(DummyKeyHash), - ty: Type::from_pk_h(), - ext: types::extra_props::ExtData::from_pk_h(), + ty: Type::from_pk_h::(), + ext: types::extra_props::ExtData::from_pk_h::(), phantom: PhantomData, })), - ty: Type::cast_check(Type::from_pk_h()).unwrap(), - ext: ExtData::cast_check(ExtData::from_pk_h()).unwrap(), + ty: Type::cast_check(Type::from_pk_h::()).unwrap(), + ext: ExtData::cast_check(ExtData::from_pk_h::()).unwrap(), phantom: PhantomData, }; string_rtt(pkh_ms, "[B/nduesm]c:[K/nduesm]pk_h(DummyKeyHash)", "pkh()"); @@ -680,12 +680,12 @@ mod tests { let pkk_ms: Segwitv0Script = Miniscript { node: Terminal::Check(Arc::new(Miniscript { node: Terminal::PkK(pk), - ty: Type::from_pk_k(), - ext: types::extra_props::ExtData::from_pk_k(), + ty: Type::from_pk_k::(), + ext: types::extra_props::ExtData::from_pk_k::(), phantom: PhantomData, })), - ty: Type::cast_check(Type::from_pk_k()).unwrap(), - ext: ExtData::cast_check(ExtData::from_pk_k()).unwrap(), + ty: Type::cast_check(Type::from_pk_k::()).unwrap(), + ext: ExtData::cast_check(ExtData::from_pk_k::()).unwrap(), phantom: PhantomData, }; @@ -698,12 +698,12 @@ mod tests { let pkh_ms: Segwitv0Script = Miniscript { node: Terminal::Check(Arc::new(Miniscript { node: Terminal::PkH(hash), - ty: Type::from_pk_h(), - ext: types::extra_props::ExtData::from_pk_h(), + ty: Type::from_pk_h::(), + ext: types::extra_props::ExtData::from_pk_h::(), phantom: PhantomData, })), - ty: Type::cast_check(Type::from_pk_h()).unwrap(), - ext: ExtData::cast_check(ExtData::from_pk_h()).unwrap(), + ty: Type::cast_check(Type::from_pk_h::()).unwrap(), + ext: ExtData::cast_check(ExtData::from_pk_h::()).unwrap(), phantom: PhantomData, }; diff --git a/src/miniscript/types/correctness.rs b/src/miniscript/types/correctness.rs index 82adad152..9718906a0 100644 --- a/src/miniscript/types/correctness.rs +++ b/src/miniscript/types/correctness.rs @@ -15,6 +15,7 @@ //! Correctness/Soundness type properties use super::{ErrorKind, Property}; +use crate::ScriptContext; /// Basic type representing where the fragment can go #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] @@ -142,7 +143,7 @@ impl Property for Correctness { } } - fn from_pk_k() -> Self { + fn from_pk_k() -> Self { Correctness { base: Base::K, input: Input::OneNonZero, @@ -151,7 +152,7 @@ impl Property for Correctness { } } - fn from_pk_h() -> Self { + fn from_pk_h() -> Self { Correctness { base: Base::K, input: Input::AnyNonZero, diff --git a/src/miniscript/types/extra_props.rs b/src/miniscript/types/extra_props.rs index 3979b1de2..c5e8bcdc3 100644 --- a/src/miniscript/types/extra_props.rs +++ b/src/miniscript/types/extra_props.rs @@ -5,6 +5,7 @@ use std::cmp; use std::iter::once; use super::{Error, ErrorKind, Property, ScriptContext}; +use crate::miniscript::context::SigType; use crate::miniscript::limits::{ HEIGHT_TIME_THRESHOLD, SEQUENCE_LOCKTIME_DISABLE_FLAG, SEQUENCE_LOCKTIME_TYPE_FLAG, }; @@ -183,14 +184,20 @@ impl Property for ExtData { } } - fn from_pk_k() -> Self { + fn from_pk_k() -> Self { ExtData { - pk_cost: 34, + pk_cost: match Ctx::sig_type() { + SigType::Ecdsa => 34, + SigType::Schnorr => 33, + }, has_free_verify: false, ops: OpLimits::new(0, Some(0), Some(0)), stack_elem_count_sat: Some(1), stack_elem_count_dissat: Some(1), - max_sat_size: Some((73, 73)), + max_sat_size: match Ctx::sig_type() { + SigType::Ecdsa => Some((73, 73)), + SigType::Schnorr => Some((66, 66)), + }, max_dissat_size: Some((1, 1)), timelock_info: TimeLockInfo::default(), exec_stack_elem_count_sat: Some(1), // pushes the pk @@ -198,15 +205,21 @@ impl Property for ExtData { } } - fn from_pk_h() -> Self { + fn from_pk_h() -> Self { ExtData { pk_cost: 24, has_free_verify: false, ops: OpLimits::new(3, Some(0), Some(0)), stack_elem_count_sat: Some(2), stack_elem_count_dissat: Some(2), - max_sat_size: Some((34 + 73, 34 + 73)), - max_dissat_size: Some((35, 35)), + max_sat_size: match Ctx::sig_type() { + SigType::Ecdsa => Some((34 + 73, 34 + 73)), + SigType::Schnorr => Some((66 + 33, 33 + 66)), + }, + max_dissat_size: match Ctx::sig_type() { + SigType::Ecdsa => Some((35, 35)), + SigType::Schnorr => Some((34, 34)), + }, timelock_info: TimeLockInfo::default(), exec_stack_elem_count_sat: Some(2), // dup and hash push exec_stack_elem_count_dissat: Some(2), @@ -244,7 +257,7 @@ impl Property for ExtData { (false, false) => 2, }; ExtData { - pk_cost: num_cost + 33 * n /*pks*/ + (n-1) /*checksigadds*/ + 1, + pk_cost: num_cost + 33 * n /*pks*/ + (n - 1) /*checksigadds*/ + 1, has_free_verify: true, // These numbers are irrelevant here are there is no op limit in tapscript ops: OpLimits::new(n, Some(0), Some(0)), @@ -903,8 +916,8 @@ impl Property for ExtData { let ret = match *fragment { Terminal::True => Ok(Self::from_true()), Terminal::False => Ok(Self::from_false()), - Terminal::PkK(..) => Ok(Self::from_pk_k()), - Terminal::PkH(..) => Ok(Self::from_pk_h()), + Terminal::PkK(..) => Ok(Self::from_pk_k::()), + Terminal::PkH(..) => Ok(Self::from_pk_h::()), Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => { if k == 0 { return Err(Error { diff --git a/src/miniscript/types/malleability.rs b/src/miniscript/types/malleability.rs index 6c3cc8169..c65db7747 100644 --- a/src/miniscript/types/malleability.rs +++ b/src/miniscript/types/malleability.rs @@ -15,6 +15,7 @@ //! Malleability-related Type properties use super::{ErrorKind, Property}; +use crate::ScriptContext; /// Whether the fragment has a dissatisfaction, and if so, whether /// it is unique. Affects both correctness and malleability-freeness, @@ -94,7 +95,7 @@ impl Property for Malleability { } } - fn from_pk_k() -> Self { + fn from_pk_k() -> Self { Malleability { dissat: Dissat::Unique, safe: true, @@ -102,7 +103,7 @@ impl Property for Malleability { } } - fn from_pk_h() -> Self { + fn from_pk_h() -> Self { Malleability { dissat: Dissat::Unique, safe: true, diff --git a/src/miniscript/types/mod.rs b/src/miniscript/types/mod.rs index 0643b74be..ac8b35998 100644 --- a/src/miniscript/types/mod.rs +++ b/src/miniscript/types/mod.rs @@ -258,10 +258,10 @@ pub trait Property: Sized { fn from_false() -> Self; /// Type property of the `PkK` fragment - fn from_pk_k() -> Self; + fn from_pk_k() -> Self; /// Type property of the `PkH` fragment - fn from_pk_h() -> Self; + fn from_pk_h() -> Self; /// Type property of a `Multi` fragment fn from_multi(k: usize, n: usize) -> Self; @@ -413,8 +413,8 @@ pub trait Property: Sized { let ret = match *fragment { Terminal::True => Ok(Self::from_true()), Terminal::False => Ok(Self::from_false()), - Terminal::PkK(..) => Ok(Self::from_pk_k()), - Terminal::PkH(..) => Ok(Self::from_pk_h()), + Terminal::PkK(..) => Ok(Self::from_pk_k::()), + Terminal::PkH(..) => Ok(Self::from_pk_h::()), Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => { if k == 0 { return Err(Error { @@ -562,17 +562,17 @@ impl Property for Type { } } - fn from_pk_k() -> Self { + fn from_pk_k() -> Self { Type { - corr: Property::from_pk_k(), - mall: Property::from_pk_k(), + corr: Property::from_pk_k::(), + mall: Property::from_pk_k::(), } } - fn from_pk_h() -> Self { + fn from_pk_h() -> Self { Type { - corr: Property::from_pk_h(), - mall: Property::from_pk_h(), + corr: Property::from_pk_h::(), + mall: Property::from_pk_h::(), } } @@ -796,8 +796,8 @@ impl Property for Type { let ret = match *fragment { Terminal::True => Ok(Self::from_true()), Terminal::False => Ok(Self::from_false()), - Terminal::PkK(..) => Ok(Self::from_pk_k()), - Terminal::PkH(..) => Ok(Self::from_pk_h()), + Terminal::PkK(..) => Ok(Self::from_pk_k::()), + Terminal::PkH(..) => Ok(Self::from_pk_h::()), Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => { if k == 0 { return Err(Error { diff --git a/src/policy/compiler.rs b/src/policy/compiler.rs index a86f56146..97aa60e65 100644 --- a/src/policy/compiler.rs +++ b/src/policy/compiler.rs @@ -24,6 +24,7 @@ use std::marker::PhantomData; use std::sync::Arc; use std::{cmp, error, f64, fmt, hash, mem}; +use crate::miniscript::context::SigType; use crate::miniscript::limits::MAX_PUBKEYS_PER_MULTISIG; use crate::miniscript::types::{self, ErrorKind, ExtData, Property, Type}; use crate::miniscript::ScriptContext; @@ -165,19 +166,30 @@ impl Property for CompilerExtData { } } - fn from_pk_k() -> Self { + fn from_pk_k() -> Self { CompilerExtData { branch_prob: None, - sat_cost: 73.0, + sat_cost: match Ctx::sig_type() { + SigType::Ecdsa => 73.0, + SigType::Schnorr => 1.0 /* */ + 64.0 /* sig */ + 1.0, /* */ + }, dissat_cost: Some(1.0), } } - fn from_pk_h() -> Self { + fn from_pk_h() -> Self { CompilerExtData { branch_prob: None, - sat_cost: 73.0 + 34.0, - dissat_cost: Some(1.0 + 34.0), + sat_cost: match Ctx::sig_type() { + SigType::Ecdsa => 73.0 + 34.0, + SigType::Schnorr => 66.0 + 33.0, + }, + dissat_cost: Some( + 1.0 + match Ctx::sig_type() { + SigType::Ecdsa => 34.0, + SigType::Schnorr => 33.0, + }, + ), } } @@ -189,6 +201,14 @@ impl Property for CompilerExtData { } } + fn from_multi_a(k: usize, n: usize) -> Self { + CompilerExtData { + branch_prob: None, + sat_cost: 66.0 * k as f64 + (n - k) as f64, + dissat_cost: Some(n as f64), /* ... := 0x00 ... 0x00 (n times) */ + } + } + fn from_hash() -> Self { CompilerExtData { branch_prob: None, @@ -1258,7 +1278,7 @@ mod tests { let compilation: DummyTapAstElemExt = best_t(&mut BTreeMap::new(), &policy, 1.0, None).unwrap(); - assert_eq!(compilation.cost_1d(1.0, None), 88.0 + 74.109375); + assert_eq!(compilation.cost_1d(1.0, None), 87.0 + 67.0390625); assert_eq!( policy.lift().unwrap().sorted(), compilation.ms.lift().unwrap().sorted() @@ -1271,7 +1291,7 @@ mod tests { let compilation: DummyTapAstElemExt = best_t(&mut BTreeMap::new(), &policy, 1.0, None).unwrap(); - assert_eq!(compilation.cost_1d(1.0, None), 438.0 + 299.4003295898438); + assert_eq!(compilation.cost_1d(1.0, None), 433.0 + 275.7909749348958); assert_eq!( policy.lift().unwrap().sorted(), compilation.ms.lift().unwrap().sorted()