// SPDX-License-Identifier: CC0-1.0 #[allow(unused_macros)] macro_rules! hex_psbt { ($s:expr) => { <$crate::psbt::Psbt>::deserialize( &<$crate::prelude::Vec<u8> as $crate::hex::FromHex>::from_hex($s).unwrap(), ) }; } #[cfg(test)] macro_rules! psbt_with_values { ($input:expr, $output:expr) => { Psbt { unsigned_tx: Transaction { version: transaction::Version::TWO, lock_time: absolute::LockTime::ZERO, input: vec![TxIn { previous_output: OutPoint { txid: "f61b1742ca13176464adb3cb66050c00787bb3a4eead37e985f2df1e37718126" .parse() .unwrap(), vout: 0, }, script_sig: ScriptBuf::new(), sequence: Sequence::ENABLE_LOCKTIME_NO_RBF, witness: Witness::default(), }], output: vec![TxOut { value: Amount::from_sat($output), script_pubkey: ScriptBuf::from_hex( "a9143545e6e33b832c47050f24d3eeb93c9c03948bc787", ) .unwrap(), }], }, xpub: Default::default(), version: 0, proprietary: BTreeMap::new(), unknown: BTreeMap::new(), inputs: vec![Input { witness_utxo: Some(TxOut { value: Amount::from_sat($input), script_pubkey: ScriptBuf::from_hex( "a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587", ) .unwrap(), }), ..Default::default() }], outputs: vec![], } }; } macro_rules! combine { ($thing:ident, $slf:ident, $other:ident) => { if let (&None, Some($thing)) = (&$slf.$thing, $other.$thing) { $slf.$thing = Some($thing); } }; } macro_rules! impl_psbt_de_serialize { ($thing:ty) => { impl_psbt_serialize!($thing); impl_psbt_deserialize!($thing); }; } macro_rules! impl_psbt_deserialize { ($thing:ty) => { impl $crate::psbt::serialize::Deserialize for $thing { fn deserialize(bytes: &[u8]) -> Result<Self, $crate::psbt::Error> { $crate::consensus::deserialize(&bytes[..]).map_err(|e| $crate::psbt::Error::from(e)) } } }; } macro_rules! impl_psbt_serialize { ($thing:ty) => { impl $crate::psbt::serialize::Serialize for $thing { fn serialize(&self) -> $crate::prelude::Vec<u8> { $crate::consensus::serialize(self) } } }; } macro_rules! impl_psbtmap_serialize { ($thing:ty) => { impl $crate::psbt::serialize::Serialize for $thing { fn serialize(&self) -> Vec<u8> { self.serialize_map() } } }; } macro_rules! impl_psbtmap_deserialize { ($thing:ty) => { impl $crate::psbt::serialize::Deserialize for $thing { fn deserialize(bytes: &[u8]) -> Result<Self, $crate::psbt::Error> { let mut decoder = bytes; Self::decode(&mut decoder) } } }; } macro_rules! impl_psbtmap_decoding { ($thing:ty) => { impl $thing { pub(crate) fn decode<R: $crate::io::Read + ?Sized>( r: &mut R, ) -> Result<Self, $crate::psbt::Error> { let mut rv: Self = core::default::Default::default(); loop { match $crate::psbt::raw::Pair::decode(r) { Ok(pair) => rv.insert_pair(pair)?, Err($crate::psbt::Error::NoMorePairs) => return Ok(rv), Err(e) => return Err(e), } } } } }; } macro_rules! impl_psbtmap_ser_de_serialize { ($thing:ty) => { impl_psbtmap_decoding!($thing); impl_psbtmap_serialize!($thing); impl_psbtmap_deserialize!($thing); }; } #[rustfmt::skip] macro_rules! impl_psbt_insert_pair { ($slf:ident.$unkeyed_name:ident <= <$raw_key:ident: _>|<$raw_value:ident: $unkeyed_value_type:ty>) => { if $raw_key.key.is_empty() { if $slf.$unkeyed_name.is_none() { let val: $unkeyed_value_type = $crate::psbt::serialize::Deserialize::deserialize(&$raw_value)?; $slf.$unkeyed_name = Some(val) } else { return Err($crate::psbt::Error::DuplicateKey($raw_key).into()); } } else { return Err($crate::psbt::Error::InvalidKey($raw_key).into()); } }; ($slf:ident.$keyed_name:ident <= <$raw_key:ident: $keyed_key_type:ty>|<$raw_value:ident: $keyed_value_type:ty>) => { if !$raw_key.key.is_empty() { let key_val: $keyed_key_type = $crate::psbt::serialize::Deserialize::deserialize(&$raw_key.key)?; match $slf.$keyed_name.entry(key_val) { $crate::prelude::btree_map::Entry::Vacant(empty_key) => { let val: $keyed_value_type = $crate::psbt::serialize::Deserialize::deserialize(&$raw_value)?; empty_key.insert(val); } $crate::prelude::btree_map::Entry::Occupied(_) => return Err($crate::psbt::Error::DuplicateKey($raw_key).into()), } } else { return Err($crate::psbt::Error::InvalidKey($raw_key).into()); } }; } #[rustfmt::skip] macro_rules! impl_psbt_get_pair { ($rv:ident.push($slf:ident.$unkeyed_name:ident, $unkeyed_typeval:ident)) => { if let Some(ref $unkeyed_name) = $slf.$unkeyed_name { $rv.push($crate::psbt::raw::Pair { key: $crate::psbt::raw::Key { type_value: $unkeyed_typeval, key: vec![], }, value: $crate::psbt::serialize::Serialize::serialize($unkeyed_name), }); } }; ($rv:ident.push_map($slf:ident.$keyed_name:ident, $keyed_typeval:ident)) => { for (key, val) in &$slf.$keyed_name { $rv.push($crate::psbt::raw::Pair { key: $crate::psbt::raw::Key { type_value: $keyed_typeval, key: $crate::psbt::serialize::Serialize::serialize(key), }, value: $crate::psbt::serialize::Serialize::serialize(val), }); } }; } // macros for serde of hashes macro_rules! impl_psbt_hash_de_serialize { ($hash_type:ty) => { impl_psbt_hash_serialize!($hash_type); impl_psbt_hash_deserialize!($hash_type); }; } macro_rules! impl_psbt_hash_deserialize { ($hash_type:ty) => { impl $crate::psbt::serialize::Deserialize for $hash_type { fn deserialize(bytes: &[u8]) -> Result<Self, $crate::psbt::Error> { <$hash_type>::from_slice(&bytes[..]).map_err(|e| $crate::psbt::Error::from(e)) } } }; } macro_rules! impl_psbt_hash_serialize { ($hash_type:ty) => { impl $crate::psbt::serialize::Serialize for $hash_type { fn serialize(&self) -> $crate::prelude::Vec<u8> { self.as_byte_array().to_vec() } } }; }