Skip to content

Commit

Permalink
Bug fix: pkh->pk lookup API
Browse files Browse the repository at this point in the history
psbts where we needed to dissatisfy pkh did not work properly as we did
not implement the mapping pkh->pk required for dissatisfaction of pkh
fragment. We now look for this mapping in bip32 derivation field of
psbt.

Our update_utxo_from_descriptor API correctly procesess these fields.
  • Loading branch information
sanket1729 committed Nov 5, 2022
1 parent 43abc43 commit 815fd1c
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 7 deletions.
40 changes: 33 additions & 7 deletions src/miniscript/satisfy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,13 @@ pub trait Satisfier<Pk: MiniscriptKey + ToPublicKey> {
None
}

/// Given a raw `Pkh`, lookup corresponding `Pk`
fn lookup_raw_pkh_pk(&self, _: &hash160::Hash) -> Option<Pk> {
/// Given a raw `Pkh`, lookup corresponding [`bitcoin::PublicKey`]
fn lookup_raw_pkh_pk(&self, _: &hash160::Hash) -> Option<bitcoin::PublicKey> {
None
}

/// Given a raw `Pkh`, lookup corresponding [`bitcoin::XOnlyPublicKey`]
fn lookup_raw_pkh_x_only_pk(&self, _: &hash160::Hash) -> Option<XOnlyPublicKey> {
None
}

Expand Down Expand Up @@ -183,8 +188,8 @@ where
self.get(&key.to_pubkeyhash(SigType::Ecdsa)).map(|x| x.1)
}

fn lookup_raw_pkh_pk(&self, pk_hash: &hash160::Hash) -> Option<Pk> {
self.get(pk_hash).map(|x| x.0.clone())
fn lookup_raw_pkh_pk(&self, pk_hash: &hash160::Hash) -> Option<bitcoin::PublicKey> {
self.get(pk_hash).map(|x| x.0.to_public_key())
}

fn lookup_raw_pkh_ecdsa_sig(
Expand Down Expand Up @@ -224,10 +229,14 @@ impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier<Pk>> Satisfier<Pk> for &'
(**self).lookup_tap_leaf_script_sig(p, h)
}

fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option<Pk> {
fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option<bitcoin::PublicKey> {
(**self).lookup_raw_pkh_pk(pkh)
}

fn lookup_raw_pkh_x_only_pk(&self, pkh: &hash160::Hash) -> Option<XOnlyPublicKey> {
(**self).lookup_raw_pkh_x_only_pk(pkh)
}

fn lookup_raw_pkh_ecdsa_sig(
&self,
pkh: &hash160::Hash,
Expand Down Expand Up @@ -290,10 +299,14 @@ impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier<Pk>> Satisfier<Pk> for &'
(**self).lookup_tap_key_spend_sig()
}

fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option<Pk> {
fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option<bitcoin::PublicKey> {
(**self).lookup_raw_pkh_pk(pkh)
}

fn lookup_raw_pkh_x_only_pk(&self, pkh: &hash160::Hash) -> Option<XOnlyPublicKey> {
(**self).lookup_raw_pkh_x_only_pk(pkh)
}

fn lookup_raw_pkh_ecdsa_sig(
&self,
pkh: &hash160::Hash,
Expand Down Expand Up @@ -406,7 +419,7 @@ macro_rules! impl_tuple_satisfier {
fn lookup_raw_pkh_pk(
&self,
key_hash: &hash160::Hash,
) -> Option<Pk> {
) -> Option<bitcoin::PublicKey> {
let &($(ref $ty,)*) = self;
$(
if let Some(result) = $ty.lookup_raw_pkh_pk(key_hash) {
Expand All @@ -416,6 +429,19 @@ macro_rules! impl_tuple_satisfier {
None
}

fn lookup_raw_pkh_x_only_pk(
&self,
key_hash: &hash160::Hash,
) -> Option<XOnlyPublicKey> {
let &($(ref $ty,)*) = self;
$(
if let Some(result) = $ty.lookup_raw_pkh_x_only_pk(key_hash) {
return Some(result);
}
)*
None
}

fn lookup_tap_control_block_map(
&self,
) -> Option<&BTreeMap<ControlBlock, (bitcoin::Script, LeafVersion)>> {
Expand Down
8 changes: 8 additions & 0 deletions src/psbt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,14 @@ impl<'psbt, Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for PsbtInputSatisfie
.copied()
}

fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option<bitcoin::PublicKey> {
self.psbt.inputs[self.index]
.bip32_derivation
.iter()
.find(|&(pubkey, _)| pubkey.to_pubkeyhash(SigType::Ecdsa) == *pkh)
.map(|(pubkey, _)| bitcoin::PublicKey::new(*pubkey))
}

fn lookup_tap_control_block_map(
&self,
) -> Option<&BTreeMap<ControlBlock, (bitcoin::Script, LeafVersion)>> {
Expand Down

0 comments on commit 815fd1c

Please sign in to comment.