Skip to content

Commit df6096a

Browse files
committed
Merge #340: SigType check for cost-analysis in SegwitV1 scripts
52d6647 Add SigType check in CompilerExtData for deciding key byte-lengths (Aman Rojjha) Pull request description: Previously, the struct `CompilerExtData` provided cost analysis for a given script considering the **SegwitV0** standards. This PR aims to track the type/ (context) of the script and provide the respective cost analysis. ACKs for top commit: sanket1729: ACK 52d6647 Tree-SHA512: 55f9ac4fb0de151fa3613195494d9c9fd7ba7e0e1982a0494d510a8f38e939a15d7b7a210ecccfed04af0947d2208e4edea501e2b93dfa220320c0a279cf65bd
2 parents 9b08d9a + 52d6647 commit df6096a

File tree

6 files changed

+83
-48
lines changed

6 files changed

+83
-48
lines changed

src/miniscript/mod.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -654,38 +654,38 @@ mod tests {
654654
let pkk_ms: Miniscript<DummyKey, Segwitv0> = Miniscript {
655655
node: Terminal::Check(Arc::new(Miniscript {
656656
node: Terminal::PkK(DummyKey),
657-
ty: Type::from_pk_k(),
658-
ext: types::extra_props::ExtData::from_pk_k(),
657+
ty: Type::from_pk_k::<Segwitv0>(),
658+
ext: types::extra_props::ExtData::from_pk_k::<Segwitv0>(),
659659
phantom: PhantomData,
660660
})),
661-
ty: Type::cast_check(Type::from_pk_k()).unwrap(),
662-
ext: ExtData::cast_check(ExtData::from_pk_k()).unwrap(),
661+
ty: Type::cast_check(Type::from_pk_k::<Segwitv0>()).unwrap(),
662+
ext: ExtData::cast_check(ExtData::from_pk_k::<Segwitv0>()).unwrap(),
663663
phantom: PhantomData,
664664
};
665665
string_rtt(pkk_ms, "[B/onduesm]c:[K/onduesm]pk_k(DummyKey)", "pk()");
666666

667667
let pkh_ms: Miniscript<DummyKey, Segwitv0> = Miniscript {
668668
node: Terminal::Check(Arc::new(Miniscript {
669669
node: Terminal::PkH(DummyKeyHash),
670-
ty: Type::from_pk_h(),
671-
ext: types::extra_props::ExtData::from_pk_h(),
670+
ty: Type::from_pk_h::<Segwitv0>(),
671+
ext: types::extra_props::ExtData::from_pk_h::<Segwitv0>(),
672672
phantom: PhantomData,
673673
})),
674-
ty: Type::cast_check(Type::from_pk_h()).unwrap(),
675-
ext: ExtData::cast_check(ExtData::from_pk_h()).unwrap(),
674+
ty: Type::cast_check(Type::from_pk_h::<Segwitv0>()).unwrap(),
675+
ext: ExtData::cast_check(ExtData::from_pk_h::<Segwitv0>()).unwrap(),
676676
phantom: PhantomData,
677677
};
678678
string_rtt(pkh_ms, "[B/nduesm]c:[K/nduesm]pk_h(DummyKeyHash)", "pkh()");
679679

680680
let pkk_ms: Segwitv0Script = Miniscript {
681681
node: Terminal::Check(Arc::new(Miniscript {
682682
node: Terminal::PkK(pk),
683-
ty: Type::from_pk_k(),
684-
ext: types::extra_props::ExtData::from_pk_k(),
683+
ty: Type::from_pk_k::<Segwitv0>(),
684+
ext: types::extra_props::ExtData::from_pk_k::<Segwitv0>(),
685685
phantom: PhantomData,
686686
})),
687-
ty: Type::cast_check(Type::from_pk_k()).unwrap(),
688-
ext: ExtData::cast_check(ExtData::from_pk_k()).unwrap(),
687+
ty: Type::cast_check(Type::from_pk_k::<Segwitv0>()).unwrap(),
688+
ext: ExtData::cast_check(ExtData::from_pk_k::<Segwitv0>()).unwrap(),
689689
phantom: PhantomData,
690690
};
691691

@@ -698,12 +698,12 @@ mod tests {
698698
let pkh_ms: Segwitv0Script = Miniscript {
699699
node: Terminal::Check(Arc::new(Miniscript {
700700
node: Terminal::PkH(hash),
701-
ty: Type::from_pk_h(),
702-
ext: types::extra_props::ExtData::from_pk_h(),
701+
ty: Type::from_pk_h::<Segwitv0>(),
702+
ext: types::extra_props::ExtData::from_pk_h::<Segwitv0>(),
703703
phantom: PhantomData,
704704
})),
705-
ty: Type::cast_check(Type::from_pk_h()).unwrap(),
706-
ext: ExtData::cast_check(ExtData::from_pk_h()).unwrap(),
705+
ty: Type::cast_check(Type::from_pk_h::<Segwitv0>()).unwrap(),
706+
ext: ExtData::cast_check(ExtData::from_pk_h::<Segwitv0>()).unwrap(),
707707
phantom: PhantomData,
708708
};
709709

src/miniscript/types/correctness.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//! Correctness/Soundness type properties
1616
1717
use super::{ErrorKind, Property};
18+
use crate::ScriptContext;
1819

1920
/// Basic type representing where the fragment can go
2021
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
@@ -142,7 +143,7 @@ impl Property for Correctness {
142143
}
143144
}
144145

145-
fn from_pk_k() -> Self {
146+
fn from_pk_k<Ctx: ScriptContext>() -> Self {
146147
Correctness {
147148
base: Base::K,
148149
input: Input::OneNonZero,
@@ -151,7 +152,7 @@ impl Property for Correctness {
151152
}
152153
}
153154

154-
fn from_pk_h() -> Self {
155+
fn from_pk_h<Ctx: ScriptContext>() -> Self {
155156
Correctness {
156157
base: Base::K,
157158
input: Input::AnyNonZero,

src/miniscript/types/extra_props.rs

+22-9
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::cmp;
55
use std::iter::once;
66

77
use super::{Error, ErrorKind, Property, ScriptContext};
8+
use crate::miniscript::context::SigType;
89
use crate::miniscript::limits::{
910
HEIGHT_TIME_THRESHOLD, SEQUENCE_LOCKTIME_DISABLE_FLAG, SEQUENCE_LOCKTIME_TYPE_FLAG,
1011
};
@@ -183,30 +184,42 @@ impl Property for ExtData {
183184
}
184185
}
185186

186-
fn from_pk_k() -> Self {
187+
fn from_pk_k<Ctx: ScriptContext>() -> Self {
187188
ExtData {
188-
pk_cost: 34,
189+
pk_cost: match Ctx::sig_type() {
190+
SigType::Ecdsa => 34,
191+
SigType::Schnorr => 33,
192+
},
189193
has_free_verify: false,
190194
ops: OpLimits::new(0, Some(0), Some(0)),
191195
stack_elem_count_sat: Some(1),
192196
stack_elem_count_dissat: Some(1),
193-
max_sat_size: Some((73, 73)),
197+
max_sat_size: match Ctx::sig_type() {
198+
SigType::Ecdsa => Some((73, 73)),
199+
SigType::Schnorr => Some((66, 66)),
200+
},
194201
max_dissat_size: Some((1, 1)),
195202
timelock_info: TimeLockInfo::default(),
196203
exec_stack_elem_count_sat: Some(1), // pushes the pk
197204
exec_stack_elem_count_dissat: Some(1),
198205
}
199206
}
200207

201-
fn from_pk_h() -> Self {
208+
fn from_pk_h<Ctx: ScriptContext>() -> Self {
202209
ExtData {
203210
pk_cost: 24,
204211
has_free_verify: false,
205212
ops: OpLimits::new(3, Some(0), Some(0)),
206213
stack_elem_count_sat: Some(2),
207214
stack_elem_count_dissat: Some(2),
208-
max_sat_size: Some((34 + 73, 34 + 73)),
209-
max_dissat_size: Some((35, 35)),
215+
max_sat_size: match Ctx::sig_type() {
216+
SigType::Ecdsa => Some((34 + 73, 34 + 73)),
217+
SigType::Schnorr => Some((66 + 33, 33 + 66)),
218+
},
219+
max_dissat_size: match Ctx::sig_type() {
220+
SigType::Ecdsa => Some((35, 35)),
221+
SigType::Schnorr => Some((34, 34)),
222+
},
210223
timelock_info: TimeLockInfo::default(),
211224
exec_stack_elem_count_sat: Some(2), // dup and hash push
212225
exec_stack_elem_count_dissat: Some(2),
@@ -244,7 +257,7 @@ impl Property for ExtData {
244257
(false, false) => 2,
245258
};
246259
ExtData {
247-
pk_cost: num_cost + 33 * n /*pks*/ + (n-1) /*checksigadds*/ + 1,
260+
pk_cost: num_cost + 33 * n /*pks*/ + (n - 1) /*checksigadds*/ + 1,
248261
has_free_verify: true,
249262
// These numbers are irrelevant here are there is no op limit in tapscript
250263
ops: OpLimits::new(n, Some(0), Some(0)),
@@ -903,8 +916,8 @@ impl Property for ExtData {
903916
let ret = match *fragment {
904917
Terminal::True => Ok(Self::from_true()),
905918
Terminal::False => Ok(Self::from_false()),
906-
Terminal::PkK(..) => Ok(Self::from_pk_k()),
907-
Terminal::PkH(..) => Ok(Self::from_pk_h()),
919+
Terminal::PkK(..) => Ok(Self::from_pk_k::<Ctx>()),
920+
Terminal::PkH(..) => Ok(Self::from_pk_h::<Ctx>()),
908921
Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => {
909922
if k == 0 {
910923
return Err(Error {

src/miniscript/types/malleability.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//! Malleability-related Type properties
1616
1717
use super::{ErrorKind, Property};
18+
use crate::ScriptContext;
1819

1920
/// Whether the fragment has a dissatisfaction, and if so, whether
2021
/// it is unique. Affects both correctness and malleability-freeness,
@@ -94,15 +95,15 @@ impl Property for Malleability {
9495
}
9596
}
9697

97-
fn from_pk_k() -> Self {
98+
fn from_pk_k<Ctx: ScriptContext>() -> Self {
9899
Malleability {
99100
dissat: Dissat::Unique,
100101
safe: true,
101102
non_malleable: true,
102103
}
103104
}
104105

105-
fn from_pk_h() -> Self {
106+
fn from_pk_h<Ctx: ScriptContext>() -> Self {
106107
Malleability {
107108
dissat: Dissat::Unique,
108109
safe: true,

src/miniscript/types/mod.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,10 @@ pub trait Property: Sized {
258258
fn from_false() -> Self;
259259

260260
/// Type property of the `PkK` fragment
261-
fn from_pk_k() -> Self;
261+
fn from_pk_k<Ctx: ScriptContext>() -> Self;
262262

263263
/// Type property of the `PkH` fragment
264-
fn from_pk_h() -> Self;
264+
fn from_pk_h<Ctx: ScriptContext>() -> Self;
265265

266266
/// Type property of a `Multi` fragment
267267
fn from_multi(k: usize, n: usize) -> Self;
@@ -413,8 +413,8 @@ pub trait Property: Sized {
413413
let ret = match *fragment {
414414
Terminal::True => Ok(Self::from_true()),
415415
Terminal::False => Ok(Self::from_false()),
416-
Terminal::PkK(..) => Ok(Self::from_pk_k()),
417-
Terminal::PkH(..) => Ok(Self::from_pk_h()),
416+
Terminal::PkK(..) => Ok(Self::from_pk_k::<Ctx>()),
417+
Terminal::PkH(..) => Ok(Self::from_pk_h::<Ctx>()),
418418
Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => {
419419
if k == 0 {
420420
return Err(Error {
@@ -562,17 +562,17 @@ impl Property for Type {
562562
}
563563
}
564564

565-
fn from_pk_k() -> Self {
565+
fn from_pk_k<Ctx: ScriptContext>() -> Self {
566566
Type {
567-
corr: Property::from_pk_k(),
568-
mall: Property::from_pk_k(),
567+
corr: Property::from_pk_k::<Ctx>(),
568+
mall: Property::from_pk_k::<Ctx>(),
569569
}
570570
}
571571

572-
fn from_pk_h() -> Self {
572+
fn from_pk_h<Ctx: ScriptContext>() -> Self {
573573
Type {
574-
corr: Property::from_pk_h(),
575-
mall: Property::from_pk_h(),
574+
corr: Property::from_pk_h::<Ctx>(),
575+
mall: Property::from_pk_h::<Ctx>(),
576576
}
577577
}
578578

@@ -796,8 +796,8 @@ impl Property for Type {
796796
let ret = match *fragment {
797797
Terminal::True => Ok(Self::from_true()),
798798
Terminal::False => Ok(Self::from_false()),
799-
Terminal::PkK(..) => Ok(Self::from_pk_k()),
800-
Terminal::PkH(..) => Ok(Self::from_pk_h()),
799+
Terminal::PkK(..) => Ok(Self::from_pk_k::<Ctx>()),
800+
Terminal::PkH(..) => Ok(Self::from_pk_h::<Ctx>()),
801801
Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => {
802802
if k == 0 {
803803
return Err(Error {

src/policy/compiler.rs

+27-7
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use std::marker::PhantomData;
2424
use std::sync::Arc;
2525
use std::{cmp, error, f64, fmt, hash, mem};
2626

27+
use crate::miniscript::context::SigType;
2728
use crate::miniscript::limits::MAX_PUBKEYS_PER_MULTISIG;
2829
use crate::miniscript::types::{self, ErrorKind, ExtData, Property, Type};
2930
use crate::miniscript::ScriptContext;
@@ -165,19 +166,30 @@ impl Property for CompilerExtData {
165166
}
166167
}
167168

168-
fn from_pk_k() -> Self {
169+
fn from_pk_k<Ctx: ScriptContext>() -> Self {
169170
CompilerExtData {
170171
branch_prob: None,
171-
sat_cost: 73.0,
172+
sat_cost: match Ctx::sig_type() {
173+
SigType::Ecdsa => 73.0,
174+
SigType::Schnorr => 1.0 /* <var_int> */ + 64.0 /* sig */ + 1.0, /* <sighash_type> */
175+
},
172176
dissat_cost: Some(1.0),
173177
}
174178
}
175179

176-
fn from_pk_h() -> Self {
180+
fn from_pk_h<Ctx: ScriptContext>() -> Self {
177181
CompilerExtData {
178182
branch_prob: None,
179-
sat_cost: 73.0 + 34.0,
180-
dissat_cost: Some(1.0 + 34.0),
183+
sat_cost: match Ctx::sig_type() {
184+
SigType::Ecdsa => 73.0 + 34.0,
185+
SigType::Schnorr => 66.0 + 33.0,
186+
},
187+
dissat_cost: Some(
188+
1.0 + match Ctx::sig_type() {
189+
SigType::Ecdsa => 34.0,
190+
SigType::Schnorr => 33.0,
191+
},
192+
),
181193
}
182194
}
183195

@@ -189,6 +201,14 @@ impl Property for CompilerExtData {
189201
}
190202
}
191203

204+
fn from_multi_a(k: usize, n: usize) -> Self {
205+
CompilerExtData {
206+
branch_prob: None,
207+
sat_cost: 66.0 * k as f64 + (n - k) as f64,
208+
dissat_cost: Some(n as f64), /* <w_n> ... <w_1> := 0x00 ... 0x00 (n times) */
209+
}
210+
}
211+
192212
fn from_hash() -> Self {
193213
CompilerExtData {
194214
branch_prob: None,
@@ -1258,7 +1278,7 @@ mod tests {
12581278
let compilation: DummyTapAstElemExt =
12591279
best_t(&mut BTreeMap::new(), &policy, 1.0, None).unwrap();
12601280

1261-
assert_eq!(compilation.cost_1d(1.0, None), 88.0 + 74.109375);
1281+
assert_eq!(compilation.cost_1d(1.0, None), 87.0 + 67.0390625);
12621282
assert_eq!(
12631283
policy.lift().unwrap().sorted(),
12641284
compilation.ms.lift().unwrap().sorted()
@@ -1271,7 +1291,7 @@ mod tests {
12711291
let compilation: DummyTapAstElemExt =
12721292
best_t(&mut BTreeMap::new(), &policy, 1.0, None).unwrap();
12731293

1274-
assert_eq!(compilation.cost_1d(1.0, None), 438.0 + 299.4003295898438);
1294+
assert_eq!(compilation.cost_1d(1.0, None), 433.0 + 275.7909749348958);
12751295
assert_eq!(
12761296
policy.lift().unwrap().sorted(),
12771297
compilation.ms.lift().unwrap().sorted()

0 commit comments

Comments
 (0)