Skip to content

Commit ed385fc

Browse files
committed
Cleanup context code with SigType enum
1 parent 80a9435 commit ed385fc

File tree

4 files changed

+83
-20
lines changed

4 files changed

+83
-20
lines changed

src/miniscript/astelem.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d, Hash};
2929

3030
use errstr;
3131
use expression;
32+
use miniscript::context::SigType;
3233
use miniscript::types::{self, Property};
3334
use miniscript::ScriptContext;
3435
use script_num_size;
@@ -761,7 +762,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
761762
.push_opcode(opcodes::all::OP_EQUAL)
762763
}
763764
Terminal::Multi(k, ref keys) => {
764-
debug_assert!(!Ctx::is_tap());
765+
debug_assert!(Ctx::sig_type() == SigType::Ecdsa);
765766
builder = builder.push_int(k as i64);
766767
for pk in keys {
767768
builder = builder.push_key(&pk.to_public_key());
@@ -771,7 +772,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
771772
.push_opcode(opcodes::all::OP_CHECKMULTISIG)
772773
}
773774
Terminal::MultiA(k, ref keys) => {
774-
debug_assert!(Ctx::is_tap());
775+
debug_assert!(Ctx::sig_type() == SigType::Schnorr);
775776
// keys must be atleast len 1 here, guaranteed by typing rules
776777
builder = builder.push_ms_key::<_, Ctx>(&keys[0]);
777778
builder = builder.push_opcode(opcodes::all::OP_CHECKSIG);

src/miniscript/context.rs

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ pub enum ScriptContextError {
7474
MultiANotAllowed,
7575
}
7676

77+
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
78+
pub enum SigType {
79+
/// Ecdsa signature
80+
Ecdsa,
81+
/// Schnorr Signature
82+
Schnorr,
83+
}
84+
7785
impl fmt::Display for ScriptContextError {
7886
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7987
match *self {
@@ -285,12 +293,10 @@ where
285293
Self::other_top_level_checks(ms)
286294
}
287295

288-
/// Reverse lookup to store whether the context is tapscript.
289-
/// pk(33-byte key) is a valid under both tapscript context and segwitv0 context
290-
/// We need to context decide whether the serialize pk to 33 byte or 32 bytes.
291-
fn is_tap() -> bool {
292-
return false;
293-
}
296+
/// The type of signature required for satisfaction
297+
// We need to context decide whether the serialize pk to 33 byte or 32 bytes.
298+
// And to decide which type of signatures to look for during satisfaction
299+
fn sig_type() -> SigType;
294300

295301
/// Get the len of public key when serialized based on context
296302
/// Note that this includes the serialization prefix. Returns
@@ -395,6 +401,10 @@ impl ScriptContext for Legacy {
395401
fn name_str() -> &'static str {
396402
"Legacy/p2sh"
397403
}
404+
405+
fn sig_type() -> SigType {
406+
SigType::Ecdsa
407+
}
398408
}
399409

400410
/// Segwitv0 ScriptContext
@@ -503,6 +513,10 @@ impl ScriptContext for Segwitv0 {
503513
fn name_str() -> &'static str {
504514
"Segwitv0"
505515
}
516+
517+
fn sig_type() -> SigType {
518+
SigType::Ecdsa
519+
}
506520
}
507521

508522
/// Tap ScriptContext
@@ -600,8 +614,8 @@ impl ScriptContext for Tap {
600614
ms.ext.max_sat_size.map(|x| x.0)
601615
}
602616

603-
fn is_tap() -> bool {
604-
true
617+
fn sig_type() -> SigType {
618+
SigType::Schnorr
605619
}
606620

607621
fn pk_len<Pk: MiniscriptKey>(_pk: &Pk) -> usize {
@@ -684,6 +698,10 @@ impl ScriptContext for BareCtx {
684698
fn name_str() -> &'static str {
685699
"BareCtx"
686700
}
701+
702+
fn sig_type() -> SigType {
703+
SigType::Ecdsa
704+
}
687705
}
688706

689707
/// "No Checks" Context
@@ -738,6 +756,51 @@ impl ScriptContext for NoChecks {
738756
// Internally used code
739757
"Nochecks"
740758
}
759+
760+
fn check_witness<Pk: MiniscriptKey>(_witness: &[Vec<u8>]) -> Result<(), ScriptContextError> {
761+
// Only really need to do this for segwitv0 and legacy
762+
// Bare is already restrcited by standardness rules
763+
// and would reach these limits.
764+
Ok(())
765+
}
766+
767+
fn check_global_validity<Pk: MiniscriptKey>(
768+
ms: &Miniscript<Pk, Self>,
769+
) -> Result<(), ScriptContextError> {
770+
Self::check_global_consensus_validity(ms)?;
771+
Self::check_global_policy_validity(ms)?;
772+
Ok(())
773+
}
774+
775+
fn check_local_validity<Pk: MiniscriptKey>(
776+
ms: &Miniscript<Pk, Self>,
777+
) -> Result<(), ScriptContextError> {
778+
Self::check_global_consensus_validity(ms)?;
779+
Self::check_global_policy_validity(ms)?;
780+
Self::check_local_consensus_validity(ms)?;
781+
Self::check_local_policy_validity(ms)?;
782+
Ok(())
783+
}
784+
785+
fn top_level_type_check<Pk: MiniscriptKey>(ms: &Miniscript<Pk, Self>) -> Result<(), Error> {
786+
if ms.ty.corr.base != types::Base::B {
787+
return Err(Error::NonTopLevel(format!("{:?}", ms)));
788+
}
789+
Ok(())
790+
}
791+
792+
fn other_top_level_checks<Pk: MiniscriptKey>(_ms: &Miniscript<Pk, Self>) -> Result<(), Error> {
793+
Ok(())
794+
}
795+
796+
fn top_level_checks<Pk: MiniscriptKey>(ms: &Miniscript<Pk, Self>) -> Result<(), Error> {
797+
Self::top_level_type_check(ms)?;
798+
Self::other_top_level_checks(ms)
799+
}
800+
801+
fn sig_type() -> SigType {
802+
unreachable!("Tried to call sig type on no-checks Miniscript")
803+
}
741804
}
742805

743806
/// Private Mod to prevent downstream from implementing this public trait

src/miniscript/satisfy.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -489,18 +489,17 @@ impl Ord for Witness {
489489
impl Witness {
490490
/// Turn a signature into (part of) a satisfaction
491491
fn signature<Pk: ToPublicKey, S: Satisfier<Pk>, Ctx: ScriptContext>(sat: S, pk: &Pk) -> Self {
492-
if Ctx::is_tap() {
493-
match sat.lookup_schnorr_sig(pk) {
492+
match Ctx::sig_type() {
493+
super::context::SigType::Ecdsa => match sat.lookup_ecdsa_sig(pk) {
494494
Some(sig) => Witness::Stack(vec![sig.to_vec()]),
495495
// Signatures cannot be forged
496496
None => Witness::Impossible,
497-
}
498-
} else {
499-
match sat.lookup_ecdsa_sig(pk) {
497+
},
498+
super::context::SigType::Schnorr => match sat.lookup_schnorr_sig(pk) {
500499
Some(sig) => Witness::Stack(vec![sig.to_vec()]),
501500
// Signatures cannot be forged
502501
None => Witness::Impossible,
503-
}
502+
},
504503
}
505504
}
506505

src/util.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use bitcoin;
22
use bitcoin::blockdata::script;
33
use bitcoin::Script;
4+
use miniscript::context;
45

56
use {ScriptContext, ToPublicKey};
67
pub(crate) fn varint_len(n: usize) -> usize {
@@ -39,10 +40,9 @@ impl MsKeyBuilder for script::Builder {
3940
Pk: ToPublicKey,
4041
Ctx: ScriptContext,
4142
{
42-
if Ctx::is_tap() {
43-
self.push_slice(&key.to_x_only_pubkey().serialize())
44-
} else {
45-
self.push_key(&key.to_public_key())
43+
match Ctx::sig_type() {
44+
context::SigType::Ecdsa => self.push_key(&key.to_public_key()),
45+
context::SigType::Schnorr => self.push_slice(&key.to_x_only_pubkey().serialize()),
4646
}
4747
}
4848
}

0 commit comments

Comments
 (0)