From 9e4b092fce79501cb8cdd650fc34f66d01db7a7b Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 21 May 2024 08:56:21 +1000 Subject: [PATCH] psbt: Use macro instead of function We have a private function that makes use of the `Hash` trait to generically hash map entries. This usage makes patching the `hashes` module difficult. We can achieve the same thing by using a macro and passing in the concrete type. This is an internal change, no effect on logic or public API. --- bitcoin/src/psbt/macros.rs | 24 +++++++++++++ bitcoin/src/psbt/map/input.rs | 66 +++++++---------------------------- 2 files changed, 36 insertions(+), 54 deletions(-) diff --git a/bitcoin/src/psbt/macros.rs b/bitcoin/src/psbt/macros.rs index 556c83a71..fb06bbcdf 100644 --- a/bitcoin/src/psbt/macros.rs +++ b/bitcoin/src/psbt/macros.rs @@ -111,6 +111,30 @@ macro_rules! impl_psbt_insert_pair { }; } +#[rustfmt::skip] +macro_rules! psbt_insert_hash_pair { + (&mut $slf:ident.$map:ident <= $raw_key:ident|$raw_value:ident|$hash:path|$hash_type_error:path) => { + if $raw_key.key.is_empty() { + return Err(psbt::Error::InvalidKey($raw_key)); + } + let key_val: $hash = Deserialize::deserialize(&$raw_key.key)?; + match $slf.$map.entry(key_val) { + btree_map::Entry::Vacant(empty_key) => { + let val: Vec = Deserialize::deserialize(&$raw_value)?; + if <$hash as hashes::Hash>::hash(&val) != key_val { + return Err(psbt::Error::InvalidPreimageHashPair { + preimage: val.into_boxed_slice(), + hash: Box::from(key_val.borrow()), + hash_type: $hash_type_error, + }); + } + empty_key.insert(val); + } + btree_map::Entry::Occupied(_) => return Err(psbt::Error::DuplicateKey($raw_key)), + } + } +} + #[rustfmt::skip] macro_rules! impl_psbt_get_pair { ($rv:ident.push($slf:ident.$unkeyed_name:ident, $unkeyed_typeval:ident)) => { diff --git a/bitcoin/src/psbt/map/input.rs b/bitcoin/src/psbt/map/input.rs index cfe778111..1be15c826 100644 --- a/bitcoin/src/psbt/map/input.rs +++ b/bitcoin/src/psbt/map/input.rs @@ -300,36 +300,24 @@ impl Input { } } PSBT_IN_RIPEMD160 => { - psbt_insert_hash_pair( - &mut self.ripemd160_preimages, - raw_key, - raw_value, - error::PsbtHash::Ripemd, - )?; + psbt_insert_hash_pair! { + &mut self.ripemd160_preimages <= raw_key|raw_value|ripemd160::Hash|error::PsbtHash::Ripemd + } } PSBT_IN_SHA256 => { - psbt_insert_hash_pair( - &mut self.sha256_preimages, - raw_key, - raw_value, - error::PsbtHash::Sha256, - )?; + psbt_insert_hash_pair! { + &mut self.sha256_preimages <= raw_key|raw_value|sha256::Hash|error::PsbtHash::Sha256 + } } PSBT_IN_HASH160 => { - psbt_insert_hash_pair( - &mut self.hash160_preimages, - raw_key, - raw_value, - error::PsbtHash::Hash160, - )?; + psbt_insert_hash_pair! { + &mut self.hash160_preimages <= raw_key|raw_value|hash160::Hash|error::PsbtHash::Hash160 + } } PSBT_IN_HASH256 => { - psbt_insert_hash_pair( - &mut self.hash256_preimages, - raw_key, - raw_value, - error::PsbtHash::Hash256, - )?; + psbt_insert_hash_pair! { + &mut self.hash256_preimages <= raw_key|raw_value|sha256d::Hash|error::PsbtHash::Hash256 + } } PSBT_IN_TAP_KEY_SIG => { impl_psbt_insert_pair! { @@ -505,36 +493,6 @@ impl Map for Input { impl_psbtmap_ser_de_serialize!(Input); -fn psbt_insert_hash_pair( - map: &mut BTreeMap>, - raw_key: raw::Key, - raw_value: Vec, - hash_type: error::PsbtHash, -) -> Result<(), Error> -where - H: hashes::Hash + Deserialize, -{ - if raw_key.key.is_empty() { - return Err(psbt::Error::InvalidKey(raw_key)); - } - let key_val: H = Deserialize::deserialize(&raw_key.key)?; - match map.entry(key_val) { - btree_map::Entry::Vacant(empty_key) => { - let val: Vec = Deserialize::deserialize(&raw_value)?; - if ::hash(&val) != key_val { - return Err(psbt::Error::InvalidPreimageHashPair { - preimage: val.into_boxed_slice(), - hash: Box::from(key_val.as_ref()), - hash_type, - }); - } - empty_key.insert(val); - Ok(()) - } - btree_map::Entry::Occupied(_) => Err(psbt::Error::DuplicateKey(raw_key)), - } -} - #[cfg(test)] mod test { use super::*;