diff --git a/bitcoind-tests/tests/setup/test_util.rs b/bitcoind-tests/tests/setup/test_util.rs index ffffe661c..64ffa6f5a 100644 --- a/bitcoind-tests/tests/setup/test_util.rs +++ b/bitcoind-tests/tests/setup/test_util.rs @@ -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; @@ -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; @@ -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) } @@ -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; @@ -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) } diff --git a/examples/big.rs b/examples/big.rs index cf0bd099a..230d656b6 100644 --- a/examples/big.rs +++ b/examples/big.rs @@ -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() { @@ -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); } diff --git a/examples/taproot.rs b/examples/taproot.rs index 3ac20c4ec..1e04f7b60 100644 --- a/examples/taproot.rs +++ b/examples/taproot.rs @@ -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 @@ -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() { diff --git a/src/descriptor/bare.rs b/src/descriptor/bare.rs index 66be5d6d4..176137ad8 100644 --- a/src/descriptor/bare.rs +++ b/src/descriptor/bare.rs @@ -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 @@ -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> { @@ -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> { @@ -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> { @@ -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))), - } - } -} diff --git a/src/descriptor/key.rs b/src/descriptor/key.rs index 0ca62fc9f..7e034ef99 100644 --- a/src/descriptor/key.rs +++ b/src/descriptor/key.rs @@ -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>, diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index 0b0bd02b6..1a2a7da16 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -28,7 +28,7 @@ use crate::plan::{AssetProvider, Plan}; use crate::prelude::*; use crate::{ expression, hash256, BareCtx, Error, ForEachKey, FromStrKey, MiniscriptKey, Satisfier, - ToPublicKey, TranslateErr, TranslatePk, Translator, + ToPublicKey, TranslateErr, Translator, }; mod bare; @@ -359,6 +359,25 @@ impl<Pk: MiniscriptKey> Descriptor<Pk> { }; Ok(weight) } + + /// Converts a descriptor using one kind of keys to another kind of key. + pub fn translate_pk<T>( + &self, + t: &mut T, + ) -> Result<Descriptor<T::TargetPk>, TranslateErr<T::Error>> + where + T: Translator<Pk>, + { + let desc = match *self { + Descriptor::Bare(ref bare) => Descriptor::Bare(bare.translate_pk(t)?), + Descriptor::Pkh(ref pk) => Descriptor::Pkh(pk.translate_pk(t)?), + Descriptor::Wpkh(ref pk) => Descriptor::Wpkh(pk.translate_pk(t)?), + Descriptor::Sh(ref sh) => Descriptor::Sh(sh.translate_pk(t)?), + Descriptor::Wsh(ref wsh) => Descriptor::Wsh(wsh.translate_pk(t)?), + Descriptor::Tr(ref tr) => Descriptor::Tr(tr.translate_pk(t)?), + }; + Ok(desc) + } } impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> { @@ -551,30 +570,6 @@ impl Descriptor<DefiniteDescriptorKey> { } } -impl<P, Q> TranslatePk<P, Q> for Descriptor<P> -where - P: MiniscriptKey, - Q: MiniscriptKey, -{ - type Output = Descriptor<Q>; - - /// Converts a descriptor using abstract keys to one using specific keys. - fn translate_pk<T, E>(&self, t: &mut T) -> Result<Self::Output, TranslateErr<E>> - where - T: Translator<P, Q, E>, - { - let desc = match *self { - Descriptor::Bare(ref bare) => Descriptor::Bare(bare.translate_pk(t)?), - Descriptor::Pkh(ref pk) => Descriptor::Pkh(pk.translate_pk(t)?), - Descriptor::Wpkh(ref pk) => Descriptor::Wpkh(pk.translate_pk(t)?), - Descriptor::Sh(ref sh) => Descriptor::Sh(sh.translate_pk(t)?), - Descriptor::Wsh(ref wsh) => Descriptor::Wsh(wsh.translate_pk(t)?), - Descriptor::Tr(ref tr) => Descriptor::Tr(tr.translate_pk(t)?), - }; - Ok(desc) - } -} - impl<Pk: MiniscriptKey> ForEachKey<Pk> for Descriptor<Pk> { fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool { match *self { @@ -607,7 +602,10 @@ impl Descriptor<DescriptorPublicKey> { ) -> Result<Descriptor<DefiniteDescriptorKey>, ConversionError> { struct Derivator(u32); - impl Translator<DescriptorPublicKey, DefiniteDescriptorKey, ConversionError> for Derivator { + impl Translator<DescriptorPublicKey> for Derivator { + type TargetPk = DefiniteDescriptorKey; + type Error = ConversionError; + fn pk( &mut self, pk: &DescriptorPublicKey, @@ -698,9 +696,10 @@ impl Descriptor<DescriptorPublicKey> { struct KeyMapWrapper<'a, C: secp256k1::Signing>(KeyMap, &'a secp256k1::Secp256k1<C>); - impl<'a, C: secp256k1::Signing> Translator<String, DescriptorPublicKey, Error> - for KeyMapWrapper<'a, C> - { + impl<'a, C: secp256k1::Signing> Translator<String> for KeyMapWrapper<'a, C> { + type TargetPk = DescriptorPublicKey; + type Error = Error; + fn pk(&mut self, pk: &String) -> Result<DescriptorPublicKey, Error> { parse_key(pk, &mut self.0, self.1) } @@ -745,29 +744,35 @@ impl Descriptor<DescriptorPublicKey> { pub fn to_string_with_secret(&self, key_map: &KeyMap) -> String { struct KeyMapLookUp<'a>(&'a KeyMap); - impl<'a> Translator<DescriptorPublicKey, String, ()> for KeyMapLookUp<'a> { - fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<String, ()> { + impl<'a> Translator<DescriptorPublicKey> for KeyMapLookUp<'a> { + type TargetPk = String; + type Error = core::convert::Infallible; + + fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<String, Self::Error> { key_to_string(pk, self.0) } - fn sha256(&mut self, sha256: &sha256::Hash) -> Result<String, ()> { + fn sha256(&mut self, sha256: &sha256::Hash) -> Result<String, Self::Error> { Ok(sha256.to_string()) } - fn hash256(&mut self, hash256: &hash256::Hash) -> Result<String, ()> { + fn hash256(&mut self, hash256: &hash256::Hash) -> Result<String, Self::Error> { Ok(hash256.to_string()) } - fn ripemd160(&mut self, ripemd160: &ripemd160::Hash) -> Result<String, ()> { + fn ripemd160(&mut self, ripemd160: &ripemd160::Hash) -> Result<String, Self::Error> { Ok(ripemd160.to_string()) } - fn hash160(&mut self, hash160: &hash160::Hash) -> Result<String, ()> { + fn hash160(&mut self, hash160: &hash160::Hash) -> Result<String, Self::Error> { Ok(hash160.to_string()) } } - fn key_to_string(pk: &DescriptorPublicKey, key_map: &KeyMap) -> Result<String, ()> { + fn key_to_string( + pk: &DescriptorPublicKey, + key_map: &KeyMap, + ) -> Result<String, core::convert::Infallible> { Ok(match key_map.get(pk) { Some(secret) => secret.to_string(), None => pk.to_string(), @@ -842,7 +847,10 @@ impl Descriptor<DescriptorPublicKey> { // Now, transform the multipath key of each descriptor into a single-key using each index. struct IndexChoser(usize); - impl Translator<DescriptorPublicKey, DescriptorPublicKey, Error> for IndexChoser { + impl Translator<DescriptorPublicKey> for IndexChoser { + type TargetPk = DescriptorPublicKey; + type Error = Error; + fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<DescriptorPublicKey, Error> { match pk { DescriptorPublicKey::Single(..) | DescriptorPublicKey::XPub(..) => { @@ -899,10 +907,10 @@ impl Descriptor<DefiniteDescriptorKey> { ) -> Result<Descriptor<bitcoin::PublicKey>, ConversionError> { struct Derivator<'a, C: secp256k1::Verification>(&'a secp256k1::Secp256k1<C>); - impl<'a, C: secp256k1::Verification> - Translator<DefiniteDescriptorKey, bitcoin::PublicKey, ConversionError> - for Derivator<'a, C> - { + impl<'a, C: secp256k1::Verification> Translator<DefiniteDescriptorKey> for Derivator<'a, C> { + type TargetPk = bitcoin::PublicKey; + type Error = ConversionError; + fn pk( &mut self, pk: &DefiniteDescriptorKey, diff --git a/src/descriptor/segwitv0.rs b/src/descriptor/segwitv0.rs index b04c1ad3a..2f2532b85 100644 --- a/src/descriptor/segwitv0.rs +++ b/src/descriptor/segwitv0.rs @@ -22,7 +22,7 @@ use crate::prelude::*; use crate::util::varint_len; use crate::{ Error, ForEachKey, FromStrKey, Miniscript, MiniscriptKey, Satisfier, Segwitv0, ToPublicKey, - TranslateErr, TranslatePk, Translator, + TranslateErr, Translator, }; /// A Segwitv0 wsh descriptor #[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] @@ -128,6 +128,18 @@ impl<Pk: MiniscriptKey> Wsh<Pk> { varint_len(max_sat_elems) + max_sat_size) } + + /// Converts the keys in a script from one type to another. + pub fn translate_pk<T>(&self, t: &mut T) -> Result<Wsh<T::TargetPk>, TranslateErr<T::Error>> + where + T: Translator<Pk>, + { + let inner = match self.inner { + WshInner::SortedMulti(ref smv) => WshInner::SortedMulti(smv.translate_pk(t)?), + WshInner::Ms(ref ms) => WshInner::Ms(ms.translate_pk(t)?), + }; + Ok(Wsh { inner }) + } } impl<Pk: MiniscriptKey + ToPublicKey> Wsh<Pk> { @@ -291,25 +303,6 @@ impl<Pk: MiniscriptKey> ForEachKey<Pk> for Wsh<Pk> { } } -impl<P, Q> TranslatePk<P, Q> for Wsh<P> -where - P: MiniscriptKey, - Q: MiniscriptKey, -{ - type Output = Wsh<Q>; - - fn translate_pk<T, E>(&self, t: &mut T) -> Result<Self::Output, TranslateErr<E>> - where - T: Translator<P, Q, E>, - { - let inner = match self.inner { - WshInner::SortedMulti(ref smv) => WshInner::SortedMulti(smv.translate_pk(t)?), - WshInner::Ms(ref ms) => WshInner::Ms(ms.translate_pk(t)?), - }; - Ok(Wsh { inner }) - } -} - /// A bare Wpkh descriptor at top level #[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] pub struct Wpkh<Pk: MiniscriptKey> { @@ -370,6 +363,18 @@ impl<Pk: MiniscriptKey> Wpkh<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 + Segwitv0::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<Wpkh<T::TargetPk>, TranslateErr<T::Error>> + where + T: Translator<Pk>, + { + let res = Wpkh::new(t.pk(&self.pk)?); + match res { + Ok(pk) => Ok(pk), + Err(e) => Err(TranslateErr::OuterError(Error::from(e))), + } + } } impl<Pk: MiniscriptKey + ToPublicKey> Wpkh<Pk> { @@ -509,22 +514,3 @@ impl<Pk: FromStrKey> core::str::FromStr for Wpkh<Pk> { impl<Pk: MiniscriptKey> ForEachKey<Pk> for Wpkh<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 Wpkh<P> -where - P: MiniscriptKey, - Q: MiniscriptKey, -{ - type Output = Wpkh<Q>; - - fn translate_pk<T, E>(&self, t: &mut T) -> Result<Self::Output, TranslateErr<E>> - where - T: Translator<P, Q, E>, - { - let res = Wpkh::new(t.pk(&self.pk)?); - match res { - Ok(pk) => Ok(pk), - Err(e) => Err(TranslateErr::OuterError(Error::from(e))), - } - } -} diff --git a/src/descriptor/sh.rs b/src/descriptor/sh.rs index c575c3476..cf05c1b71 100644 --- a/src/descriptor/sh.rs +++ b/src/descriptor/sh.rs @@ -25,7 +25,7 @@ use crate::prelude::*; use crate::util::{varint_len, witness_to_scriptsig}; use crate::{ push_opcode_size, Error, ForEachKey, FromStrKey, Legacy, Miniscript, MiniscriptKey, Satisfier, - Segwitv0, ToPublicKey, TranslateErr, TranslatePk, Translator, + Segwitv0, ToPublicKey, TranslateErr, Translator, }; /// A Legacy p2sh Descriptor @@ -259,6 +259,20 @@ impl<Pk: MiniscriptKey> Sh<Pk> { } }) } + + /// Converts the keys in a script from one type to another. + pub fn translate_pk<T>(&self, t: &mut T) -> Result<Sh<T::TargetPk>, TranslateErr<T::Error>> + where + T: Translator<Pk>, + { + let inner = match self.inner { + ShInner::Wsh(ref wsh) => ShInner::Wsh(wsh.translate_pk(t)?), + ShInner::Wpkh(ref wpkh) => ShInner::Wpkh(wpkh.translate_pk(t)?), + ShInner::SortedMulti(ref smv) => ShInner::SortedMulti(smv.translate_pk(t)?), + ShInner::Ms(ref ms) => ShInner::Ms(ms.translate_pk(t)?), + }; + Ok(Sh { inner }) + } } impl<Pk: MiniscriptKey + ToPublicKey> Sh<Pk> { @@ -444,24 +458,3 @@ impl<Pk: MiniscriptKey> ForEachKey<Pk> for Sh<Pk> { } } } - -impl<P, Q> TranslatePk<P, Q> for Sh<P> -where - P: MiniscriptKey, - Q: MiniscriptKey, -{ - type Output = Sh<Q>; - - fn translate_pk<T, E>(&self, t: &mut T) -> Result<Self::Output, TranslateErr<E>> - where - T: Translator<P, Q, E>, - { - let inner = match self.inner { - ShInner::Wsh(ref wsh) => ShInner::Wsh(wsh.translate_pk(t)?), - ShInner::Wpkh(ref wpkh) => ShInner::Wpkh(wpkh.translate_pk(t)?), - ShInner::SortedMulti(ref smv) => ShInner::SortedMulti(smv.translate_pk(t)?), - ShInner::Ms(ref ms) => ShInner::Ms(ms.translate_pk(t)?), - }; - Ok(Sh { inner }) - } -} diff --git a/src/descriptor/sortedmulti.rs b/src/descriptor/sortedmulti.rs index 5b7079292..b8a378a26 100644 --- a/src/descriptor/sortedmulti.rs +++ b/src/descriptor/sortedmulti.rs @@ -77,13 +77,12 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> SortedMultiVec<Pk, Ctx> { /// This will panic if fpk returns an uncompressed key when /// converting to a Segwit descriptor. To prevent this panic, ensure /// fpk returns an error in this case instead. - pub fn translate_pk<T, Q, FuncError>( + pub fn translate_pk<T>( &self, t: &mut T, - ) -> Result<SortedMultiVec<Q, Ctx>, TranslateErr<FuncError>> + ) -> Result<SortedMultiVec<T::TargetPk, Ctx>, TranslateErr<T::Error>> where - T: Translator<Pk, Q, FuncError>, - Q: MiniscriptKey, + T: Translator<Pk>, { let ret = SortedMultiVec { inner: self.inner.translate_ref(|pk| t.pk(pk))?, diff --git a/src/descriptor/tr.rs b/src/descriptor/tr.rs index 6018551c9..2f505780c 100644 --- a/src/descriptor/tr.rs +++ b/src/descriptor/tr.rs @@ -24,7 +24,7 @@ use crate::prelude::*; use crate::util::{varint_len, witness_size}; use crate::{ errstr, Error, ForEachKey, FromStrKey, MiniscriptKey, Satisfier, ScriptContext, Tap, Threshold, - ToPublicKey, TranslateErr, TranslatePk, Translator, + ToPublicKey, TranslateErr, Translator, }; /// A Taproot Tree representation. @@ -132,10 +132,9 @@ impl<Pk: MiniscriptKey> TapTree<Pk> { pub fn iter(&self) -> TapTreeIter<Pk> { TapTreeIter { stack: vec![(0, self)] } } // Helper function to translate keys - fn translate_helper<T, Q, E>(&self, t: &mut T) -> Result<TapTree<Q>, TranslateErr<E>> + fn translate_helper<T>(&self, t: &mut T) -> Result<TapTree<T::TargetPk>, TranslateErr<T::Error>> where - T: Translator<Pk, Q, E>, - Q: MiniscriptKey, + T: Translator<Pk>, { let frag = match *self { TapTree::Tree { ref left, ref right, ref height } => TapTree::Tree { @@ -351,6 +350,23 @@ impl<Pk: MiniscriptKey> Tr<Pk> { .max() .ok_or(Error::ImpossibleSatisfaction) } + + /// Converts keys from one type of public key to another. + pub fn translate_pk<T>( + &self, + translate: &mut T, + ) -> Result<Tr<T::TargetPk>, TranslateErr<T::Error>> + where + T: Translator<Pk>, + { + let tree = match &self.tree { + Some(tree) => Some(tree.translate_helper(translate)?), + None => None, + }; + let translate_desc = + Tr::new(translate.pk(&self.internal_key)?, tree).map_err(TranslateErr::OuterError)?; + Ok(translate_desc) + } } impl<Pk: MiniscriptKey + ToPublicKey> Tr<Pk> { @@ -652,27 +668,6 @@ impl<Pk: MiniscriptKey> ForEachKey<Pk> for Tr<Pk> { } } -impl<P, Q> TranslatePk<P, Q> for Tr<P> -where - P: MiniscriptKey, - Q: MiniscriptKey, -{ - type Output = Tr<Q>; - - fn translate_pk<T, E>(&self, translate: &mut T) -> Result<Self::Output, TranslateErr<E>> - where - T: Translator<P, Q, E>, - { - let tree = match &self.tree { - Some(tree) => Some(tree.translate_helper(translate)?), - None => None, - }; - let translate_desc = Tr::new(translate.pk(&self.internal_key)?, tree) - .map_err(|e| TranslateErr::OuterError(e))?; - Ok(translate_desc) - } -} - // Helper function to compute the len of control block at a given depth fn control_block_len(depth: u8) -> usize { TAPROOT_CONTROL_BASE_SIZE + (depth as usize) * TAPROOT_CONTROL_NODE_SIZE diff --git a/src/interpreter/inner.rs b/src/interpreter/inner.rs index e607266e7..49134c6de 100644 --- a/src/interpreter/inner.rs +++ b/src/interpreter/inner.rs @@ -356,12 +356,15 @@ impl<Ctx: ScriptContext> ToNoChecks for Miniscript<bitcoin::PublicKey, Ctx> { fn to_no_checks_ms(&self) -> Miniscript<BitcoinKey, NoChecks> { struct TranslateFullPk; - impl Translator<bitcoin::PublicKey, BitcoinKey, ()> for TranslateFullPk { - fn pk(&mut self, pk: &bitcoin::PublicKey) -> Result<BitcoinKey, ()> { + impl Translator<bitcoin::PublicKey> for TranslateFullPk { + type TargetPk = BitcoinKey; + type Error = core::convert::Infallible; + + fn pk(&mut self, pk: &bitcoin::PublicKey) -> Result<BitcoinKey, Self::Error> { Ok(BitcoinKey::Fullkey(*pk)) } - translate_hash_clone!(bitcoin::PublicKey, BitcoinKey, ()); + translate_hash_clone!(bitcoin::PublicKey, BitcoinKey, Self::Error); } self.translate_pk_ctx(&mut TranslateFullPk) @@ -371,15 +374,17 @@ impl<Ctx: ScriptContext> ToNoChecks for Miniscript<bitcoin::PublicKey, Ctx> { impl<Ctx: ScriptContext> ToNoChecks for Miniscript<bitcoin::key::XOnlyPublicKey, Ctx> { fn to_no_checks_ms(&self) -> Miniscript<BitcoinKey, NoChecks> { - // specify the () error type as this cannot error struct TranslateXOnlyPk; - impl Translator<bitcoin::key::XOnlyPublicKey, BitcoinKey, ()> for TranslateXOnlyPk { - fn pk(&mut self, pk: &bitcoin::key::XOnlyPublicKey) -> Result<BitcoinKey, ()> { + impl Translator<bitcoin::key::XOnlyPublicKey> for TranslateXOnlyPk { + type TargetPk = BitcoinKey; + type Error = core::convert::Infallible; + + fn pk(&mut self, pk: &bitcoin::key::XOnlyPublicKey) -> Result<BitcoinKey, Self::Error> { Ok(BitcoinKey::XOnlyPublicKey(*pk)) } - translate_hash_clone!(bitcoin::key::XOnlyPublicKey, BitcoinKey, ()); + translate_hash_clone!(bitcoin::key::XOnlyPublicKey, BitcoinKey, Self::Error); } self.translate_pk_ctx(&mut TranslateXOnlyPk) .expect("Translation should succeed") diff --git a/src/lib.rs b/src/lib.rs index b463807ce..4cf566392 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -296,25 +296,38 @@ impl ToPublicKey for bitcoin::secp256k1::XOnlyPublicKey { /// Describes an object that can translate various keys and hashes from one key to the type /// associated with the other key. Used by the [`TranslatePk`] trait to do the actual translations. -pub trait Translator<P, Q, E> -where - P: MiniscriptKey, - Q: MiniscriptKey, -{ - /// Translates public keys P -> Q. - fn pk(&mut self, pk: &P) -> Result<Q, E>; - - /// Provides the translation from P::Sha256 -> Q::Sha256 - fn sha256(&mut self, sha256: &P::Sha256) -> Result<Q::Sha256, E>; - - /// Provides the translation from P::Hash256 -> Q::Hash256 - fn hash256(&mut self, hash256: &P::Hash256) -> Result<Q::Hash256, E>; - - /// Translates ripemd160 hashes from P::Ripemd160 -> Q::Ripemd160 - fn ripemd160(&mut self, ripemd160: &P::Ripemd160) -> Result<Q::Ripemd160, E>; - - /// Translates hash160 hashes from P::Hash160 -> Q::Hash160 - fn hash160(&mut self, hash160: &P::Hash160) -> Result<Q::Hash160, E>; +pub trait Translator<P: MiniscriptKey> { + /// The public key (and associated hash types that this translator converts to. + type TargetPk: MiniscriptKey; + /// An error that may occur during transalation. + type Error; + + /// Translates keys. + fn pk(&mut self, pk: &P) -> Result<Self::TargetPk, Self::Error>; + + /// Translates SHA256 hashes. + fn sha256( + &mut self, + sha256: &P::Sha256, + ) -> Result<<Self::TargetPk as MiniscriptKey>::Sha256, Self::Error>; + + /// Translates HASH256 hashes. + fn hash256( + &mut self, + hash256: &P::Hash256, + ) -> Result<<Self::TargetPk as MiniscriptKey>::Hash256, Self::Error>; + + /// Translates RIPEMD160 hashes. + fn ripemd160( + &mut self, + ripemd160: &P::Ripemd160, + ) -> Result<<Self::TargetPk as MiniscriptKey>::Ripemd160, Self::Error>; + + /// Translates HASH160 hashes. + fn hash160( + &mut self, + hash160: &P::Hash160, + ) -> Result<<Self::TargetPk as MiniscriptKey>::Hash160, Self::Error>; } /// An enum for representing translation errors @@ -368,31 +381,14 @@ impl<E: fmt::Debug> fmt::Debug for TranslateErr<E> { /// Converts a descriptor using abstract keys to one using specific keys. Uses translator `t` to do /// the actual translation function calls. +#[deprecated(since = "TBD", note = "This trait no longer needs to be imported.")] pub trait TranslatePk<P, Q> where P: MiniscriptKey, Q: MiniscriptKey, { - /// The associated output type. This must be `Self<Q>`. - type Output; - - /// Translates a struct from one generic to another where the translations - /// for Pk are provided by the given [`Translator`]. - fn translate_pk<T, E>(&self, translator: &mut T) -> Result<Self::Output, TranslateErr<E>> - where - T: Translator<P, Q, E>; } -/// Either a key or keyhash, but both contain Pk -// pub struct ForEach<'a, Pk: MiniscriptKey>(&'a Pk); - -// impl<'a, Pk: MiniscriptKey<Hash = Pk>> ForEach<'a, Pk> { -// /// Convenience method to avoid distinguishing between keys and hashes when these are the same type -// pub fn as_key(&self) -> &'a Pk { -// self.0 -// } -// } - /// Trait describing the ability to iterate over every key pub trait ForEachKey<Pk: MiniscriptKey> { /// Run a predicate on every key in the descriptor, returning whether diff --git a/src/miniscript/mod.rs b/src/miniscript/mod.rs index 5a48d74a2..1a68606ba 100644 --- a/src/miniscript/mod.rs +++ b/src/miniscript/mod.rs @@ -43,8 +43,7 @@ use self::lex::{lex, TokenIter}; pub use crate::miniscript::context::ScriptContext; use crate::miniscript::decode::Terminal; use crate::{ - expression, plan, Error, ForEachKey, FromStrKey, MiniscriptKey, ToPublicKey, TranslatePk, - Translator, + expression, plan, Error, ForEachKey, FromStrKey, MiniscriptKey, ToPublicKey, Translator, }; #[cfg(test)] mod ms_tests; @@ -514,33 +513,26 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> ForEachKey<Pk> for Miniscript<Pk, Ct } } -impl<Pk, Q, Ctx> TranslatePk<Pk, Q> for Miniscript<Pk, Ctx> -where - Pk: MiniscriptKey, - Q: MiniscriptKey, - Ctx: ScriptContext, -{ - type Output = Miniscript<Q, Ctx>; - +impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> { /// Translates a struct from one generic to another where the translation /// for Pk is provided by [`Translator`] - fn translate_pk<T, E>(&self, t: &mut T) -> Result<Self::Output, TranslateErr<E>> + pub fn translate_pk<T>( + &self, + t: &mut T, + ) -> Result<Miniscript<T::TargetPk, Ctx>, TranslateErr<T::Error>> where - T: Translator<Pk, Q, E>, + T: Translator<Pk>, { self.translate_pk_ctx(t) } -} -impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> { - pub(super) fn translate_pk_ctx<Q, CtxQ, T, FuncError>( + pub(super) fn translate_pk_ctx<CtxQ, T>( &self, t: &mut T, - ) -> Result<Miniscript<Q, CtxQ>, TranslateErr<FuncError>> + ) -> Result<Miniscript<T::TargetPk, CtxQ>, TranslateErr<T::Error>> where - Q: MiniscriptKey, CtxQ: ScriptContext, - T: Translator<Pk, Q, FuncError>, + T: Translator<Pk>, { let mut translated = vec![]; for data in self.rtl_post_order_iter() { @@ -837,7 +829,7 @@ mod tests { use crate::policy::Liftable; use crate::prelude::*; use crate::test_utils::{StrKeyTranslator, StrXOnlyKeyTranslator}; - use crate::{hex_script, Error, ExtParams, RelLockTime, Satisfier, ToPublicKey, TranslatePk}; + use crate::{hex_script, Error, ExtParams, RelLockTime, Satisfier, ToPublicKey}; type Segwitv0Script = Miniscript<bitcoin::PublicKey, Segwitv0>; type Tapscript = Miniscript<bitcoin::secp256k1::XOnlyPublicKey, Tap>; diff --git a/src/policy/concrete.rs b/src/policy/concrete.rs index 6382d837b..8e31d5474 100644 --- a/src/policy/concrete.rs +++ b/src/policy/concrete.rs @@ -507,10 +507,9 @@ impl<Pk: MiniscriptKey> Policy<Pk> { /// Converts a policy using one kind of public key to another type of public key. /// /// For example usage please see [`crate::policy::semantic::Policy::translate_pk`]. - pub fn translate_pk<Q, E, T>(&self, t: &mut T) -> Result<Policy<Q>, E> + pub fn translate_pk<T>(&self, t: &mut T) -> Result<Policy<T::TargetPk>, T::Error> where - T: Translator<Pk, Q, E>, - Q: MiniscriptKey, + T: Translator<Pk>, { use Policy::*; @@ -1140,15 +1139,26 @@ mod tests { #[test] fn tranaslate_pk() { pub struct TestTranslator; - impl Translator<String, String, ()> for TestTranslator { - fn pk(&mut self, pk: &String) -> Result<String, ()> { + impl Translator<String> for TestTranslator { + type TargetPk = String; + type Error = core::convert::Infallible; + + fn pk(&mut self, pk: &String) -> Result<String, Self::Error> { let new = format!("NEW-{}", pk); Ok(new.to_string()) } - fn sha256(&mut self, hash: &String) -> Result<String, ()> { Ok(hash.to_string()) } - fn hash256(&mut self, hash: &String) -> Result<String, ()> { Ok(hash.to_string()) } - fn ripemd160(&mut self, hash: &String) -> Result<String, ()> { Ok(hash.to_string()) } - fn hash160(&mut self, hash: &String) -> Result<String, ()> { Ok(hash.to_string()) } + fn sha256(&mut self, hash: &String) -> Result<String, Self::Error> { + Ok(hash.to_string()) + } + fn hash256(&mut self, hash: &String) -> Result<String, Self::Error> { + Ok(hash.to_string()) + } + fn ripemd160(&mut self, hash: &String) -> Result<String, Self::Error> { + Ok(hash.to_string()) + } + fn hash160(&mut self, hash: &String) -> Result<String, Self::Error> { + Ok(hash.to_string()) + } } let policy = Policy::<String>::from_str("or(and(pk(A),pk(B)),pk(C))").unwrap(); let mut t = TestTranslator; diff --git a/src/policy/semantic.rs b/src/policy/semantic.rs index 7d2959764..62487a54a 100644 --- a/src/policy/semantic.rs +++ b/src/policy/semantic.rs @@ -120,8 +120,11 @@ impl<Pk: MiniscriptKey> Policy<Pk> { /// /// // If we also wanted to provide mapping of other associated types (sha256, older etc), /// // we would use the general [`Translator`] trait. - /// impl Translator<String, bitcoin::PublicKey, ()> for StrPkTranslator { - /// fn pk(&mut self, pk: &String) -> Result<bitcoin::PublicKey, ()> { + /// impl Translator<String> for StrPkTranslator { + /// type TargetPk = bitcoin::PublicKey; + /// type Error = (); + /// + /// fn pk(&mut self, pk: &String) -> Result<bitcoin::PublicKey, Self::Error> { /// self.pk_map.get(pk).copied().ok_or(()) // Dummy Err /// } /// @@ -140,10 +143,9 @@ impl<Pk: MiniscriptKey> Policy<Pk> { /// let expected_policy = Policy::from_str(&format!("and(pk({}),pk({}))", alice_pk, bob_pk)).unwrap(); /// assert_eq!(real_policy, expected_policy); /// ``` - pub fn translate_pk<Q, E, T>(&self, t: &mut T) -> Result<Policy<Q>, E> + pub fn translate_pk<T>(&self, t: &mut T) -> Result<Policy<T::TargetPk>, T::Error> where - T: Translator<Pk, Q, E>, - Q: MiniscriptKey, + T: Translator<Pk>, { use Policy::*; diff --git a/src/psbt/mod.rs b/src/psbt/mod.rs index 2c489ca89..96615df4c 100644 --- a/src/psbt/mod.rs +++ b/src/psbt/mod.rs @@ -25,7 +25,7 @@ use crate::miniscript::context::SigType; use crate::prelude::*; use crate::{ descriptor, interpreter, DefiniteDescriptorKey, Descriptor, DescriptorPublicKey, MiniscriptKey, - Preimage32, Satisfier, ToPublicKey, TranslatePk, Translator, + Preimage32, Satisfier, ToPublicKey, Translator, }; mod finalizer; @@ -976,9 +976,10 @@ struct KeySourceLookUp( pub secp256k1::Secp256k1<VerifyOnly>, ); -impl Translator<DefiniteDescriptorKey, bitcoin::PublicKey, descriptor::ConversionError> - for KeySourceLookUp -{ +impl Translator<DefiniteDescriptorKey> for KeySourceLookUp { + type TargetPk = bitcoin::PublicKey; + type Error = descriptor::ConversionError; + fn pk( &mut self, xpk: &DefiniteDescriptorKey, diff --git a/src/pub_macros.rs b/src/pub_macros.rs index bdb0d59b4..538d37f3c 100644 --- a/src/pub_macros.rs +++ b/src/pub_macros.rs @@ -27,9 +27,12 @@ /// /// // If we also wanted to provide mapping of other associated types(sha256, older etc), /// // we would use the general Translator Trait. -/// impl Translator<String, bitcoin::PublicKey, ()> for StrPkTranslator { +/// impl Translator<String> for StrPkTranslator { +/// type TargetPk = bitcoin::PublicKey; +/// type Error = (); +/// /// // Provides the translation public keys P -> Q -/// fn pk(&mut self, pk: &String) -> Result<bitcoin::PublicKey, ()> { +/// fn pk(&mut self, pk: &String) -> Result<bitcoin::PublicKey, Self::Error> { /// self.pk_map.get(pk).copied().ok_or(()) // Dummy Err /// } /// diff --git a/src/test_utils.rs b/src/test_utils.rs index 170e3c7f6..9d52b7c25 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -2,6 +2,7 @@ //! Generally useful utilities for test scripts +use core::convert::Infallible; use std::collections::HashMap; use std::str::FromStr; @@ -25,8 +26,11 @@ pub struct StrKeyTranslator { pub hash160_map: HashMap<String, hash160::Hash>, } -impl Translator<String, bitcoin::PublicKey, ()> for StrKeyTranslator { - fn pk(&mut self, pk: &String) -> Result<bitcoin::PublicKey, ()> { +impl Translator<String> for StrKeyTranslator { + type TargetPk = bitcoin::PublicKey; + type Error = Infallible; + + fn pk(&mut self, pk: &String) -> Result<bitcoin::PublicKey, Infallible> { let key = self.pk_map.get(pk).copied().unwrap_or_else(|| { bitcoin::PublicKey::from_str( "02c2122e30e73f7fe37986e3f81ded00158e94b7ad472369b83bbdd28a9a198a39", @@ -36,7 +40,7 @@ impl Translator<String, bitcoin::PublicKey, ()> for StrKeyTranslator { Ok(key) } - fn sha256(&mut self, _sha256: &String) -> Result<sha256::Hash, ()> { + fn sha256(&mut self, _sha256: &String) -> Result<sha256::Hash, Infallible> { let hash = sha256::Hash::from_str( "4ae81572f06e1b88fd5ced7a1a000945432e83e1551e6f721ee9c00b8cc33260", ) @@ -44,7 +48,7 @@ impl Translator<String, bitcoin::PublicKey, ()> for StrKeyTranslator { Ok(hash) } - fn hash256(&mut self, _hash256: &String) -> Result<hash256::Hash, ()> { + fn hash256(&mut self, _hash256: &String) -> Result<hash256::Hash, Infallible> { // hard coded value let hash = hash256::Hash::from_str( "4ae81572f06e1b88fd5ced7a1a000945432e83e1551e6f721ee9c00b8cc33260", @@ -53,12 +57,12 @@ impl Translator<String, bitcoin::PublicKey, ()> for StrKeyTranslator { Ok(hash) } - fn ripemd160(&mut self, _ripemd160: &String) -> Result<ripemd160::Hash, ()> { + fn ripemd160(&mut self, _ripemd160: &String) -> Result<ripemd160::Hash, Infallible> { let hash = ripemd160::Hash::from_str("4ae81572f06e1b88fd5ced7a1a00094543a0069").unwrap(); Ok(hash) } - fn hash160(&mut self, _hash160: &String) -> Result<hash160::Hash, ()> { + fn hash160(&mut self, _hash160: &String) -> Result<hash160::Hash, Infallible> { let hash = hash160::Hash::from_str("4ae81572f06e1b88fd5ced7a1a00094543a0069").unwrap(); Ok(hash) } @@ -74,8 +78,11 @@ pub struct StrXOnlyKeyTranslator { pub hash160_map: HashMap<String, hash160::Hash>, } -impl Translator<String, XOnlyPublicKey, ()> for StrXOnlyKeyTranslator { - fn pk(&mut self, pk: &String) -> Result<XOnlyPublicKey, ()> { +impl Translator<String> for StrXOnlyKeyTranslator { + type TargetPk = XOnlyPublicKey; + type Error = Infallible; + + fn pk(&mut self, pk: &String) -> Result<XOnlyPublicKey, Infallible> { let key = self.pk_map.get(pk).copied().unwrap_or_else(|| { XOnlyPublicKey::from_str( "c2122e30e73f7fe37986e3f81ded00158e94b7ad472369b83bbdd28a9a198a39", @@ -85,7 +92,7 @@ impl Translator<String, XOnlyPublicKey, ()> for StrXOnlyKeyTranslator { Ok(key) } - fn sha256(&mut self, _sha256: &String) -> Result<sha256::Hash, ()> { + fn sha256(&mut self, _sha256: &String) -> Result<sha256::Hash, Infallible> { let hash = sha256::Hash::from_str( "4ae81572f06e1b88fd5ced7a1a000945432e83e1551e6f721ee9c00b8cc33260", ) @@ -93,7 +100,7 @@ impl Translator<String, XOnlyPublicKey, ()> for StrXOnlyKeyTranslator { Ok(hash) } - fn hash256(&mut self, _hash256: &String) -> Result<hash256::Hash, ()> { + fn hash256(&mut self, _hash256: &String) -> Result<hash256::Hash, Infallible> { let hash = hash256::Hash::from_str( "4ae81572f06e1b88fd5ced7a1a000945432e83e1551e6f721ee9c00b8cc33260", ) @@ -101,12 +108,12 @@ impl Translator<String, XOnlyPublicKey, ()> for StrXOnlyKeyTranslator { Ok(hash) } - fn ripemd160(&mut self, _ripemd160: &String) -> Result<ripemd160::Hash, ()> { + fn ripemd160(&mut self, _ripemd160: &String) -> Result<ripemd160::Hash, Infallible> { let hash = ripemd160::Hash::from_str("4ae81572f06e1b88fd5ced7a1a00094543a0069").unwrap(); Ok(hash) } - fn hash160(&mut self, _hash160: &String) -> Result<hash160::Hash, ()> { + fn hash160(&mut self, _hash160: &String) -> Result<hash160::Hash, Infallible> { let hash = hash160::Hash::from_str("4ae81572f06e1b88fd5ced7a1a00094543a0069").unwrap(); Ok(hash) }