From 36b065981a10c30f37548f5df792885d5397730f Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sat, 24 Aug 2024 16:50:18 +0000 Subject: [PATCH] translator: make target pk and error associated types This is an annoying breaking change for users of the Translator trait but I think it greatly improves the ergonomics of using the trait. Rather than having it be parameterized over 3 types, it is now parameterized over just one (the "source pk type"). This matches how this trait is used in practice -- you typically have a miniscript/policy/whatever with a keytype Pk, and you want to use a translator from Pk to "whatever the translator maps to" with "whatever error the translator yields". So the only type parameter you really need to type is Pk; the others are irrelevant, and making the user name and type them is annoying. Since this eliminates the need to explicitly write out the error types except when actually implementing the trait, this also changes a ton of error types from () to Infallible, which is more efficient and correct. --- bitcoind-tests/tests/setup/test_util.rs | 30 ++++++++------ examples/big.rs | 9 +++-- examples/taproot.rs | 9 +++-- src/descriptor/bare.rs | 10 ++--- src/descriptor/mod.rs | 53 ++++++++++++++++--------- src/descriptor/segwitv0.rs | 10 ++--- src/descriptor/sh.rs | 5 +-- src/descriptor/sortedmulti.rs | 7 ++-- src/descriptor/tr.rs | 17 ++++---- src/interpreter/inner.rs | 19 +++++---- src/lib.rs | 51 +++++++++++++++--------- src/miniscript/mod.rs | 15 +++---- src/policy/concrete.rs | 28 ++++++++----- src/policy/semantic.rs | 12 +++--- src/psbt/mod.rs | 7 ++-- src/pub_macros.rs | 7 +++- src/test_utils.rs | 31 +++++++++------ 17 files changed, 192 insertions(+), 128 deletions(-) diff --git a/bitcoind-tests/tests/setup/test_util.rs b/bitcoind-tests/tests/setup/test_util.rs index b16e8ed47..64ffa6f5a 100644 --- a/bitcoind-tests/tests/setup/test_util.rs +++ b/bitcoind-tests/tests/setup/test_util.rs @@ -155,8 +155,11 @@ pub fn parse_insane_ms( #[derive(Debug, Clone)] struct StrDescPubKeyTranslator<'a>(usize, &'a PubData); -impl<'a> Translator for StrDescPubKeyTranslator<'a> { - fn pk(&mut self, pk_str: &String) -> Result { +impl<'a> Translator for StrDescPubKeyTranslator<'a> { + type TargetPk = DescriptorPublicKey; + type Error = core::convert::Infallible; + + fn pk(&mut self, pk_str: &String) -> Result { let avail = !pk_str.ends_with('!'); if avail { self.0 += 1; @@ -181,22 +184,22 @@ impl<'a> Translator for StrDescPubKeyTranslator } } - fn sha256(&mut self, sha256: &String) -> Result { + fn sha256(&mut self, sha256: &String) -> Result { let sha = sha256::Hash::from_str(sha256).unwrap(); Ok(sha) } - fn hash256(&mut self, hash256: &String) -> Result { + fn hash256(&mut self, hash256: &String) -> Result { let hash256 = hash256::Hash::from_str(hash256).unwrap(); Ok(hash256) } - fn ripemd160(&mut self, ripemd160: &String) -> Result { + fn ripemd160(&mut self, ripemd160: &String) -> Result { let ripemd160 = ripemd160::Hash::from_str(ripemd160).unwrap(); Ok(ripemd160) } - fn hash160(&mut self, hash160: &String) -> Result { + fn hash160(&mut self, hash160: &String) -> Result { let hash160 = hash160::Hash::from_str(hash160).unwrap(); Ok(hash160) } @@ -208,8 +211,11 @@ impl<'a> Translator for StrDescPubKeyTranslator #[derive(Debug, Clone)] struct StrTranslatorLoose<'a>(usize, &'a PubData); -impl<'a> Translator for StrTranslatorLoose<'a> { - fn pk(&mut self, pk_str: &String) -> Result { +impl<'a> Translator for StrTranslatorLoose<'a> { + type TargetPk = DescriptorPublicKey; + type Error = core::convert::Infallible; + + fn pk(&mut self, pk_str: &String) -> Result { let avail = !pk_str.ends_with('!'); if avail { self.0 += 1; @@ -238,22 +244,22 @@ impl<'a> Translator for StrTranslatorLoose<'a> } } - fn sha256(&mut self, sha256: &String) -> Result { + fn sha256(&mut self, sha256: &String) -> Result { let sha = sha256::Hash::from_str(sha256).unwrap(); Ok(sha) } - fn hash256(&mut self, hash256: &String) -> Result { + fn hash256(&mut self, hash256: &String) -> Result { let hash256 = hash256::Hash::from_str(hash256).unwrap(); Ok(hash256) } - fn ripemd160(&mut self, ripemd160: &String) -> Result { + fn ripemd160(&mut self, ripemd160: &String) -> Result { let ripemd160 = ripemd160::Hash::from_str(ripemd160).unwrap(); Ok(ripemd160) } - fn hash160(&mut self, hash160: &String) -> Result { + fn hash160(&mut self, hash160: &String) -> Result { let hash160 = hash160::Hash::from_str(hash160).unwrap(); Ok(hash160) } diff --git a/examples/big.rs b/examples/big.rs index 2a80f4de6..230d656b6 100644 --- a/examples/big.rs +++ b/examples/big.rs @@ -82,12 +82,15 @@ struct StrPkTranslator { pk_map: HashMap, } -impl Translator for StrPkTranslator { - fn pk(&mut self, pk: &String) -> Result { +impl Translator for StrPkTranslator { + type TargetPk = XOnlyPublicKey; + type Error = (); + + fn pk(&mut self, pk: &String) -> Result { 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 3ca109552..1e04f7b60 100644 --- a/examples/taproot.rs +++ b/examples/taproot.rs @@ -17,14 +17,17 @@ struct StrPkTranslator { pk_map: HashMap, } -impl Translator for StrPkTranslator { - fn pk(&mut self, pk: &String) -> Result { +impl Translator for StrPkTranslator { + type TargetPk = XOnlyPublicKey; + type Error = (); + + fn pk(&mut self, pk: &String) -> Result { 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 f720ac29f..176137ad8 100644 --- a/src/descriptor/bare.rs +++ b/src/descriptor/bare.rs @@ -94,10 +94,9 @@ impl Bare { } /// Converts the keys in the script from one type to another. - pub fn translate_pk(&self, t: &mut T) -> Result, TranslateErr> + pub fn translate_pk(&self, t: &mut T) -> Result, TranslateErr> where - T: Translator, - Q: MiniscriptKey, + T: Translator, { Bare::new(self.ms.translate_pk(t)?).map_err(TranslateErr::OuterError) } @@ -256,10 +255,9 @@ impl Pkh { 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(&self, t: &mut T) -> Result, TranslateErr> + pub fn translate_pk(&self, t: &mut T) -> Result, TranslateErr> where - T: Translator, - Q: MiniscriptKey, + T: Translator, { let res = Pkh::new(t.pk(&self.pk)?); match res { diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index 1c6393a85..1a2a7da16 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -361,10 +361,12 @@ impl Descriptor { } /// Converts a descriptor using one kind of keys to another kind of key. - pub fn translate_pk(&self, t: &mut T) -> Result, TranslateErr> + pub fn translate_pk( + &self, + t: &mut T, + ) -> Result, TranslateErr> where - T: Translator, - Q: MiniscriptKey, + T: Translator, { let desc = match *self { Descriptor::Bare(ref bare) => Descriptor::Bare(bare.translate_pk(t)?), @@ -600,7 +602,10 @@ impl Descriptor { ) -> Result, ConversionError> { struct Derivator(u32); - impl Translator for Derivator { + impl Translator for Derivator { + type TargetPk = DefiniteDescriptorKey; + type Error = ConversionError; + fn pk( &mut self, pk: &DescriptorPublicKey, @@ -691,9 +696,10 @@ impl Descriptor { struct KeyMapWrapper<'a, C: secp256k1::Signing>(KeyMap, &'a secp256k1::Secp256k1); - impl<'a, C: secp256k1::Signing> Translator - for KeyMapWrapper<'a, C> - { + impl<'a, C: secp256k1::Signing> Translator for KeyMapWrapper<'a, C> { + type TargetPk = DescriptorPublicKey; + type Error = Error; + fn pk(&mut self, pk: &String) -> Result { parse_key(pk, &mut self.0, self.1) } @@ -738,29 +744,35 @@ impl Descriptor { pub fn to_string_with_secret(&self, key_map: &KeyMap) -> String { struct KeyMapLookUp<'a>(&'a KeyMap); - impl<'a> Translator for KeyMapLookUp<'a> { - fn pk(&mut self, pk: &DescriptorPublicKey) -> Result { + impl<'a> Translator for KeyMapLookUp<'a> { + type TargetPk = String; + type Error = core::convert::Infallible; + + fn pk(&mut self, pk: &DescriptorPublicKey) -> Result { key_to_string(pk, self.0) } - fn sha256(&mut self, sha256: &sha256::Hash) -> Result { + fn sha256(&mut self, sha256: &sha256::Hash) -> Result { Ok(sha256.to_string()) } - fn hash256(&mut self, hash256: &hash256::Hash) -> Result { + fn hash256(&mut self, hash256: &hash256::Hash) -> Result { Ok(hash256.to_string()) } - fn ripemd160(&mut self, ripemd160: &ripemd160::Hash) -> Result { + fn ripemd160(&mut self, ripemd160: &ripemd160::Hash) -> Result { Ok(ripemd160.to_string()) } - fn hash160(&mut self, hash160: &hash160::Hash) -> Result { + fn hash160(&mut self, hash160: &hash160::Hash) -> Result { Ok(hash160.to_string()) } } - fn key_to_string(pk: &DescriptorPublicKey, key_map: &KeyMap) -> Result { + fn key_to_string( + pk: &DescriptorPublicKey, + key_map: &KeyMap, + ) -> Result { Ok(match key_map.get(pk) { Some(secret) => secret.to_string(), None => pk.to_string(), @@ -835,7 +847,10 @@ impl Descriptor { // Now, transform the multipath key of each descriptor into a single-key using each index. struct IndexChoser(usize); - impl Translator for IndexChoser { + impl Translator for IndexChoser { + type TargetPk = DescriptorPublicKey; + type Error = Error; + fn pk(&mut self, pk: &DescriptorPublicKey) -> Result { match pk { DescriptorPublicKey::Single(..) | DescriptorPublicKey::XPub(..) => { @@ -892,10 +907,10 @@ impl Descriptor { ) -> Result, ConversionError> { struct Derivator<'a, C: secp256k1::Verification>(&'a secp256k1::Secp256k1); - impl<'a, C: secp256k1::Verification> - Translator - for Derivator<'a, C> - { + impl<'a, C: secp256k1::Verification> Translator 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 2a30f1db1..2f2532b85 100644 --- a/src/descriptor/segwitv0.rs +++ b/src/descriptor/segwitv0.rs @@ -130,10 +130,9 @@ impl Wsh { } /// Converts the keys in a script from one type to another. - pub fn translate_pk(&self, t: &mut T) -> Result, TranslateErr> + pub fn translate_pk(&self, t: &mut T) -> Result, TranslateErr> where - T: Translator, - Q: MiniscriptKey, + T: Translator, { let inner = match self.inner { WshInner::SortedMulti(ref smv) => WshInner::SortedMulti(smv.translate_pk(t)?), @@ -366,10 +365,9 @@ impl Wpkh { 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(&self, t: &mut T) -> Result, TranslateErr> + pub fn translate_pk(&self, t: &mut T) -> Result, TranslateErr> where - T: Translator, - Q: MiniscriptKey, + T: Translator, { let res = Wpkh::new(t.pk(&self.pk)?); match res { diff --git a/src/descriptor/sh.rs b/src/descriptor/sh.rs index 99923ca77..cf05c1b71 100644 --- a/src/descriptor/sh.rs +++ b/src/descriptor/sh.rs @@ -261,10 +261,9 @@ impl Sh { } /// Converts the keys in a script from one type to another. - pub fn translate_pk(&self, t: &mut T) -> Result, TranslateErr> + pub fn translate_pk(&self, t: &mut T) -> Result, TranslateErr> where - T: Translator, - Q: MiniscriptKey, + T: Translator, { let inner = match self.inner { ShInner::Wsh(ref wsh) => ShInner::Wsh(wsh.translate_pk(t)?), 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 SortedMultiVec { /// 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( + pub fn translate_pk( &self, t: &mut T, - ) -> Result, TranslateErr> + ) -> Result, TranslateErr> where - T: Translator, - Q: MiniscriptKey, + T: Translator, { 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 1716682d9..2f505780c 100644 --- a/src/descriptor/tr.rs +++ b/src/descriptor/tr.rs @@ -132,10 +132,9 @@ impl TapTree { pub fn iter(&self) -> TapTreeIter { TapTreeIter { stack: vec![(0, self)] } } // Helper function to translate keys - fn translate_helper(&self, t: &mut T) -> Result, TranslateErr> + fn translate_helper(&self, t: &mut T) -> Result, TranslateErr> where - T: Translator, - Q: MiniscriptKey, + T: Translator, { let frag = match *self { TapTree::Tree { ref left, ref right, ref height } => TapTree::Tree { @@ -353,17 +352,19 @@ impl Tr { } /// Converts keys from one type of public key to another. - pub fn translate_pk(&self, translate: &mut T) -> Result, TranslateErr> + pub fn translate_pk( + &self, + translate: &mut T, + ) -> Result, TranslateErr> where - T: Translator, - Q: MiniscriptKey, + T: Translator, { 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))?; + let translate_desc = + Tr::new(translate.pk(&self.internal_key)?, tree).map_err(TranslateErr::OuterError)?; Ok(translate_desc) } } 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 ToNoChecks for Miniscript { fn to_no_checks_ms(&self) -> Miniscript { struct TranslateFullPk; - impl Translator for TranslateFullPk { - fn pk(&mut self, pk: &bitcoin::PublicKey) -> Result { + impl Translator for TranslateFullPk { + type TargetPk = BitcoinKey; + type Error = core::convert::Infallible; + + fn pk(&mut self, pk: &bitcoin::PublicKey) -> Result { 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 ToNoChecks for Miniscript { impl ToNoChecks for Miniscript { fn to_no_checks_ms(&self) -> Miniscript { - // specify the () error type as this cannot error struct TranslateXOnlyPk; - impl Translator for TranslateXOnlyPk { - fn pk(&mut self, pk: &bitcoin::key::XOnlyPublicKey) -> Result { + impl Translator for TranslateXOnlyPk { + type TargetPk = BitcoinKey; + type Error = core::convert::Infallible; + + fn pk(&mut self, pk: &bitcoin::key::XOnlyPublicKey) -> Result { 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 7f7040f29..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 -where - P: MiniscriptKey, - Q: MiniscriptKey, -{ - /// Translates public keys P -> Q. - fn pk(&mut self, pk: &P) -> Result; - - /// Provides the translation from P::Sha256 -> Q::Sha256 - fn sha256(&mut self, sha256: &P::Sha256) -> Result; - - /// Provides the translation from P::Hash256 -> Q::Hash256 - fn hash256(&mut self, hash256: &P::Hash256) -> Result; - - /// Translates ripemd160 hashes from P::Ripemd160 -> Q::Ripemd160 - fn ripemd160(&mut self, ripemd160: &P::Ripemd160) -> Result; - - /// Translates hash160 hashes from P::Hash160 -> Q::Hash160 - fn hash160(&mut self, hash160: &P::Hash160) -> Result; +pub trait Translator { + /// 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; + + /// Translates SHA256 hashes. + fn sha256( + &mut self, + sha256: &P::Sha256, + ) -> Result<::Sha256, Self::Error>; + + /// Translates HASH256 hashes. + fn hash256( + &mut self, + hash256: &P::Hash256, + ) -> Result<::Hash256, Self::Error>; + + /// Translates RIPEMD160 hashes. + fn ripemd160( + &mut self, + ripemd160: &P::Ripemd160, + ) -> Result<::Ripemd160, Self::Error>; + + /// Translates HASH160 hashes. + fn hash160( + &mut self, + hash160: &P::Hash160, + ) -> Result<::Hash160, Self::Error>; } /// An enum for representing translation errors diff --git a/src/miniscript/mod.rs b/src/miniscript/mod.rs index 0091691e5..1a68606ba 100644 --- a/src/miniscript/mod.rs +++ b/src/miniscript/mod.rs @@ -516,22 +516,23 @@ impl ForEachKey for Miniscript Miniscript { /// Translates a struct from one generic to another where the translation /// for Pk is provided by [`Translator`] - pub fn translate_pk(&self, t: &mut T) -> Result, TranslateErr> + pub fn translate_pk( + &self, + t: &mut T, + ) -> Result, TranslateErr> where - T: Translator, - Q: MiniscriptKey, + T: Translator, { self.translate_pk_ctx(t) } - pub(super) fn translate_pk_ctx( + pub(super) fn translate_pk_ctx( &self, t: &mut T, - ) -> Result, TranslateErr> + ) -> Result, TranslateErr> where - Q: MiniscriptKey, CtxQ: ScriptContext, - T: Translator, + T: Translator, { let mut translated = vec![]; for data in self.rtl_post_order_iter() { 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 Policy { /// 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(&self, t: &mut T) -> Result, E> + pub fn translate_pk(&self, t: &mut T) -> Result, T::Error> where - T: Translator, - Q: MiniscriptKey, + T: Translator, { use Policy::*; @@ -1140,15 +1139,26 @@ mod tests { #[test] fn tranaslate_pk() { pub struct TestTranslator; - impl Translator for TestTranslator { - fn pk(&mut self, pk: &String) -> Result { + impl Translator for TestTranslator { + type TargetPk = String; + type Error = core::convert::Infallible; + + fn pk(&mut self, pk: &String) -> Result { let new = format!("NEW-{}", pk); Ok(new.to_string()) } - fn sha256(&mut self, hash: &String) -> Result { Ok(hash.to_string()) } - fn hash256(&mut self, hash: &String) -> Result { Ok(hash.to_string()) } - fn ripemd160(&mut self, hash: &String) -> Result { Ok(hash.to_string()) } - fn hash160(&mut self, hash: &String) -> Result { Ok(hash.to_string()) } + fn sha256(&mut self, hash: &String) -> Result { + Ok(hash.to_string()) + } + fn hash256(&mut self, hash: &String) -> Result { + Ok(hash.to_string()) + } + fn ripemd160(&mut self, hash: &String) -> Result { + Ok(hash.to_string()) + } + fn hash160(&mut self, hash: &String) -> Result { + Ok(hash.to_string()) + } } let policy = Policy::::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 Policy { /// /// // If we also wanted to provide mapping of other associated types (sha256, older etc), /// // we would use the general [`Translator`] trait. - /// impl Translator for StrPkTranslator { - /// fn pk(&mut self, pk: &String) -> Result { + /// impl Translator for StrPkTranslator { + /// type TargetPk = bitcoin::PublicKey; + /// type Error = (); + /// + /// fn pk(&mut self, pk: &String) -> Result { /// self.pk_map.get(pk).copied().ok_or(()) // Dummy Err /// } /// @@ -140,10 +143,9 @@ impl Policy { /// 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(&self, t: &mut T) -> Result, E> + pub fn translate_pk(&self, t: &mut T) -> Result, T::Error> where - T: Translator, - Q: MiniscriptKey, + T: Translator, { use Policy::*; diff --git a/src/psbt/mod.rs b/src/psbt/mod.rs index bb06bb3f2..96615df4c 100644 --- a/src/psbt/mod.rs +++ b/src/psbt/mod.rs @@ -976,9 +976,10 @@ struct KeySourceLookUp( pub secp256k1::Secp256k1, ); -impl Translator - for KeySourceLookUp -{ +impl Translator 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 for StrPkTranslator { +/// impl Translator for StrPkTranslator { +/// type TargetPk = bitcoin::PublicKey; +/// type Error = (); +/// /// // Provides the translation public keys P -> Q -/// fn pk(&mut self, pk: &String) -> Result { +/// fn pk(&mut self, pk: &String) -> Result { /// 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, } -impl Translator for StrKeyTranslator { - fn pk(&mut self, pk: &String) -> Result { +impl Translator for StrKeyTranslator { + type TargetPk = bitcoin::PublicKey; + type Error = Infallible; + + fn pk(&mut self, pk: &String) -> Result { let key = self.pk_map.get(pk).copied().unwrap_or_else(|| { bitcoin::PublicKey::from_str( "02c2122e30e73f7fe37986e3f81ded00158e94b7ad472369b83bbdd28a9a198a39", @@ -36,7 +40,7 @@ impl Translator for StrKeyTranslator { Ok(key) } - fn sha256(&mut self, _sha256: &String) -> Result { + fn sha256(&mut self, _sha256: &String) -> Result { let hash = sha256::Hash::from_str( "4ae81572f06e1b88fd5ced7a1a000945432e83e1551e6f721ee9c00b8cc33260", ) @@ -44,7 +48,7 @@ impl Translator for StrKeyTranslator { Ok(hash) } - fn hash256(&mut self, _hash256: &String) -> Result { + fn hash256(&mut self, _hash256: &String) -> Result { // hard coded value let hash = hash256::Hash::from_str( "4ae81572f06e1b88fd5ced7a1a000945432e83e1551e6f721ee9c00b8cc33260", @@ -53,12 +57,12 @@ impl Translator for StrKeyTranslator { Ok(hash) } - fn ripemd160(&mut self, _ripemd160: &String) -> Result { + fn ripemd160(&mut self, _ripemd160: &String) -> Result { let hash = ripemd160::Hash::from_str("4ae81572f06e1b88fd5ced7a1a00094543a0069").unwrap(); Ok(hash) } - fn hash160(&mut self, _hash160: &String) -> Result { + fn hash160(&mut self, _hash160: &String) -> Result { let hash = hash160::Hash::from_str("4ae81572f06e1b88fd5ced7a1a00094543a0069").unwrap(); Ok(hash) } @@ -74,8 +78,11 @@ pub struct StrXOnlyKeyTranslator { pub hash160_map: HashMap, } -impl Translator for StrXOnlyKeyTranslator { - fn pk(&mut self, pk: &String) -> Result { +impl Translator for StrXOnlyKeyTranslator { + type TargetPk = XOnlyPublicKey; + type Error = Infallible; + + fn pk(&mut self, pk: &String) -> Result { let key = self.pk_map.get(pk).copied().unwrap_or_else(|| { XOnlyPublicKey::from_str( "c2122e30e73f7fe37986e3f81ded00158e94b7ad472369b83bbdd28a9a198a39", @@ -85,7 +92,7 @@ impl Translator for StrXOnlyKeyTranslator { Ok(key) } - fn sha256(&mut self, _sha256: &String) -> Result { + fn sha256(&mut self, _sha256: &String) -> Result { let hash = sha256::Hash::from_str( "4ae81572f06e1b88fd5ced7a1a000945432e83e1551e6f721ee9c00b8cc33260", ) @@ -93,7 +100,7 @@ impl Translator for StrXOnlyKeyTranslator { Ok(hash) } - fn hash256(&mut self, _hash256: &String) -> Result { + fn hash256(&mut self, _hash256: &String) -> Result { let hash = hash256::Hash::from_str( "4ae81572f06e1b88fd5ced7a1a000945432e83e1551e6f721ee9c00b8cc33260", ) @@ -101,12 +108,12 @@ impl Translator for StrXOnlyKeyTranslator { Ok(hash) } - fn ripemd160(&mut self, _ripemd160: &String) -> Result { + fn ripemd160(&mut self, _ripemd160: &String) -> Result { let hash = ripemd160::Hash::from_str("4ae81572f06e1b88fd5ced7a1a00094543a0069").unwrap(); Ok(hash) } - fn hash160(&mut self, _hash160: &String) -> Result { + fn hash160(&mut self, _hash160: &String) -> Result { let hash = hash160::Hash::from_str("4ae81572f06e1b88fd5ced7a1a00094543a0069").unwrap(); Ok(hash) }