From 9aa235c24d65d23de2afc21fcbd019892bf4ad2a Mon Sep 17 00:00:00 2001 From: Daniel Roberts Date: Sun, 11 May 2025 10:28:19 -0500 Subject: [PATCH] BREAKING: Change Psbt serde implementations Replace derived Psbt serde implementation with one that conforms to BIP-174. In human readable serde contexts, serialize to the base64 encoded format, and in binary serde contexts, serialize to the raw binary format. The previous derived serde implementation cannot be used in a backward or forward compatible way in binary formats like bincode, which means that every field added to the Psbt struct would break serde de/serialization into binary formats. Instead, this one-time breaking change will fix the issue going forward. Downstream users with persisted data in the old serde format should continue using 0.32.x to create migrations to the new format. --- bitcoin/CHANGELOG.md | 4 + bitcoin/Cargo.toml | 2 +- bitcoin/src/lib.rs | 2 - bitcoin/src/psbt/map/input.rs | 12 - bitcoin/src/psbt/map/output.rs | 5 - bitcoin/src/psbt/mod.rs | 50 ++- bitcoin/src/psbt/raw.rs | 7 - bitcoin/src/serde_utils.rs | 298 ------------------ .../tests/data/serde/proprietary_key_bincode | Bin 32 -> 0 bytes bitcoin/tests/data/serde/psbt_base64.json | 1 + bitcoin/tests/data/serde/psbt_bincode | Bin 1377 -> 810 bytes bitcoin/tests/data/serde/raw_pair_bincode | Bin 32 -> 0 bytes bitcoin/tests/serde.rs | 29 +- 13 files changed, 58 insertions(+), 352 deletions(-) delete mode 100644 bitcoin/src/serde_utils.rs delete mode 100644 bitcoin/tests/data/serde/proprietary_key_bincode create mode 100644 bitcoin/tests/data/serde/psbt_base64.json delete mode 100644 bitcoin/tests/data/serde/raw_pair_bincode diff --git a/bitcoin/CHANGELOG.md b/bitcoin/CHANGELOG.md index bbe596b71..6b593c7bf 100644 --- a/bitcoin/CHANGELOG.md +++ b/bitcoin/CHANGELOG.md @@ -4,6 +4,10 @@ - Use MAX_MONEY in serde regression test [#3950](https://github.com/rust-bitcoin/rust-bitcoin/pull/3950) +## Breaking changes + +- Change Psbt serde implementation to contextually use the PSBT binary or base64 encoded formats described in BIP-174. + # 0.33.0-alpha.0 - 2024-11-18 This series of alpha releases is meant for two things: diff --git a/bitcoin/Cargo.toml b/bitcoin/Cargo.toml index 075ddbd89..39547f023 100644 --- a/bitcoin/Cargo.toml +++ b/bitcoin/Cargo.toml @@ -19,7 +19,7 @@ default = [ "std", "secp-recovery" ] std = ["base58/std", "bech32/std", "hashes/std", "hex/std", "internals/std", "io/std", "primitives/std", "secp256k1/std", "units/std", "base64?/std", "bitcoinconsensus?/std"] rand-std = ["secp256k1/rand", "std"] rand = ["secp256k1/rand"] -serde = ["dep:serde", "hashes/serde", "internals/serde", "primitives/serde", "secp256k1/serde", "units/serde"] +serde = ["base64", "dep:serde", "hashes/serde", "internals/serde", "primitives/serde", "secp256k1/serde", "units/serde"] secp-lowmemory = ["secp256k1/lowmemory"] secp-recovery = ["secp256k1/recovery"] arbitrary = ["dep:arbitrary", "units/arbitrary", "primitives/arbitrary"] diff --git a/bitcoin/src/lib.rs b/bitcoin/src/lib.rs index a57ababde..cb68c3543 100644 --- a/bitcoin/src/lib.rs +++ b/bitcoin/src/lib.rs @@ -92,8 +92,6 @@ pub extern crate secp256k1; extern crate serde; mod internal_macros; -#[cfg(feature = "serde")] -mod serde_utils; #[macro_use] pub mod p2p; diff --git a/bitcoin/src/psbt/map/input.rs b/bitcoin/src/psbt/map/input.rs index d33be651b..287c7f362 100644 --- a/bitcoin/src/psbt/map/input.rs +++ b/bitcoin/src/psbt/map/input.rs @@ -65,7 +65,6 @@ const PSBT_IN_PROPRIETARY: u64 = 0xFC; /// A key-value map for an input of the corresponding index in the unsigned /// transaction. #[derive(Clone, Default, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Input { /// The non-witness transaction this input spends from. Should only be /// `Option::Some` for inputs which spend non-SegWit outputs or @@ -87,7 +86,6 @@ pub struct Input { pub witness_script: Option, /// A map from public keys needed to sign this input to their corresponding /// master key fingerprints and derivation paths. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))] pub bip32_derivation: BTreeMap, /// The finalized, fully-constructed scriptSig with signatures and any other /// scripts necessary for this input to pass validation. @@ -96,37 +94,28 @@ pub struct Input { /// other scripts necessary for this input to pass validation. pub final_script_witness: Option, /// RIPEMD160 hash to preimage map. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))] pub ripemd160_preimages: BTreeMap>, /// SHA256 hash to preimage map. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))] pub sha256_preimages: BTreeMap>, /// HASH160 hash to preimage map. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))] pub hash160_preimages: BTreeMap>, /// HASH256 hash to preimage map. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))] pub hash256_preimages: BTreeMap>, /// Serialized Taproot signature with sighash type for key spend. pub tap_key_sig: Option, /// Map of `|` with signature. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))] pub tap_script_sigs: BTreeMap<(XOnlyPublicKey, TapLeafHash), taproot::Signature>, /// Map of Control blocks to Script version pair. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))] pub tap_scripts: BTreeMap, /// Map of tap root x only keys to origin info and leaf hashes contained in it. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))] pub tap_key_origins: BTreeMap, KeySource)>, /// Taproot Internal key. pub tap_internal_key: Option, /// Taproot Merkle root. pub tap_merkle_root: Option, /// Proprietary key-value pairs for this input. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))] pub proprietary: BTreeMap>, /// Unknown key-value pairs for this input. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))] pub unknown: BTreeMap>, } @@ -147,7 +136,6 @@ pub struct Input { /// let _tap_sighash_all: PsbtSighashType = TapSighashType::All.into(); /// ``` #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct PsbtSighashType { pub(in crate::psbt) inner: u32, } diff --git a/bitcoin/src/psbt/map/output.rs b/bitcoin/src/psbt/map/output.rs index 22e28abc6..7f86bdb65 100644 --- a/bitcoin/src/psbt/map/output.rs +++ b/bitcoin/src/psbt/map/output.rs @@ -26,7 +26,6 @@ const PSBT_OUT_PROPRIETARY: u64 = 0xFC; /// A key-value map for an output of the corresponding index in the unsigned /// transaction. #[derive(Clone, Default, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Output { /// The redeem script for this output. pub redeem_script: Option, @@ -34,20 +33,16 @@ pub struct Output { pub witness_script: Option, /// A map from public keys needed to spend this output to their /// corresponding master key fingerprints and derivation paths. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))] pub bip32_derivation: BTreeMap, /// The internal pubkey. pub tap_internal_key: Option, /// Taproot Output tree. pub tap_tree: Option, /// Map of tap root x only keys to origin info and leaf hashes contained in it. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))] pub tap_key_origins: BTreeMap, KeySource)>, /// Proprietary key-value pairs for this output. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))] pub proprietary: BTreeMap>, /// Unknown key-value pairs for this output. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))] pub unknown: BTreeMap>, } diff --git a/bitcoin/src/psbt/mod.rs b/bitcoin/src/psbt/mod.rs index 47be38fa8..a9c8c3951 100644 --- a/bitcoin/src/psbt/mod.rs +++ b/bitcoin/src/psbt/mod.rs @@ -40,7 +40,6 @@ pub use self::{ /// A Partially Signed Transaction. #[derive(Debug, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Psbt { /// The unsigned transaction, scriptSigs and witnesses for each input must be empty. pub unsigned_tx: Transaction, @@ -50,10 +49,8 @@ pub struct Psbt { /// derivation path as defined by BIP 32. pub xpub: BTreeMap, /// Global proprietary key-value pairs. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))] pub proprietary: BTreeMap>, /// Unknown global key-value pairs. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))] pub unknown: BTreeMap>, /// The corresponding key-value map for each input in the unsigned transaction. @@ -731,6 +728,53 @@ impl Psbt { } } +#[cfg(feature = "serde")] +impl serde::Serialize for Psbt { + fn serialize(&self, serializer: S) -> Result { + use crate::prelude::ToString; + + if serializer.is_human_readable() { + serializer.serialize_str(&self.to_string()) + } else { + serializer.serialize_bytes(&self.serialize()) + } + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for Psbt { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de> + { + struct Visitor; + + impl<'de> serde::de::Visitor<'de> for Visitor + { + type Value = Psbt; + + fn expecting(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "a psbt") + } + + fn visit_bytes(self, bytes: &[u8]) -> Result { + Psbt::deserialize(bytes) + .map_err(|e| serde::de::Error::custom(e)) + } + + fn visit_str(self, s: &str) -> Result { + s.parse().map_err(|e| serde::de::Error::custom(e)) + } + } + + if deserializer.is_human_readable() { + deserializer.deserialize_str(Visitor) + } else { + deserializer.deserialize_bytes(Visitor) + } + } +} + /// Data required to call [`GetKey`] to get the private key to sign an input. #[derive(Clone, Debug, PartialEq, Eq)] #[non_exhaustive] diff --git a/bitcoin/src/psbt/raw.rs b/bitcoin/src/psbt/raw.rs index 4502bde61..205d076b5 100644 --- a/bitcoin/src/psbt/raw.rs +++ b/bitcoin/src/psbt/raw.rs @@ -21,25 +21,21 @@ use crate::psbt::Error; /// /// ` := ` #[derive(Debug, PartialEq, Hash, Eq, Clone, Ord, PartialOrd)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Key { /// The type of this PSBT key. pub type_value: u64, // Encoded as a compact size. /// The key data itself in raw byte form. - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::hex_bytes"))] pub key_data: Vec, } /// A PSBT key-value pair in its raw byte form. /// ` := ` #[derive(Debug, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Pair { /// The key of this key-value pair. pub key: Key, /// The value data of this key-value pair in raw byte form. /// ` := ` - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::hex_bytes"))] pub value: Vec, } @@ -49,19 +45,16 @@ pub type ProprietaryType = u64; /// Proprietary keys (i.e. keys starting with 0xFC byte) with their internal /// structure according to BIP 174. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ProprietaryKey where Subtype: Copy + From + Into, { /// Proprietary type prefix used for grouping together keys under some /// application and avoid namespace collision - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::hex_bytes"))] pub prefix: Vec, /// Custom proprietary subtype pub subtype: Subtype, /// Additional key bytes (like serialized public key data etc) - #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::hex_bytes"))] pub key: Vec, } diff --git a/bitcoin/src/serde_utils.rs b/bitcoin/src/serde_utils.rs deleted file mode 100644 index df306d9df..000000000 --- a/bitcoin/src/serde_utils.rs +++ /dev/null @@ -1,298 +0,0 @@ -// SPDX-License-Identifier: CC0-1.0 - -//! Bitcoin serde utilities. -//! -//! This module is for special serde serializations. - -pub(crate) struct SerializeBytesAsHex<'a>(pub(crate) &'a [u8]); - -impl serde::Serialize for SerializeBytesAsHex<'_> { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - use hex::DisplayHex; - - serializer.collect_str(&format_args!("{:x}", self.0.as_hex())) - } -} - -pub mod btreemap_byte_values { - //! Module for serialization of BTreeMaps with hex byte values. - #![allow(missing_docs)] - - // NOTE: This module can be exactly copied to use with HashMap. - - use hex::FromHex; - - use crate::prelude::{BTreeMap, Vec}; - - pub fn serialize(v: &BTreeMap>, s: S) -> Result - where - S: serde::Serializer, - T: serde::Serialize + core::hash::Hash + Eq + Ord, - { - use serde::ser::SerializeMap; - - // Don't do anything special when not human readable. - if !s.is_human_readable() { - serde::Serialize::serialize(v, s) - } else { - let mut map = s.serialize_map(Some(v.len()))?; - for (key, value) in v.iter() { - map.serialize_entry(key, &super::SerializeBytesAsHex(value))?; - } - map.end() - } - } - - pub fn deserialize<'de, D, T>(d: D) -> Result>, D::Error> - where - D: serde::Deserializer<'de>, - T: serde::Deserialize<'de> + core::hash::Hash + Eq + Ord, - { - use core::marker::PhantomData; - - struct Visitor(PhantomData); - impl<'de, T> serde::de::Visitor<'de> for Visitor - where - T: serde::Deserialize<'de> + core::hash::Hash + Eq + Ord, - { - type Value = BTreeMap>; - - fn expecting(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - write!(f, "a map with hexadecimal values") - } - - fn visit_map>( - self, - mut a: A, - ) -> Result { - let mut ret = BTreeMap::new(); - while let Some((key, value)) = a.next_entry()? { - ret.insert(key, FromHex::from_hex(value).map_err(serde::de::Error::custom)?); - } - Ok(ret) - } - } - - // Don't do anything special when not human readable. - if !d.is_human_readable() { - serde::Deserialize::deserialize(d) - } else { - d.deserialize_map(Visitor(PhantomData)) - } - } -} - -pub mod btreemap_as_seq { - //! Module for serialization of BTreeMaps as lists of sequences because - //! serde_json will not serialize hashmaps with non-string keys be default. - #![allow(missing_docs)] - - // NOTE: This module can be exactly copied to use with HashMap. - - use crate::prelude::BTreeMap; - - pub fn serialize(v: &BTreeMap, s: S) -> Result - where - S: serde::Serializer, - T: serde::Serialize + core::hash::Hash + Eq + Ord, - U: serde::Serialize, - { - use serde::ser::SerializeSeq; - - // Don't do anything special when not human readable. - if !s.is_human_readable() { - serde::Serialize::serialize(v, s) - } else { - let mut seq = s.serialize_seq(Some(v.len()))?; - for pair in v.iter() { - seq.serialize_element(&pair)?; - } - seq.end() - } - } - - pub fn deserialize<'de, D, T, U>(d: D) -> Result, D::Error> - where - D: serde::Deserializer<'de>, - T: serde::Deserialize<'de> + core::hash::Hash + Eq + Ord, - U: serde::Deserialize<'de>, - { - use core::marker::PhantomData; - - struct Visitor(PhantomData<(T, U)>); - impl<'de, T, U> serde::de::Visitor<'de> for Visitor - where - T: serde::Deserialize<'de> + core::hash::Hash + Eq + Ord, - U: serde::Deserialize<'de>, - { - type Value = BTreeMap; - - fn expecting(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - write!(f, "a sequence of pairs") - } - - fn visit_seq>( - self, - mut a: A, - ) -> Result { - let mut ret = BTreeMap::new(); - while let Some((key, value)) = a.next_element()? { - ret.insert(key, value); - } - Ok(ret) - } - } - - // Don't do anything special when not human readable. - if !d.is_human_readable() { - serde::Deserialize::deserialize(d) - } else { - d.deserialize_seq(Visitor(PhantomData)) - } - } -} - -pub mod btreemap_as_seq_byte_values { - //! Module for serialization of BTreeMaps as lists of sequences because - //! serde_json will not serialize hashmaps with non-string keys be default. - #![allow(missing_docs)] - - // NOTE: This module can be exactly copied to use with HashMap. - - use crate::prelude::{BTreeMap, Vec}; - - /// A custom key-value pair type that serialized the bytes as hex. - #[derive(Debug, Deserialize)] - struct OwnedPair( - T, - #[serde(deserialize_with = "crate::serde_utils::hex_bytes::deserialize")] Vec, - ); - - /// A custom key-value pair type that serialized the bytes as hex. - #[derive(Debug, Serialize)] - struct BorrowedPair<'a, T: 'static>( - &'a T, - #[serde(serialize_with = "crate::serde_utils::hex_bytes::serialize")] &'a [u8], - ); - - pub fn serialize(v: &BTreeMap>, s: S) -> Result - where - S: serde::Serializer, - T: serde::Serialize + core::hash::Hash + Eq + Ord + 'static, - { - use serde::ser::SerializeSeq; - - // Don't do anything special when not human readable. - if !s.is_human_readable() { - serde::Serialize::serialize(v, s) - } else { - let mut seq = s.serialize_seq(Some(v.len()))?; - for (key, value) in v.iter() { - seq.serialize_element(&BorrowedPair(key, value))?; - } - seq.end() - } - } - - pub fn deserialize<'de, D, T>(d: D) -> Result>, D::Error> - where - D: serde::Deserializer<'de>, - T: serde::Deserialize<'de> + core::hash::Hash + Eq + Ord, - { - use core::marker::PhantomData; - - struct Visitor(PhantomData); - impl<'de, T> serde::de::Visitor<'de> for Visitor - where - T: serde::Deserialize<'de> + core::hash::Hash + Eq + Ord, - { - type Value = BTreeMap>; - - fn expecting(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - write!(f, "a sequence of pairs") - } - - fn visit_seq>( - self, - mut a: A, - ) -> Result { - let mut ret = BTreeMap::new(); - while let Option::Some(OwnedPair(key, value)) = a.next_element()? { - ret.insert(key, value); - } - Ok(ret) - } - } - - // Don't do anything special when not human readable. - if !d.is_human_readable() { - serde::Deserialize::deserialize(d) - } else { - d.deserialize_seq(Visitor(PhantomData)) - } - } -} - -pub mod hex_bytes { - //! Module for serialization of byte arrays as hex strings. - #![allow(missing_docs)] - - use hex::FromHex; - - pub fn serialize(bytes: &T, s: S) -> Result - where - T: serde::Serialize + AsRef<[u8]>, - S: serde::Serializer, - { - // Don't do anything special when not human readable. - if !s.is_human_readable() { - serde::Serialize::serialize(bytes, s) - } else { - serde::Serialize::serialize(&super::SerializeBytesAsHex(bytes.as_ref()), s) - } - } - - pub fn deserialize<'de, D, B>(d: D) -> Result - where - D: serde::Deserializer<'de>, - B: serde::Deserialize<'de> + FromHex, - { - struct Visitor(core::marker::PhantomData); - - impl serde::de::Visitor<'_> for Visitor { - type Value = B; - - fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { - formatter.write_str("an ASCII hex string") - } - - fn visit_bytes(self, v: &[u8]) -> Result - where - E: serde::de::Error, - { - if let Ok(hex) = core::str::from_utf8(v) { - FromHex::from_hex(hex).map_err(E::custom) - } else { - Err(E::invalid_value(serde::de::Unexpected::Bytes(v), &self)) - } - } - - fn visit_str(self, v: &str) -> Result - where - E: serde::de::Error, - { - FromHex::from_hex(v).map_err(E::custom) - } - } - - // Don't do anything special when not human readable. - if !d.is_human_readable() { - serde::Deserialize::deserialize(d) - } else { - d.deserialize_str(Visitor(core::marker::PhantomData)) - } - } -} diff --git a/bitcoin/tests/data/serde/proprietary_key_bincode b/bitcoin/tests/data/serde/proprietary_key_bincode deleted file mode 100644 index 8c0100713be8a87a97c9e4926701c50a89dcac89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32 TcmZQ!fC5G)W=1HJ1xXA50dN2o diff --git a/bitcoin/tests/data/serde/psbt_base64.json b/bitcoin/tests/data/serde/psbt_base64.json new file mode 100644 index 000000000..6bb318f10 --- /dev/null +++ b/bitcoin/tests/data/serde/psbt_base64.json @@ -0,0 +1 @@ +"cHNidP8BAFMBAAAAAYmjxx6rTSDgNxu7pMxpj6KVyUY6+i45f4UzzLYvlWflAQAAAAD/////AXL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAAAAAE8BBIiyHgAAAAAAAAAAAIc9/4HAL1JWI/0f5RZ+rDpVoEnePTFLtC7iJ//tN9UIAzmjYBMwFZfa70H75ZOgLMUT0LVVJ+wt8QUOLo/0nIXCDN6tvu8AAACAAQAAABD8BXByZWZ4KnRlc3Rfa2V5AwUGBwMJAAEDAwQFAAEAjwEAAAAAAQGJo8ceq00g4Dcbu6TMaY+ilclGOvouOX+FM8y2L5Vn5QEAAAAXFgAUvhjRUqmwEgOdrz2n3k9TNJ7suYX/////AXL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUAAAAAAQEgcv74TiwAAAAXqRQzlyW6Ie/WKsdTqbzQZ9bHpqOdBYciAgM5iA3JI5S3NV49BDn6KDwx3nWQgS6gEcQkXAZ0poXog0cwRAIgT2fir7dhQtRPrliiSV0zo0GdqibNDbjQTzRStjKJrA8CIBB2Kp+2fpTMXK2QJvbcmf9/Bw9CeNMPvH0Mhp3TjH/nAQEDBIMAAAABBAFRIgYDOYgNySOUtzVePQQ5+ig8Md51kIEuoBHEJFwGdKaF6IMM3q2+7wAAAIABAAAAAQgGAgIBAwEFFQoYn3yLGjhv/o7tkbODDHp7zR53jAIBAiELoShx/uIQ+4YZKR6uoZRYHL0lMeSyN1nSJfaAaSP2MiICAQIVDBXMSeGRy8Ug2RlEYApct3r2qjKRAgECIQ12pWrO2RXSUT3NhMLDeLLoqlzWMrW3HKLyrFsOOmSb2wIBAhD8BXByZWZ4KnRlc3Rfa2V5AwUGBwMJAAEDAwQFACICAzmIDckjlLc1Xj0EOfooPDHedZCBLqARxCRcBnSmheiDDN6tvu8AAACAAQAAABD8BXByZWZ4KnRlc3Rfa2V5AwUGBwMJAAEDAwQFAA==" \ No newline at end of file diff --git a/bitcoin/tests/data/serde/psbt_bincode b/bitcoin/tests/data/serde/psbt_bincode index 2c352b99c33227c4258ba8380928e5fa0a2e694f..35d580f4b0ddd26395b7974739e0cd48ad82fbe4 100644 GIT binary patch delta 447 zcmaFJwTewtiJ1Wm3W}3T{xdQJGXi;x6D3sn{sRGH(Z3&lIzSQe$pK8_^&o}*j4U0S z8KE zSw*=d=GSyfS>*rgdpmJ+Gf!3ZS-J8aCPpSj?#WA;6TzdDCGnxI1rk-@O`lV-C-)ekjoBq`Fr!e&(<^O>I zs*M3AUi9yWpAJw^94fI=#CW>uF2(oPw2lX_+;buQ+VN$J=d!kgWMNwJp-L+XN|VgY z41Fto%N+}Yl9Js@BGQ9RizB@poeB%xEhBw$olOD_gHjR;EYpKsE&K{g$}5xHGg1R0 zjnboxEM0@$vI@QOol6aaN(-`5Eh0%tr&yIK8cG#D>n!+&s}f3{GNZX$-Fl^TS3tRGhPvD zEc2y@VI@ zQ?{GN*|J#v(y%eSS303lZ-L+ul^C{?Wvwro-Jlu_T$mL6(;uzhp6GPNe_g~P&sgKd zj&oP3o#owe!QUikn^ET)ekKKhGOhXB>ZY8DSvx`P+nt&J>)H98DlYTyspV;#d%36n zIXBd_U{7}s$6$|mM;{-?W}p~6_yggokeQInU}*$By)ZDsVj4y>GQ)x&9;_lzhe*t? z>6Ws{|JV0+;^t?vECb?&CHdN|}8dp%dybY!uA#G|e}NQiJ^Xf;*n3E(QSM&@@m0 diff --git a/bitcoin/tests/data/serde/raw_pair_bincode b/bitcoin/tests/data/serde/raw_pair_bincode deleted file mode 100644 index bf1d3218ac25dc751f2281d92e2067b95d236da0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32 TcmZQ%fB+UK&A`aSjLZfA0W1I( diff --git a/bitcoin/tests/serde.rs b/bitcoin/tests/serde.rs index f9e7e4a6a..136d72418 100644 --- a/bitcoin/tests/serde.rs +++ b/bitcoin/tests/serde.rs @@ -30,7 +30,7 @@ use bitcoin::consensus::encode::deserialize; use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d}; use bitcoin::hex::FromHex; use bitcoin::locktime::{absolute, relative}; -use bitcoin::psbt::raw::{self, Key, Pair, ProprietaryKey}; +use bitcoin::psbt::raw; use bitcoin::psbt::{Input, Output, Psbt, PsbtSighashType}; use bitcoin::script::ScriptBufExt as _; use bitcoin::sighash::{EcdsaSighashType, TapSighashType}; @@ -320,30 +320,11 @@ fn serde_regression_psbt() { let got = serialize(&psbt).unwrap(); let want = include_bytes!("data/serde/psbt_bincode") as &[_]; - assert_eq!(got, want) -} + assert_eq!(got, want); -#[test] -fn serde_regression_raw_pair() { - let pair = Pair { - key: Key { type_value: 1u64, key_data: vec![0u8, 1u8, 2u8, 3u8] }, - value: vec![0u8, 1u8, 2u8, 3u8], - }; - let got = serialize(&pair).unwrap(); - let want = include_bytes!("data/serde/raw_pair_bincode") as &[_]; - assert_eq!(got, want) -} - -#[test] -fn serde_regression_proprietary_key() { - let key = ProprietaryKey { - prefix: vec![0u8, 1u8, 2u8, 3u8], - subtype: 1u64, - key: vec![0u8, 1u8, 2u8, 3u8], - }; - let got = serialize(&key).unwrap(); - let want = include_bytes!("data/serde/proprietary_key_bincode") as &[_]; - assert_eq!(got, want) + let got = serde_json::to_string(&psbt).unwrap(); + let want = include_str!("data/serde/psbt_base64.json"); + assert_eq!(got, want); } #[test]