Skip to content

Commit 4d63856

Browse files
Refactor PkH to include key.
Basic refactor done. TODO: Fix Lifetime errors.
1 parent ea76eb1 commit 4d63856

File tree

11 files changed

+89
-30
lines changed

11 files changed

+89
-30
lines changed

src/interpreter/mod.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,16 @@ where
594594
return res;
595595
}
596596
}
597-
Terminal::PkH(ref pkh) => {
597+
Terminal::PkH(ref pk) => {
598+
debug_assert_eq!(node_state.n_evaluated, 0);
599+
debug_assert_eq!(node_state.n_satisfied, 0);
600+
let pkh = &pk.to_pubkeyhash();
601+
let res = self.stack.evaluate_pkh(&mut self.verify_sig, &pkh);
602+
if res.is_some() {
603+
return res;
604+
}
605+
}
606+
Terminal::RawPkH(ref pkh) => {
598607
debug_assert_eq!(node_state.n_evaluated, 0);
599608
debug_assert_eq!(node_state.n_satisfied, 0);
600609
let res = self.stack.evaluate_pkh(&mut self.verify_sig, pkh);

src/miniscript/astelem.rs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
9191
{
9292
match *self {
9393
Terminal::PkK(ref p) => pred(ForEach::Key(p)),
94-
Terminal::PkH(ref p) => pred(ForEach::Hash(p)),
94+
Terminal::PkH(ref p) => pred(ForEach::Hash(&p.to_pubkeyhash())),
95+
Terminal::RawPkH(ref p) => pred(ForEach::Hash(p)),
9596
Terminal::After(..)
9697
| Terminal::Older(..)
9798
| Terminal::Sha256(..)
@@ -140,7 +141,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
140141
{
141142
let frag: Terminal<Q, CtxQ> = match *self {
142143
Terminal::PkK(ref p) => Terminal::PkK(fpk(p)?),
143-
Terminal::PkH(ref p) => Terminal::PkH(fpkh(p)?),
144+
Terminal::PkH(ref p) => Terminal::PkH(fpk(p)?),
145+
Terminal::RawPkH(ref p) => Terminal::RawPkH(fpkh(p)?),
144146
Terminal::After(n) => Terminal::After(n),
145147
Terminal::Older(n) => Terminal::Older(n),
146148
Terminal::Sha256(x) => Terminal::Sha256(x),
@@ -273,7 +275,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Debug for Terminal<Pk, Ctx> {
273275
} else {
274276
match *self {
275277
Terminal::PkK(ref pk) => write!(f, "pk_k({:?})", pk),
276-
Terminal::PkH(ref pkh) => write!(f, "pk_h({:?})", pkh),
278+
Terminal::PkH(ref pk) => write!(f, "pk_h({{{:?}}} {:?})", pk, &pk.to_pubkeyhash()),
279+
Terminal::RawPkH(ref pkh) => write!(f, "pk_h({:?})", pkh),
277280
Terminal::After(t) => write!(f, "after({})", t),
278281
Terminal::Older(t) => write!(f, "older({})", t),
279282
Terminal::Sha256(h) => write!(f, "sha256({})", h),
@@ -330,7 +333,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Display for Terminal<Pk, Ctx> {
330333
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
331334
match *self {
332335
Terminal::PkK(ref pk) => write!(f, "pk_k({})", pk),
333-
Terminal::PkH(ref pkh) => write!(f, "pk_h({})", pkh),
336+
Terminal::PkH(ref pk) => write!(f, "pk_h({})", &pk.to_pubkeyhash()),
337+
Terminal::RawPkH(ref pkh) => write!(f, "pk_h({})", pkh),
334338
Terminal::After(t) => write!(f, "after({})", t),
335339
Terminal::Older(t) => write!(f, "older({})", t),
336340
Terminal::Sha256(h) => write!(f, "sha256({})", h),
@@ -390,7 +394,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Display for Terminal<Pk, Ctx> {
390394
if let Terminal::PkK(ref pk) = sub.node {
391395
// alias: pk(K) = c:pk_k(K)
392396
return write!(f, "pk({})", pk);
393-
} else if let Terminal::PkH(ref pkh) = sub.node {
397+
} else if let Terminal::RawPkH(ref pkh) = sub.node {
394398
// alias: pkh(K) = c:pk_h(K)
395399
return write!(f, "pkh({})", pkh);
396400
}
@@ -404,7 +408,9 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Display for Terminal<Pk, Ctx> {
404408
// Add a ':' wrapper if there are other wrappers apart from c:pk_k()
405409
// tvc:pk_k() -> tv:pk()
406410
Some(('c', ms)) => match ms.node {
407-
Terminal::PkK(_) | Terminal::PkH(_) => fmt::Write::write_char(f, ':')?,
411+
Terminal::PkK(_) | Terminal::RawPkH(_) => {
412+
fmt::Write::write_char(f, ':')?
413+
}
408414
_ => {}
409415
},
410416
_ => {}
@@ -488,9 +494,9 @@ where
488494
("pk_k", 1) => {
489495
expression::terminal(&top.args[0], |x| Pk::from_str(x).map(Terminal::PkK))
490496
}
491-
("pk_h", 1) => {
492-
expression::terminal(&top.args[0], |x| Pk::Hash::from_str(x).map(Terminal::PkH))
493-
}
497+
("pk_h", 1) => expression::terminal(&top.args[0], |x| {
498+
Pk::Hash::from_str(x).map(Terminal::RawPkH)
499+
}),
494500
("after", 1) => expression::terminal(&top.args[0], |x| {
495501
expression::parse_num(x).map(Terminal::After)
496502
}),
@@ -648,7 +654,12 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
648654
{
649655
match *self {
650656
Terminal::PkK(ref pk) => builder.push_ms_key::<_, Ctx>(pk),
651-
Terminal::PkH(ref hash) => builder
657+
Terminal::PkH(ref pk) => builder
658+
.push_opcode(opcodes::all::OP_DUP)
659+
.push_opcode(opcodes::all::OP_HASH160)
660+
.push_slice(&Pk::hash_to_hash160(&pk.to_pubkeyhash())[..])
661+
.push_opcode(opcodes::all::OP_EQUALVERIFY),
662+
Terminal::RawPkH(ref hash) => builder
652663
.push_opcode(opcodes::all::OP_DUP)
653664
.push_opcode(opcodes::all::OP_HASH160)
654665
.push_slice(&Pk::hash_to_hash160(hash)[..])
@@ -788,7 +799,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
788799
pub fn script_size(&self) -> usize {
789800
match *self {
790801
Terminal::PkK(ref pk) => Ctx::pk_len(pk),
791-
Terminal::PkH(..) => 24,
802+
Terminal::PkH(..) | Terminal::RawPkH(..) => 24,
792803
Terminal::After(n) => script_num_size(n as usize) + 1,
793804
Terminal::Older(n) => script_num_size(n as usize) + 1,
794805
Terminal::Sha256(..) => 33 + 6,

src/miniscript/context.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,9 @@ impl ScriptContext for Legacy {
355355
) -> Result<(), ScriptContextError> {
356356
match *frag {
357357
Terminal::PkH(ref _pkh) => Err(ScriptContextError::MalleablePkH),
358+
//Given that we don't have different properties except implementational for RawPkH and
359+
// PkH, I've kept it the same.
360+
Terminal::RawPkH(ref _pk) => Err(ScriptContextError::MalleablePkH),
358361
Terminal::OrI(ref _a, ref _b) => Err(ScriptContextError::MalleableOrI),
359362
Terminal::DupIf(ref _ms) => Err(ScriptContextError::MalleableDupIf),
360363
_ => Ok(()),
@@ -746,8 +749,8 @@ impl ScriptContext for BareCtx {
746749
fn other_top_level_checks<Pk: MiniscriptKey>(ms: &Miniscript<Pk, Self>) -> Result<(), Error> {
747750
match &ms.node {
748751
Terminal::Check(ref ms) => match &ms.node {
749-
Terminal::PkH(_pkh) => Ok(()),
750-
Terminal::PkK(_pk) => Ok(()),
752+
Terminal::RawPkH(_pkh) => Ok(()),
753+
Terminal::PkK(_pk) | Terminal::PkH(_pk) => Ok(()),
751754
_ => Err(Error::NonStandardBareScript),
752755
},
753756
Terminal::Multi(_k, subs) if subs.len() <= 3 => Ok(()),

src/miniscript/decode.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ pub enum Terminal<Pk: MiniscriptKey, Ctx: ScriptContext> {
134134
/// `<key>`
135135
PkK(Pk),
136136
/// `DUP HASH160 <keyhash> EQUALVERIFY`
137-
PkH(Pk::Hash),
137+
PkH(Pk),
138+
/// Only for Parsing PkH
139+
RawPkH(Pk::Hash),
138140
// timelocks
139141
/// `n CHECKLOCKTIMEVERIFY`
140142
After(u32),
@@ -336,7 +338,7 @@ pub fn parse<Ctx: ScriptContext>(
336338
Tk::Hash160 => match_token!(
337339
tokens,
338340
Tk::Dup => {
339-
term.reduce0(Terminal::PkH(
341+
term.reduce0(Terminal::RawPkH(
340342
hash160::Hash::from_slice(hash).expect("valid size")
341343
))?
342344
},

src/miniscript/iter.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
5858
/// them.
5959
pub fn branches(&self) -> Vec<&Miniscript<Pk, Ctx>> {
6060
match self.node {
61-
Terminal::PkK(_) | Terminal::PkH(_) | Terminal::Multi(_, _) => vec![],
61+
Terminal::PkK(_) | Terminal::PkH(_) | Terminal::RawPkH(_) | Terminal::Multi(_, _) => {
62+
vec![]
63+
}
6264

6365
Terminal::Alt(ref node)
6466
| Terminal::Swap(ref node)
@@ -140,8 +142,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
140142
/// for example `miniscript.iter_pubkey_hashes().collect()`.
141143
pub fn get_leaf_pkh(&self) -> Vec<Pk::Hash> {
142144
match self.node {
143-
Terminal::PkH(ref hash) => vec![hash.clone()],
144-
Terminal::PkK(ref key) => vec![key.to_pubkeyhash()],
145+
Terminal::RawPkH(ref hash) => vec![hash.clone()],
146+
Terminal::PkK(ref key) | Terminal::PkH(ref key) => vec![key.to_pubkeyhash()],
145147
Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => {
146148
keys.iter().map(Pk::to_pubkeyhash).collect()
147149
}
@@ -158,7 +160,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
158160
/// function, for example `miniscript.iter_pubkeys_and_hashes().collect()`.
159161
pub fn get_leaf_pk_pkh(&self) -> Vec<PkPkh<Pk>> {
160162
match self.node {
161-
Terminal::PkH(ref hash) => vec![PkPkh::HashedPubkey(hash.clone())],
163+
Terminal::RawPkH(ref hash) => vec![PkPkh::HashedPubkey(hash.clone())],
164+
Terminal::PkH(ref key) => vec![PkPkh::HashedPubkey(key.to_pubkeyhash())],
162165
Terminal::PkK(ref key) => vec![PkPkh::PlainPubkey(key.clone())],
163166
Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => keys
164167
.iter()
@@ -191,8 +194,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
191194
/// NB: The function analyzes only single miniscript item and not any of its descendants in AST.
192195
pub fn get_nth_pkh(&self, n: usize) -> Option<Pk::Hash> {
193196
match (&self.node, n) {
194-
(&Terminal::PkH(ref hash), 0) => Some(hash.clone()),
195-
(&Terminal::PkK(ref key), 0) => Some(key.to_pubkeyhash()),
197+
(&Terminal::RawPkH(ref hash), 0) => Some(hash.clone()),
198+
(&Terminal::PkK(ref key) | &Terminal::PkH(ref key), 0) => Some(key.to_pubkeyhash()),
196199
(&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => {
197200
keys.get(n).map(Pk::to_pubkeyhash)
198201
}
@@ -206,7 +209,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
206209
/// NB: The function analyzes only single miniscript item and not any of its descendants in AST.
207210
pub fn get_nth_pk_pkh(&self, n: usize) -> Option<PkPkh<Pk>> {
208211
match (&self.node, n) {
209-
(&Terminal::PkH(ref hash), 0) => Some(PkPkh::HashedPubkey(hash.clone())),
212+
(&Terminal::RawPkH(ref hash), 0) => Some(PkPkh::HashedPubkey(hash.clone())),
213+
(&Terminal::PkH(ref key), 0) => Some(PkPkh::HashedPubkey(key.to_pubkeyhash())),
210214
(&Terminal::PkK(ref key), 0) => Some(PkPkh::PlainPubkey(key.clone())),
211215
(&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => {
212216
keys.get(n).map(|key| PkPkh::PlainPubkey(key.clone()))

src/miniscript/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ mod tests {
669669

670670
let pkh_ms: Miniscript<DummyKey, Segwitv0> = Miniscript {
671671
node: Terminal::Check(Arc::new(Miniscript {
672-
node: Terminal::PkH(DummyKeyHash),
672+
node: Terminal::RawPkH(DummyKeyHash),
673673
ty: Type::from_pk_h::<Segwitv0>(),
674674
ext: types::extra_props::ExtData::from_pk_h::<Segwitv0>(),
675675
phantom: PhantomData,
@@ -700,7 +700,7 @@ mod tests {
700700

701701
let pkh_ms: Segwitv0Script = Miniscript {
702702
node: Terminal::Check(Arc::new(Miniscript {
703-
node: Terminal::PkH(hash),
703+
node: Terminal::RawPkH(hash),
704704
ty: Type::from_pk_h::<Segwitv0>(),
705705
ext: types::extra_props::ExtData::from_pk_h::<Segwitv0>(),
706706
phantom: PhantomData,

src/miniscript/satisfy.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -938,7 +938,11 @@ impl Satisfaction {
938938
stack: Witness::signature::<_, _, Ctx>(stfr, pk, leaf_hash),
939939
has_sig: true,
940940
},
941-
Terminal::PkH(ref pkh) => Satisfaction {
941+
Terminal::PkH(ref pk) => Satisfaction {
942+
stack: Witness::pkh_signature(stfr, &pk.to_pubkeyhash()),
943+
has_sig: true,
944+
},
945+
Terminal::RawPkH(ref pkh) => Satisfaction {
942946
stack: Witness::pkh_signature(stfr, pkh),
943947
has_sig: true,
944948
},
@@ -1246,7 +1250,14 @@ impl Satisfaction {
12461250
stack: Witness::push_0(),
12471251
has_sig: false,
12481252
},
1249-
Terminal::PkH(ref pkh) => Satisfaction {
1253+
Terminal::PkH(ref pk) => Satisfaction {
1254+
stack: Witness::combine(
1255+
Witness::push_0(),
1256+
Witness::pkh_public_key(stfr, &pk.to_pubkeyhash()),
1257+
),
1258+
has_sig: false,
1259+
},
1260+
Terminal::RawPkH(ref pkh) => Satisfaction {
12501261
stack: Witness::combine(Witness::push_0(), Witness::pkh_public_key(stfr, pkh)),
12511262
has_sig: false,
12521263
},

src/miniscript/types/extra_props.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,10 @@ impl Property for ExtData {
911911
Terminal::False => Ok(Self::from_false()),
912912
Terminal::PkK(..) => Ok(Self::from_pk_k::<Ctx>()),
913913
Terminal::PkH(..) => Ok(Self::from_pk_h::<Ctx>()),
914+
Terminal::RawPkH(..) => Err(Error {
915+
fragment: fragment.clone(),
916+
error: ErrorKind::RawPkHParseOnly,
917+
}),
914918
Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => {
915919
if k == 0 {
916920
return Err(Error {

src/miniscript/types/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ pub enum ErrorKind {
9595
/// Number of strong children
9696
n_strong: usize,
9797
},
98+
/// RawPkH can only be used for parsing
99+
RawPkHParseOnly,
98100
}
99101

100102
/// Error type for typechecking
@@ -211,6 +213,11 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Display for Error<Pk, Ctx> {
211213
n - k,
212214
n_strong,
213215
),
216+
ErrorKind::RawPkHParseOnly => write!(
217+
f,
218+
"fragment «{}» is a RawPkH which should only be used when parsing from string",
219+
self.fragment
220+
)
214221
}
215222
}
216223
}
@@ -414,6 +421,10 @@ pub trait Property: Sized {
414421
Terminal::False => Ok(Self::from_false()),
415422
Terminal::PkK(..) => Ok(Self::from_pk_k::<Ctx>()),
416423
Terminal::PkH(..) => Ok(Self::from_pk_h::<Ctx>()),
424+
Terminal::RawPkH(..) => Err(Error {
425+
fragment: fragment.clone(),
426+
error: ErrorKind::RawPkHParseOnly,
427+
}),
417428
Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => {
418429
if k == 0 {
419430
return Err(Error {
@@ -797,6 +808,10 @@ impl Property for Type {
797808
Terminal::False => Ok(Self::from_false()),
798809
Terminal::PkK(..) => Ok(Self::from_pk_k::<Ctx>()),
799810
Terminal::PkH(..) => Ok(Self::from_pk_h::<Ctx>()),
811+
Terminal::RawPkH(..) => Err(Error {
812+
fragment: fragment.clone(),
813+
error: ErrorKind::RawPkHParseOnly,
814+
}),
800815
Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => {
801816
if k == 0 {
802817
return Err(Error {

src/policy/compiler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,7 @@ where
840840
insert_wrap!(AstElemExt::terminal(Terminal::True));
841841
}
842842
Concrete::Key(ref pk) => {
843-
insert_wrap!(AstElemExt::terminal(Terminal::PkH(pk.to_pubkeyhash())));
843+
insert_wrap!(AstElemExt::terminal(Terminal::PkH(pk.clone())));
844844
insert_wrap!(AstElemExt::terminal(Terminal::PkK(pk.clone())));
845845
}
846846
Concrete::After(n) => insert_wrap!(AstElemExt::terminal(Terminal::After(n))),

src/policy/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Liftable<Pk> for Miniscript<Pk, Ctx>
124124
impl<Pk: MiniscriptKey, Ctx: ScriptContext> Liftable<Pk> for Terminal<Pk, Ctx> {
125125
fn lift(&self) -> Result<Semantic<Pk>, Error> {
126126
let ret = match *self {
127-
Terminal::PkK(ref pk) => Semantic::KeyHash(pk.to_pubkeyhash()),
128-
Terminal::PkH(ref pkh) => Semantic::KeyHash(pkh.clone()),
127+
Terminal::PkK(ref pk) | Terminal::PkH(ref pk) => Semantic::KeyHash(pk.to_pubkeyhash()),
128+
Terminal::RawPkH(ref pkh) => Semantic::KeyHash(pkh.clone()),
129129
Terminal::After(t) => Semantic::After(t),
130130
Terminal::Older(t) => Semantic::Older(t),
131131
Terminal::Sha256(h) => Semantic::Sha256(h),

0 commit comments

Comments
 (0)