Skip to content

Commit

Permalink
Remove PkTranslator trait
Browse files Browse the repository at this point in the history
This is the second commit in a series of two in order to remove the
PkTranslator trait. The triat has a general implementation of Tranlator
like `impl Translator for PkTranslator where P::Sha256 ...`.

However, this blanket implemented has constraints on associated types
and makes it impossible to implement the trait for a generic type
downstream. Rust compiler does not support for trait specialization yet,
and so we should only provide a macro to ease implementation rather than
a blanket implementation that causes duplicate conflicts downstream
  • Loading branch information
sanket1729 committed Jun 13, 2022
1 parent 9ddf516 commit f16927c
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 51 deletions.
12 changes: 8 additions & 4 deletions src/descriptor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ use self::checksum::verify_checksum;
use crate::miniscript::{Legacy, Miniscript, Segwitv0};
use crate::prelude::*;
use crate::{
expression, hash256, miniscript, BareCtx, Error, ForEach, ForEachKey, MiniscriptKey,
PkTranslator, Satisfier, ToPublicKey, TranslatePk, Translator,
expression, hash256, miniscript, BareCtx, Error, ForEach, ForEachKey, MiniscriptKey, Satisfier,
ToPublicKey, TranslatePk, Translator,
};

mod bare;
Expand Down Expand Up @@ -526,14 +526,16 @@ impl Descriptor<DescriptorPublicKey> {
pub fn derive(&self, index: u32) -> Descriptor<DerivedDescriptorKey> {
struct Derivator(u32);

impl PkTranslator<DescriptorPublicKey, DerivedDescriptorKey, ()> for Derivator {
impl Translator<DescriptorPublicKey, DerivedDescriptorKey, ()> for Derivator {
fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<DerivedDescriptorKey, ()> {
Ok(pk.clone().derive(self.0))
}

fn pkh(&mut self, pkh: &DescriptorPublicKey) -> Result<DerivedDescriptorKey, ()> {
Ok(pkh.clone().derive(self.0))
}

translate_assoc_clone!(DescriptorPublicKey, DescriptorPublicKey, ());
}
self.translate_pk(&mut Derivator(index))
.expect("BIP 32 key index substitution cannot fail")
Expand Down Expand Up @@ -571,7 +573,7 @@ impl Descriptor<DescriptorPublicKey> {
struct Derivator<'a, C: secp256k1::Verification>(&'a secp256k1::Secp256k1<C>);

impl<'a, C: secp256k1::Verification>
PkTranslator<DerivedDescriptorKey, bitcoin::PublicKey, ConversionError>
Translator<DerivedDescriptorKey, bitcoin::PublicKey, ConversionError>
for Derivator<'a, C>
{
fn pk(
Expand All @@ -587,6 +589,8 @@ impl Descriptor<DescriptorPublicKey> {
) -> Result<bitcoin::hashes::hash160::Hash, ConversionError> {
Ok(pkh.derive_public_key(&self.0)?.to_pubkeyhash())
}

translate_assoc_clone!(DerivedDescriptorKey, bitcoin::PublicKey, ConversionError);
}

let derived = self.derive(index).translate_pk(&mut Derivator(secp))?;
Expand Down
9 changes: 6 additions & 3 deletions src/interpreter/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use bitcoin::util::taproot::{ControlBlock, TAPROOT_ANNEX_PREFIX};
use super::{stack, BitcoinKey, Error, Stack, TypedHash160};
use crate::miniscript::context::{NoChecks, ScriptContext};
use crate::prelude::*;
use crate::{BareCtx, Legacy, Miniscript, MiniscriptKey, PkTranslator, Segwitv0, Tap};
use crate::{BareCtx, Legacy, Miniscript, MiniscriptKey, Segwitv0, Tap, Translator};

/// Attempts to parse a slice as a Bitcoin public key, checking compressedness
/// if asked to, but otherwise dropping it
Expand Down Expand Up @@ -377,14 +377,16 @@ impl<Ctx: ScriptContext> ToNoChecks for Miniscript<bitcoin::PublicKey, Ctx> {
fn to_no_checks_ms(&self) -> Miniscript<BitcoinKey, NoChecks> {
struct TranslateFullPk;

impl PkTranslator<bitcoin::PublicKey, BitcoinKey, ()> for TranslateFullPk {
impl Translator<bitcoin::PublicKey, BitcoinKey, ()> for TranslateFullPk {
fn pk(&mut self, pk: &bitcoin::PublicKey) -> Result<BitcoinKey, ()> {
Ok(BitcoinKey::Fullkey(*pk))
}

fn pkh(&mut self, pkh: &hash160::Hash) -> Result<TypedHash160, ()> {
Ok(TypedHash160::FullKey(*pkh))
}

translate_assoc_clone!(bitcoin::PublicKey, BitcoinKey, ());
}

self.real_translate_pk(&mut TranslateFullPk)
Expand All @@ -397,14 +399,15 @@ impl<Ctx: ScriptContext> ToNoChecks for Miniscript<bitcoin::XOnlyPublicKey, Ctx>
// specify the () error type as this cannot error
struct TranslateXOnlyPk;

impl PkTranslator<bitcoin::XOnlyPublicKey, BitcoinKey, ()> for TranslateXOnlyPk {
impl Translator<bitcoin::XOnlyPublicKey, BitcoinKey, ()> for TranslateXOnlyPk {
fn pk(&mut self, pk: &bitcoin::XOnlyPublicKey) -> Result<BitcoinKey, ()> {
Ok(BitcoinKey::XOnlyPublicKey(*pk))
}

fn pkh(&mut self, pkh: &hash160::Hash) -> Result<TypedHash160, ()> {
Ok(TypedHash160::XonlyKey(*pkh))
}
translate_assoc_clone!(bitcoin::XOnlyPublicKey, BitcoinKey, ());
}
self.real_translate_pk(&mut TranslateXOnlyPk)
.expect("Translation should succeed")
Expand Down
38 changes: 0 additions & 38 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,44 +465,6 @@ where
fn hash256(&mut self, hash256: &P::Hash256) -> Result<Q::Hash256, E>;
}

/// Provides the conversion information required in [`TranslatePk`].
/// Same as [`Translator`], but useful when all the associated types apart
/// from Pk/Pkh don't change in translation
pub trait PkTranslator<P, Q, E>
where
P: MiniscriptKey,
Q: MiniscriptKey<Sha256 = P::Sha256>,
{
/// Provides the translation public keys P -> Q
fn pk(&mut self, pk: &P) -> Result<Q, E>;

/// Provides the translation public keys hashes P::Hash -> Q::Hash
fn pkh(&mut self, pkh: &P::Hash) -> Result<Q::Hash, E>;
}

impl<P, Q, E, T> Translator<P, Q, E> for T
where
T: PkTranslator<P, Q, E>,
P: MiniscriptKey,
Q: MiniscriptKey<Sha256 = P::Sha256, Hash256 = P::Hash256>,
{
fn pk(&mut self, pk: &P) -> Result<Q, E> {
<Self as PkTranslator<P, Q, E>>::pk(self, pk)
}

fn pkh(&mut self, pkh: &<P as MiniscriptKey>::Hash) -> Result<<Q as MiniscriptKey>::Hash, E> {
<Self as PkTranslator<P, Q, E>>::pkh(self, pkh)
}

fn sha256(&mut self, sha256: &<P as MiniscriptKey>::Sha256) -> Result<<Q>::Sha256, E> {
Ok(sha256.clone())
}

fn hash256(&mut self, hash256: &<P as MiniscriptKey>::Hash256) -> Result<<Q>::Hash256, E> {
Ok(hash256.clone())
}
}

/// Converts a descriptor using abstract keys to one using specific keys. Uses translator `t` to do
/// the actual translation function calls.
pub trait TranslatePk<P, Q>
Expand Down
4 changes: 2 additions & 2 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ macro_rules! translate_assoc_clone {
($source: ty, $target:ty, $error_ty: ty) => {
fn sha256(
&mut self,
_sha256: &<$source as MiniscriptKey>::Sha256,
sha256: &<$source as MiniscriptKey>::Sha256,
) -> Result<<$target as MiniscriptKey>::Sha256, $error_ty> {
Ok(sha256.clone())
}

fn hash256(
&mut self,
_hash256: &<$source as MiniscriptKey>::Hash256,
hash256: &<$source as MiniscriptKey>::Hash256,
) -> Result<<$target as MiniscriptKey>::Hash256, $error_ty> {
Ok(hash256.clone())
}
Expand Down
21 changes: 17 additions & 4 deletions src/psbt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ use crate::miniscript::limits::SEQUENCE_LOCKTIME_DISABLE_FLAG;
use crate::miniscript::satisfy::{After, Older};
use crate::prelude::*;
use crate::{
descriptor, interpreter, Descriptor, DescriptorPublicKey, MiniscriptKey, PkTranslator,
Preimage32, Satisfier, ToPublicKey, TranslatePk,
descriptor, interpreter, Descriptor, DescriptorPublicKey, MiniscriptKey, Preimage32, Satisfier,
ToPublicKey, TranslatePk, Translator,
};

mod finalizer;
Expand Down Expand Up @@ -937,7 +937,7 @@ struct XOnlyHashLookUp(
pub secp256k1::Secp256k1<VerifyOnly>,
);

impl PkTranslator<DescriptorPublicKey, bitcoin::PublicKey, descriptor::ConversionError>
impl Translator<DescriptorPublicKey, bitcoin::PublicKey, descriptor::ConversionError>
for XOnlyHashLookUp
{
fn pk(
Expand All @@ -957,6 +957,13 @@ impl PkTranslator<DescriptorPublicKey, bitcoin::PublicKey, descriptor::Conversio
self.0.insert(hash, xonly);
Ok(hash)
}

// Clone all the associated types in translation
translate_assoc_clone!(
DescriptorPublicKey,
bitcoin::PublicKey,
descriptor::ConversionError
);
}

// Traverse the pkh lookup while maintaining a reverse map for storing the map
Expand All @@ -966,7 +973,7 @@ struct KeySourceLookUp(
pub secp256k1::Secp256k1<VerifyOnly>,
);

impl PkTranslator<DescriptorPublicKey, bitcoin::PublicKey, descriptor::ConversionError>
impl Translator<DescriptorPublicKey, bitcoin::PublicKey, descriptor::ConversionError>
for KeySourceLookUp
{
fn pk(
Expand All @@ -987,6 +994,12 @@ impl PkTranslator<DescriptorPublicKey, bitcoin::PublicKey, descriptor::Conversio
) -> Result<hash160::Hash, descriptor::ConversionError> {
Ok(self.pk(xpk)?.to_pubkeyhash())
}

translate_assoc_clone!(
DescriptorPublicKey,
bitcoin::PublicKey,
descriptor::ConversionError
);
}

fn update_input_with_descriptor_helper(
Expand Down

0 comments on commit f16927c

Please sign in to comment.