Merge rust-bitcoin/rust-bitcoin#2715: psbt: Use macro to hash instead of relying on `Hash` trait
9e4b092fce
psbt: Use macro instead of function (Tobin C. Harding) Pull request description: 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. ACKs for top commit: apoelstra: ACK9e4b092fce
Tree-SHA512: 8b788fa91d21bbae556c746c2e55e6e9395e022bedf13193555ef7482109b6ef5032b233c5f37543a31ebda49d9b4761c161ca0db501472047eb661a48e944b7
This commit is contained in:
commit
3c7ac53e89
|
@ -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<u8> = 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)) => {
|
||||
|
|
|
@ -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<H>(
|
||||
map: &mut BTreeMap<H, Vec<u8>>,
|
||||
raw_key: raw::Key,
|
||||
raw_value: Vec<u8>,
|
||||
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<u8> = Deserialize::deserialize(&raw_value)?;
|
||||
if <H as hashes::Hash>::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::*;
|
||||
|
|
Loading…
Reference in New Issue