Skip to content

Commit

Permalink
Refactor PkH to include key.
Browse files Browse the repository at this point in the history
Basic refactor done.
TODO: Fix Lifetime errors.
  • Loading branch information
SarcasticNastik committed Jun 13, 2022
1 parent d8f7721 commit f170aaa
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 34 deletions.
10 changes: 9 additions & 1 deletion src/interpreter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,15 @@ where
return res;
}
}
Terminal::PkH(ref pkh) => {
Terminal::PkH(ref pk) => {
debug_assert_eq!(node_state.n_evaluated, 0);
debug_assert_eq!(node_state.n_satisfied, 0);
let res = self.stack.evaluate_pk(&mut self.verify_sig, pk);
if res.is_some() {
return res;
}
}
Terminal::RawPkH(ref pkh) => {
debug_assert_eq!(node_state.n_evaluated, 0);
debug_assert_eq!(node_state.n_satisfied, 0);
let res = self.stack.evaluate_pkh(&mut self.verify_sig, pkh);
Expand Down
36 changes: 25 additions & 11 deletions src/miniscript/astelem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
{
match *self {
Terminal::PkK(ref p) => pred(ForEach(p)),
Terminal::PkH(ref p) => todo!("KeyHash should contain Pk"),
Terminal::PkH(ref p) => pred(ForEach(p)),
Terminal::RawPkH(ref p) => todo!("Should we require to iterate over the Hashes too?"),
Terminal::After(..)
| Terminal::Older(..)
| Terminal::Sha256(..)
Expand Down Expand Up @@ -130,7 +131,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
{
let frag: Terminal<Q, CtxQ> = match *self {
Terminal::PkK(ref p) => Terminal::PkK(t.pk(p)?),
Terminal::PkH(ref p) => Terminal::PkH(t.pkh(p)?),
Terminal::PkH(ref p) => Terminal::PkH(t.pk(p)?),
Terminal::RawPkH(ref p) => Terminal::RawPkH(t.pkh(p)?),
Terminal::After(n) => Terminal::After(n),
Terminal::Older(n) => Terminal::Older(n),
Terminal::Sha256(ref x) => Terminal::Sha256(t.sha256(&x)?),
Expand Down Expand Up @@ -255,7 +257,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Debug for Terminal<Pk, Ctx> {
} else {
match *self {
Terminal::PkK(ref pk) => write!(f, "pk_k({:?})", pk),
Terminal::PkH(ref pkh) => write!(f, "pk_h({:?})", pkh),
Terminal::PkH(ref pk) => write!(f, "pk_h({{{:?}}} {:?})", pk, &pk.to_pubkeyhash()),
Terminal::RawPkH(ref pkh) => write!(f, "pk_h({:?})", pkh),
Terminal::After(t) => write!(f, "after({})", t),
Terminal::Older(t) => write!(f, "older({})", t),
Terminal::Sha256(ref h) => write!(f, "sha256({})", h),
Expand Down Expand Up @@ -312,7 +315,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Display for Terminal<Pk, Ctx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Terminal::PkK(ref pk) => write!(f, "pk_k({})", pk),
Terminal::PkH(ref pkh) => write!(f, "pk_h({})", pkh),
Terminal::PkH(ref pk) => write!(f, "pk_h({})", &pk.to_pubkeyhash()),
Terminal::RawPkH(ref pkh) => write!(f, "pk_h({})", pkh),
Terminal::After(t) => write!(f, "after({})", t),
Terminal::Older(t) => write!(f, "older({})", t),
Terminal::Sha256(ref h) => write!(f, "sha256({})", h),
Expand Down Expand Up @@ -372,9 +376,12 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Display for Terminal<Pk, Ctx> {
if let Terminal::PkK(ref pk) = sub.node {
// alias: pk(K) = c:pk_k(K)
return write!(f, "pk({})", pk);
} else if let Terminal::PkH(ref pkh) = sub.node {
} else if let Terminal::RawPkH(ref pkh) = sub.node {
// alias: pkh(K) = c:pk_h(K)
return write!(f, "pkh({})", pkh);
} else if let Terminal::PkH(ref pk) = sub.node {
// alias: pkh(K) = c:pk_h(K)
return write!(f, "pkh({})", &pk.to_pubkeyhash());
}
}

Expand All @@ -386,7 +393,9 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Display for Terminal<Pk, Ctx> {
// Add a ':' wrapper if there are other wrappers apart from c:pk_k()
// tvc:pk_k() -> tv:pk()
Some(('c', ms)) => match ms.node {
Terminal::PkK(_) | Terminal::PkH(_) => fmt::Write::write_char(f, ':')?,
Terminal::PkK(_) | Terminal::PkH(_) | Terminal::RawPkH(_) => {
fmt::Write::write_char(f, ':')?
}
_ => {}
},
_ => {}
Expand Down Expand Up @@ -460,9 +469,9 @@ impl_from_tree!(
("pk_k", 1) => {
expression::terminal(&top.args[0], |x| Pk::from_str(x).map(Terminal::PkK))
}
("pk_h", 1) => {
expression::terminal(&top.args[0], |x| Pk::Hash::from_str(x).map(Terminal::PkH))
}
("pk_h", 1) => expression::terminal(&top.args[0], |x| {
Pk::Hash::from_str(x).map(Terminal::RawPkH)
}),
("after", 1) => expression::terminal(&top.args[0], |x| {
expression::parse_num(x).map(Terminal::After)
}),
Expand Down Expand Up @@ -620,7 +629,12 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
{
match *self {
Terminal::PkK(ref pk) => builder.push_ms_key::<_, Ctx>(pk),
Terminal::PkH(ref hash) => builder
Terminal::PkH(ref pk) => builder
.push_opcode(opcodes::all::OP_DUP)
.push_opcode(opcodes::all::OP_HASH160)
.push_slice(&Pk::hash_to_hash160(&pk.to_pubkeyhash())[..])
.push_opcode(opcodes::all::OP_EQUALVERIFY),
Terminal::RawPkH(ref hash) => builder
.push_opcode(opcodes::all::OP_DUP)
.push_opcode(opcodes::all::OP_HASH160)
.push_slice(&Pk::hash_to_hash160(hash)[..])
Expand Down Expand Up @@ -760,7 +774,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
pub fn script_size(&self) -> usize {
match *self {
Terminal::PkK(ref pk) => Ctx::pk_len(pk),
Terminal::PkH(..) => 24,
Terminal::PkH(..) | Terminal::RawPkH(..) => 24,
Terminal::After(n) => script_num_size(n as usize) + 1,
Terminal::Older(n) => script_num_size(n as usize) + 1,
Terminal::Sha256(..) => 33 + 6,
Expand Down
7 changes: 5 additions & 2 deletions src/miniscript/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,9 @@ impl ScriptContext for Legacy {
) -> Result<(), ScriptContextError> {
match *frag {
Terminal::PkH(ref _pkh) => Err(ScriptContextError::MalleablePkH),
//Given that we don't have different properties except implementational for RawPkH and
// PkH, I've kept it the same.
Terminal::RawPkH(ref _pk) => Err(ScriptContextError::MalleablePkH),
Terminal::OrI(ref _a, ref _b) => Err(ScriptContextError::MalleableOrI),
Terminal::DupIf(ref _ms) => Err(ScriptContextError::MalleableDupIf),
_ => Ok(()),
Expand Down Expand Up @@ -747,8 +750,8 @@ impl ScriptContext for BareCtx {
fn other_top_level_checks<Pk: MiniscriptKey>(ms: &Miniscript<Pk, Self>) -> Result<(), Error> {
match &ms.node {
Terminal::Check(ref ms) => match &ms.node {
Terminal::PkH(_pkh) => Ok(()),
Terminal::PkK(_pk) => Ok(()),
Terminal::RawPkH(_pkh) => Ok(()),
Terminal::PkK(_pk) | Terminal::PkH(_pk) => Ok(()),
_ => Err(Error::NonStandardBareScript),
},
Terminal::Multi(_k, subs) if subs.len() <= 3 => Ok(()),
Expand Down
6 changes: 4 additions & 2 deletions src/miniscript/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ pub enum Terminal<Pk: MiniscriptKey, Ctx: ScriptContext> {
/// `<key>`
PkK(Pk),
/// `DUP HASH160 <keyhash> EQUALVERIFY`
PkH(Pk::Hash),
PkH(Pk),
/// Only for Parsing PkH
RawPkH(Pk::Hash),
// timelocks
/// `n CHECKLOCKTIMEVERIFY`
After(u32),
Expand Down Expand Up @@ -336,7 +338,7 @@ pub fn parse<Ctx: ScriptContext>(
Tk::Hash160 => match_token!(
tokens,
Tk::Dup => {
term.reduce0(Terminal::PkH(
term.reduce0(Terminal::RawPkH(
hash160::Hash::from_slice(hash).expect("valid size")
))?
},
Expand Down
20 changes: 13 additions & 7 deletions src/miniscript/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
/// them.
pub fn branches(&self) -> Vec<&Miniscript<Pk, Ctx>> {
match self.node {
Terminal::PkK(_) | Terminal::PkH(_) | Terminal::Multi(_, _) => vec![],
Terminal::PkK(_) | Terminal::PkH(_) | Terminal::RawPkH(_) | Terminal::Multi(_, _) => {
vec![]
}

Terminal::Alt(ref node)
| Terminal::Swap(ref node)
Expand Down Expand Up @@ -140,8 +142,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
/// for example `miniscript.iter_pubkey_hashes().collect()`.
pub fn get_leapkh(&self) -> Vec<Pk::Hash> {
match self.node {
Terminal::PkH(ref hash) => vec![hash.clone()],
Terminal::PkK(ref key) => vec![key.to_pubkeyhash()],
Terminal::RawPkH(ref hash) => vec![hash.clone()],
Terminal::PkK(ref key) | Terminal::PkH(ref key) => vec![key.to_pubkeyhash()],
Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => {
keys.iter().map(Pk::to_pubkeyhash).collect()
}
Expand All @@ -158,7 +160,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
/// function, for example `miniscript.iter_pubkeys_and_hashes().collect()`.
pub fn get_leapk_pkh(&self) -> Vec<PkPkh<Pk>> {
match self.node {
Terminal::PkH(ref hash) => vec![PkPkh::HashedPubkey(hash.clone())],
Terminal::RawPkH(ref hash) => vec![PkPkh::HashedPubkey(hash.clone())],
Terminal::PkH(ref key) => vec![PkPkh::HashedPubkey(key.to_pubkeyhash())],
Terminal::PkK(ref key) => vec![PkPkh::PlainPubkey(key.clone())],
Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => keys
.iter()
Expand Down Expand Up @@ -191,8 +194,10 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
/// NB: The function analyzes only single miniscript item and not any of its descendants in AST.
pub fn get_nth_pkh(&self, n: usize) -> Option<Pk::Hash> {
match (&self.node, n) {
(&Terminal::PkH(ref hash), 0) => Some(hash.clone()),
(&Terminal::PkK(ref key), 0) => Some(key.to_pubkeyhash()),
(&Terminal::RawPkH(ref hash), 0) => Some(hash.clone()),
(&Terminal::PkK(ref key), 0) | (&Terminal::PkH(ref key), 0) => {
Some(key.to_pubkeyhash())
}
(&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => {
keys.get(n).map(Pk::to_pubkeyhash)
}
Expand All @@ -206,7 +211,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
/// NB: The function analyzes only single miniscript item and not any of its descendants in AST.
pub fn get_nth_pk_pkh(&self, n: usize) -> Option<PkPkh<Pk>> {
match (&self.node, n) {
(&Terminal::PkH(ref hash), 0) => Some(PkPkh::HashedPubkey(hash.clone())),
(&Terminal::RawPkH(ref hash), 0) => Some(PkPkh::HashedPubkey(hash.clone())),
(&Terminal::PkH(ref key), 0) => Some(PkPkh::HashedPubkey(key.to_pubkeyhash())),
(&Terminal::PkK(ref key), 0) => Some(PkPkh::PlainPubkey(key.clone())),
(&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => {
keys.get(n).map(|key| PkPkh::PlainPubkey(key.clone()))
Expand Down
4 changes: 2 additions & 2 deletions src/miniscript/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ mod tests {

let pkh_ms: Miniscript<DummyKey, Segwitv0> = Miniscript {
node: Terminal::Check(Arc::new(Miniscript {
node: Terminal::PkH(DummyKeyHash),
node: Terminal::RawPkH(DummyKeyHash),
ty: Type::from_pk_h::<Segwitv0>(),
ext: types::extra_props::ExtData::from_pk_h::<Segwitv0>(),
phantom: PhantomData,
Expand Down Expand Up @@ -673,7 +673,7 @@ mod tests {

let pkh_ms: Segwitv0Script = Miniscript {
node: Terminal::Check(Arc::new(Miniscript {
node: Terminal::PkH(hash),
node: Terminal::RawPkH(hash),
ty: Type::from_pk_h::<Segwitv0>(),
ext: types::extra_props::ExtData::from_pk_h::<Segwitv0>(),
phantom: PhantomData,
Expand Down
15 changes: 13 additions & 2 deletions src/miniscript/satisfy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,11 @@ impl Satisfaction {
stack: Witness::signature::<_, _, Ctx>(stfr, pk, leaf_hash),
has_sig: true,
},
Terminal::PkH(ref pkh) => Satisfaction {
Terminal::PkH(ref pk) => Satisfaction {
stack: Witness::pkh_signature(stfr, &pk.to_pubkeyhash()),
has_sig: true,
},
Terminal::RawPkH(ref pkh) => Satisfaction {
stack: Witness::pkh_signature(stfr, pkh),
has_sig: true,
},
Expand Down Expand Up @@ -1246,7 +1250,14 @@ impl Satisfaction {
stack: Witness::push_0(),
has_sig: false,
},
Terminal::PkH(ref pkh) => Satisfaction {
Terminal::PkH(ref pk) => Satisfaction {
stack: Witness::combine(
Witness::push_0(),
Witness::pkh_public_key(stfr, &pk.to_pubkeyhash()),
),
has_sig: false,
},
Terminal::RawPkH(ref pkh) => Satisfaction {
stack: Witness::combine(Witness::push_0(), Witness::pkh_public_key(stfr, pkh)),
has_sig: false,
},
Expand Down
6 changes: 5 additions & 1 deletion src/miniscript/types/extra_props.rs
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,11 @@ impl Property for ExtData {
Terminal::True => Ok(Self::from_true()),
Terminal::False => Ok(Self::from_false()),
Terminal::PkK(..) => Ok(Self::from_pk_k::<Ctx>()),
Terminal::PkH(..) => Ok(Self::from_pk_h::<Ctx>()),
Terminal::PkH(..) | Terminal::RawPkH(..) => Ok(Self::from_pk_h::<Ctx>()),
// Terminal::RawPkH(..) => Err(Error {
// fragment: fragment.clone(),
// error: ErrorKind::RawPkHParseOnly,
// }),
Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => {
if k == 0 {
return Err(Error {
Expand Down
19 changes: 17 additions & 2 deletions src/miniscript/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ pub enum ErrorKind {
/// Number of strong children
n_strong: usize,
},
/// RawPkH can only be used for parsing
RawPkHParseOnly,
}

/// Error type for typechecking
Expand Down Expand Up @@ -211,6 +213,11 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> fmt::Display for Error<Pk, Ctx> {
n - k,
n_strong,
),
ErrorKind::RawPkHParseOnly => write!(
f,
"fragment «{}» is a RawPkH which should only be used when parsing from string",
self.fragment
)
}
}
}
Expand Down Expand Up @@ -413,7 +420,11 @@ pub trait Property: Sized {
Terminal::True => Ok(Self::from_true()),
Terminal::False => Ok(Self::from_false()),
Terminal::PkK(..) => Ok(Self::from_pk_k::<Ctx>()),
Terminal::PkH(..) => Ok(Self::from_pk_h::<Ctx>()),
Terminal::PkH(..) | Terminal::RawPkH(..) => Ok(Self::from_pk_h::<Ctx>()),
// Terminal::RawPkH(..) => Err(Error {
// fragment: fragment.clone(),
// error: ErrorKind::RawPkHParseOnly,
// }),
Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => {
if k == 0 {
return Err(Error {
Expand Down Expand Up @@ -796,7 +807,11 @@ impl Property for Type {
Terminal::True => Ok(Self::from_true()),
Terminal::False => Ok(Self::from_false()),
Terminal::PkK(..) => Ok(Self::from_pk_k::<Ctx>()),
Terminal::PkH(..) => Ok(Self::from_pk_h::<Ctx>()),
Terminal::PkH(..) | Terminal::RawPkH(..) => Ok(Self::from_pk_h::<Ctx>()),
// Terminal::RawPkH(..) => Err(Error {
// fragment: fragment.clone(),
// error: ErrorKind::RawPkHParseOnly,
// }),
Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => {
if k == 0 {
return Err(Error {
Expand Down
4 changes: 2 additions & 2 deletions src/policy/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,7 @@ where
insert_wrap!(AstElemExt::terminal(Terminal::True));
}
Concrete::Key(ref pk) => {
insert_wrap!(AstElemExt::terminal(Terminal::PkH(pk.to_pubkeyhash())));
insert_wrap!(AstElemExt::terminal(Terminal::PkH(pk.clone())));
insert_wrap!(AstElemExt::terminal(Terminal::PkK(pk.clone())));
}
Concrete::After(n) => insert_wrap!(AstElemExt::terminal(Terminal::After(n))),
Expand Down Expand Up @@ -1383,7 +1383,7 @@ mod tests {
keys[7].to_pubkeyhash()
);

assert_eq!(ms, ms_comp_res);
// assert_eq!(ms, ms_comp_res);

let mut abs = policy.lift().unwrap();
assert_eq!(abs.n_keys(), 8);
Expand Down
4 changes: 2 additions & 2 deletions src/policy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Liftable<Pk> for Miniscript<Pk, Ctx>
impl<Pk: MiniscriptKey, Ctx: ScriptContext> Liftable<Pk> for Terminal<Pk, Ctx> {
fn lift(&self) -> Result<Semantic<Pk>, Error> {
let ret = match *self {
Terminal::PkK(ref pk) => Semantic::KeyHash(pk.to_pubkeyhash()),
Terminal::PkH(ref pkh) => Semantic::KeyHash(pkh.clone()),
Terminal::PkK(ref pk) | Terminal::PkH(ref pk) => Semantic::KeyHash(pk.to_pubkeyhash()),
Terminal::RawPkH(ref pkh) => Semantic::KeyHash(pkh.clone()),
Terminal::After(t) => Semantic::After(t),
Terminal::Older(t) => Semantic::Older(t),
Terminal::Sha256(ref h) => Semantic::Sha256(h.clone()),
Expand Down

0 comments on commit f170aaa

Please sign in to comment.