From b3246bf73ff9635f5c73616f9a22d7a86a7ab7f0 Mon Sep 17 00:00:00 2001 From: sanket1729 Date: Sun, 1 Jan 2023 11:42:29 -0800 Subject: [PATCH 1/2] Fix LeafVersion serde The default implementation maps to visit_u64. The current implementation does not roundtrip with many deserializers, including serde_json. See failing test in the subsequent commit --- bitcoin/src/taproot.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bitcoin/src/taproot.rs b/bitcoin/src/taproot.rs index 62f9c348..5e38ae64 100644 --- a/bitcoin/src/taproot.rs +++ b/bitcoin/src/taproot.rs @@ -944,10 +944,16 @@ impl<'de> serde::Deserialize<'de> for LeafVersion { formatter.write_str("a valid consensus-encoded taproot leaf version") } - fn visit_u8(self, value: u8) -> Result + fn visit_u64(self, value: u64) -> Result where E: serde::de::Error, { + let value = u8::try_from(value).map_err(|_| { + E::invalid_value( + serde::de::Unexpected::Unsigned(value), + &"consensus-encoded leaf version as u8", + ) + })?; LeafVersion::from_consensus(value).map_err(|_| { E::invalid_value( ::serde::de::Unexpected::Unsigned(value as u64), From a4007576765cbe534d916b8c49fbdd454261cf87 Mon Sep 17 00:00:00 2001 From: sanket1729 Date: Sun, 1 Jan 2023 11:44:40 -0800 Subject: [PATCH 2/2] Add failing tests from serde-json --- bitcoin/src/taproot.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/bitcoin/src/taproot.rs b/bitcoin/src/taproot.rs index 5e38ae64..3e18f850 100644 --- a/bitcoin/src/taproot.rs +++ b/bitcoin/src/taproot.rs @@ -1104,6 +1104,9 @@ mod test { use crate::{Address, Network}; extern crate serde_json; + #[cfg(feature = "serde")] + use serde_test::{assert_tokens, Token}; + fn tag_engine(tag_name: &str) -> sha256::HashEngine { let mut engine = sha256::Hash::engine(); let tag_hash = sha256::Hash::hash(tag_name.as_bytes()); @@ -1357,6 +1360,18 @@ mod test { } } + #[test] + #[cfg(feature = "serde")] + fn test_leaf_version_serde() { + let leaf_version = LeafVersion::TapScript; + // use serde_test to test serialization and deserialization + assert_tokens(&leaf_version, &[Token::U8(192)]); + + let json = serde_json::to_string(&leaf_version).unwrap(); + let leaf_version2 = serde_json::from_str(&json).unwrap(); + assert_eq!(leaf_version, leaf_version2); + } + #[test] fn bip_341_tests() { fn process_script_trees(