Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove TranslatePk trait and clean up Translator trait #733

Merged
merged 8 commits into from
Sep 1, 2024
32 changes: 19 additions & 13 deletions bitcoind-tests/tests/setup/test_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use bitcoin::secp256k1;
use miniscript::descriptor::{SinglePub, SinglePubKey};
use miniscript::{
bitcoin, hash256, Descriptor, DescriptorPublicKey, Error, Miniscript, ScriptContext,
TranslatePk, Translator,
Translator,
};
use rand::RngCore;
use secp256k1::XOnlyPublicKey;
Expand Down Expand Up @@ -155,8 +155,11 @@ pub fn parse_insane_ms<Ctx: ScriptContext>(
#[derive(Debug, Clone)]
struct StrDescPubKeyTranslator<'a>(usize, &'a PubData);

impl<'a> Translator<String, DescriptorPublicKey, ()> for StrDescPubKeyTranslator<'a> {
fn pk(&mut self, pk_str: &String) -> Result<DescriptorPublicKey, ()> {
impl<'a> Translator<String> for StrDescPubKeyTranslator<'a> {
type TargetPk = DescriptorPublicKey;
type Error = core::convert::Infallible;

fn pk(&mut self, pk_str: &String) -> Result<Self::TargetPk, Self::Error> {
let avail = !pk_str.ends_with('!');
if avail {
self.0 += 1;
Expand All @@ -181,22 +184,22 @@ impl<'a> Translator<String, DescriptorPublicKey, ()> for StrDescPubKeyTranslator
}
}

fn sha256(&mut self, sha256: &String) -> Result<sha256::Hash, ()> {
fn sha256(&mut self, sha256: &String) -> Result<sha256::Hash, Self::Error> {
let sha = sha256::Hash::from_str(sha256).unwrap();
Ok(sha)
}

fn hash256(&mut self, hash256: &String) -> Result<hash256::Hash, ()> {
fn hash256(&mut self, hash256: &String) -> Result<hash256::Hash, Self::Error> {
let hash256 = hash256::Hash::from_str(hash256).unwrap();
Ok(hash256)
}

fn ripemd160(&mut self, ripemd160: &String) -> Result<ripemd160::Hash, ()> {
fn ripemd160(&mut self, ripemd160: &String) -> Result<ripemd160::Hash, Self::Error> {
let ripemd160 = ripemd160::Hash::from_str(ripemd160).unwrap();
Ok(ripemd160)
}

fn hash160(&mut self, hash160: &String) -> Result<hash160::Hash, ()> {
fn hash160(&mut self, hash160: &String) -> Result<hash160::Hash, Self::Error> {
let hash160 = hash160::Hash::from_str(hash160).unwrap();
Ok(hash160)
}
Expand All @@ -208,8 +211,11 @@ impl<'a> Translator<String, DescriptorPublicKey, ()> for StrDescPubKeyTranslator
#[derive(Debug, Clone)]
struct StrTranslatorLoose<'a>(usize, &'a PubData);

impl<'a> Translator<String, DescriptorPublicKey, ()> for StrTranslatorLoose<'a> {
fn pk(&mut self, pk_str: &String) -> Result<DescriptorPublicKey, ()> {
impl<'a> Translator<String> for StrTranslatorLoose<'a> {
type TargetPk = DescriptorPublicKey;
type Error = core::convert::Infallible;

fn pk(&mut self, pk_str: &String) -> Result<Self::TargetPk, Self::Error> {
let avail = !pk_str.ends_with('!');
if avail {
self.0 += 1;
Expand Down Expand Up @@ -238,22 +244,22 @@ impl<'a> Translator<String, DescriptorPublicKey, ()> for StrTranslatorLoose<'a>
}
}

fn sha256(&mut self, sha256: &String) -> Result<sha256::Hash, ()> {
fn sha256(&mut self, sha256: &String) -> Result<sha256::Hash, Self::Error> {
let sha = sha256::Hash::from_str(sha256).unwrap();
Ok(sha)
}

fn hash256(&mut self, hash256: &String) -> Result<hash256::Hash, ()> {
fn hash256(&mut self, hash256: &String) -> Result<hash256::Hash, Self::Error> {
let hash256 = hash256::Hash::from_str(hash256).unwrap();
Ok(hash256)
}

fn ripemd160(&mut self, ripemd160: &String) -> Result<ripemd160::Hash, ()> {
fn ripemd160(&mut self, ripemd160: &String) -> Result<ripemd160::Hash, Self::Error> {
let ripemd160 = ripemd160::Hash::from_str(ripemd160).unwrap();
Ok(ripemd160)
}

fn hash160(&mut self, hash160: &String) -> Result<hash160::Hash, ()> {
fn hash160(&mut self, hash160: &String) -> Result<hash160::Hash, Self::Error> {
let hash160 = hash160::Hash::from_str(hash160).unwrap();
Ok(hash160)
}
Expand Down
11 changes: 7 additions & 4 deletions examples/big.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use miniscript::policy::{Concrete, Liftable};
use miniscript::psbt::PsbtExt;
use miniscript::{
translate_hash_fail, DefiniteDescriptorKey, Descriptor, DescriptorPublicKey, MiniscriptKey,
TranslatePk, Translator,
Translator,
};
use secp256k1::Secp256k1;
fn main() {
Expand Down Expand Up @@ -82,12 +82,15 @@ struct StrPkTranslator {
pk_map: HashMap<String, XOnlyPublicKey>,
}

impl Translator<String, XOnlyPublicKey, ()> for StrPkTranslator {
fn pk(&mut self, pk: &String) -> Result<XOnlyPublicKey, ()> {
impl Translator<String> for StrPkTranslator {
type TargetPk = XOnlyPublicKey;
type Error = ();

fn pk(&mut self, pk: &String) -> Result<XOnlyPublicKey, Self::Error> {
self.pk_map.get(pk).copied().ok_or(())
}

// We don't need to implement these methods as we are not using them in the policy.
// Fail if we encounter any hash fragments. See also translate_hash_clone! macro.
translate_hash_fail!(String, XOnlyPublicKey, ());
translate_hash_fail!(String, XOnlyPublicKey, Self::Error);
}
11 changes: 7 additions & 4 deletions examples/taproot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use miniscript::bitcoin::secp256k1::rand;
use miniscript::bitcoin::{Network, WitnessVersion};
use miniscript::descriptor::DescriptorType;
use miniscript::policy::Concrete;
use miniscript::{translate_hash_fail, Descriptor, Miniscript, Tap, TranslatePk, Translator};
use miniscript::{translate_hash_fail, Descriptor, Miniscript, Tap, Translator};

// Refer to https://github.com/sanket1729/adv_btc_workshop/blob/master/workshop.md#creating-a-taproot-descriptor
// for a detailed explanation of the policy and it's compilation
Expand All @@ -17,14 +17,17 @@ struct StrPkTranslator {
pk_map: HashMap<String, XOnlyPublicKey>,
}

impl Translator<String, XOnlyPublicKey, ()> for StrPkTranslator {
fn pk(&mut self, pk: &String) -> Result<XOnlyPublicKey, ()> {
impl Translator<String> for StrPkTranslator {
type TargetPk = XOnlyPublicKey;
type Error = ();

fn pk(&mut self, pk: &String) -> Result<XOnlyPublicKey, Self::Error> {
self.pk_map.get(pk).copied().ok_or(())
}

// We don't need to implement these methods as we are not using them in the policy.
// Fail if we encounter any hash fragments. See also translate_hash_clone! macro.
translate_hash_fail!(String, XOnlyPublicKey, ());
translate_hash_fail!(String, XOnlyPublicKey, Self::Error);
}

fn main() {
Expand Down
56 changes: 21 additions & 35 deletions src/descriptor/bare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::prelude::*;
use crate::util::{varint_len, witness_to_scriptsig};
use crate::{
BareCtx, Error, ForEachKey, FromStrKey, Miniscript, MiniscriptKey, Satisfier, ToPublicKey,
TranslateErr, TranslatePk, Translator,
TranslateErr, Translator,
};

/// Create a Bare Descriptor. That is descriptor that is
Expand Down Expand Up @@ -92,6 +92,14 @@ impl<Pk: MiniscriptKey> Bare<Pk> {
let scriptsig_len = self.ms.max_satisfaction_size()?;
Ok(4 * (varint_len(scriptsig_len) + scriptsig_len))
}

/// Converts the keys in the script from one type to another.
pub fn translate_pk<T>(&self, t: &mut T) -> Result<Bare<T::TargetPk>, TranslateErr<T::Error>>
where
T: Translator<Pk>,
{
Bare::new(self.ms.translate_pk(t)?).map_err(TranslateErr::OuterError)
}
}

impl<Pk: MiniscriptKey + ToPublicKey> Bare<Pk> {
Expand Down Expand Up @@ -190,21 +198,6 @@ impl<Pk: MiniscriptKey> ForEachKey<Pk> for Bare<Pk> {
}
}

impl<P, Q> TranslatePk<P, Q> for Bare<P>
where
P: MiniscriptKey,
Q: MiniscriptKey,
{
type Output = Bare<Q>;

fn translate_pk<T, E>(&self, t: &mut T) -> Result<Bare<Q>, TranslateErr<E>>
where
T: Translator<P, Q, E>,
{
Bare::new(self.ms.translate_pk(t)?).map_err(TranslateErr::OuterError)
}
}

/// A bare PkH descriptor at top level
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct Pkh<Pk: MiniscriptKey> {
Expand Down Expand Up @@ -260,6 +253,18 @@ impl<Pk: MiniscriptKey> Pkh<Pk> {
note = "Use max_weight_to_satisfy instead. The method to count bytes was redesigned and the results will differ from max_weight_to_satisfy. For more details check rust-bitcoin/rust-miniscript#476."
)]
pub fn max_satisfaction_weight(&self) -> usize { 4 * (1 + 73 + BareCtx::pk_len(&self.pk)) }

/// Converts the keys in a script from one type to another.
pub fn translate_pk<T>(&self, t: &mut T) -> Result<Pkh<T::TargetPk>, TranslateErr<T::Error>>
where
T: Translator<Pk>,
{
let res = Pkh::new(t.pk(&self.pk)?);
match res {
Ok(pk) => Ok(pk),
Err(e) => Err(TranslateErr::OuterError(Error::from(e))),
}
}
}

impl<Pk: MiniscriptKey + ToPublicKey> Pkh<Pk> {
Expand Down Expand Up @@ -391,22 +396,3 @@ impl<Pk: FromStrKey> core::str::FromStr for Pkh<Pk> {
impl<Pk: MiniscriptKey> ForEachKey<Pk> for Pkh<Pk> {
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool { pred(&self.pk) }
}

impl<P, Q> TranslatePk<P, Q> for Pkh<P>
where
P: MiniscriptKey,
Q: MiniscriptKey,
{
type Output = Pkh<Q>;

fn translate_pk<T, E>(&self, t: &mut T) -> Result<Self::Output, TranslateErr<E>>
where
T: Translator<P, Q, E>,
{
let res = Pkh::new(t.pk(&self.pk)?);
match res {
Ok(pk) => Ok(pk),
Err(e) => Err(TranslateErr::OuterError(Error::from(e))),
}
}
}
4 changes: 1 addition & 3 deletions src/descriptor/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1003,9 +1003,7 @@ impl DefiniteDescriptorKey {
/// always return a compressed key
///
/// Will return an error if the descriptor key has any hardened derivation steps in its path. To
/// avoid this error you should replace any such public keys first with [`translate_pk`].
///
/// [`translate_pk`]: crate::TranslatePk::translate_pk
/// avoid this error you should replace any such public keys first with [`crate::Descriptor::translate_pk`].
pub fn derive_public_key<C: Verification>(
&self,
secp: &Secp256k1<C>,
Expand Down
Loading
Loading