diff --git a/Cargo.toml b/Cargo.toml index de33bc15d..ebc58ee4c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,7 @@ alloy-rlp = { version = "0.3.0", default-features = false } alloy-rlp-derive = { version = "0.3.0", default-features = false } arbitrary = "1.3" arrayvec = { version = "0.7", default-features = false } +bincode = "1.3" bytes = { version = "1.4", default-features = false } criterion = "0.5" derive_arbitrary = "1.3" diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index cfda541ed..190df6198 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -45,6 +45,7 @@ proptest = { workspace = true, optional = true } proptest-derive = { workspace = true, optional = true } [dev-dependencies] +bincode.workspace = true serde_json.workspace = true serde = { workspace = true, features = ["derive"] } diff --git a/crates/primitives/src/bits/serde.rs b/crates/primitives/src/bits/serde.rs index 4094a7989..26af5c59e 100644 --- a/crates/primitives/src/bits/serde.rs +++ b/crates/primitives/src/bits/serde.rs @@ -63,13 +63,18 @@ impl<'de, const N: usize> Deserialize<'de> for FixedBytes { } } - deserializer.deserialize_any(FixedVisitor::) + if deserializer.is_human_readable() { + deserializer.deserialize_any(FixedVisitor::) + } else { + deserializer.deserialize_bytes(FixedVisitor::) + } } } #[cfg(test)] mod tests { use super::*; + use bincode as _; use serde::Deserialize; #[derive(Debug, Deserialize)] struct TestCase { @@ -82,6 +87,13 @@ mod tests { let ser = serde_json::to_string(&bytes).unwrap(); assert_eq!(ser, "\"0x000000000123456789abcdef\""); assert_eq!(serde_json::from_str::>(&ser).unwrap(), bytes); + + let val = serde_json::to_value(&bytes).unwrap(); + assert_eq!(val, serde_json::json! {"0x000000000123456789abcdef"}); + assert_eq!( + serde_json::from_value::>(val).unwrap(), + bytes + ); } #[test] @@ -101,4 +113,12 @@ mod tests { ) .contains("invalid length 5, expected exactly 4 bytes"),); } + + #[test] + fn test_bincode_roundtrip() { + let bytes = FixedBytes([0, 0, 0, 0, 1, 35, 69, 103, 137, 171, 205, 239]); + + let bin = bincode::serialize(&bytes).unwrap(); + assert_eq!(bincode::deserialize::>(&bin).unwrap(), bytes); + } } diff --git a/crates/primitives/src/bytes/serde.rs b/crates/primitives/src/bytes/serde.rs index 33c510e9d..0fbe8e14b 100644 --- a/crates/primitives/src/bytes/serde.rs +++ b/crates/primitives/src/bytes/serde.rs @@ -53,13 +53,18 @@ impl<'de> serde::Deserialize<'de> for Bytes { } } - deserializer.deserialize_any(BytesVisitor) + if deserializer.is_human_readable() { + deserializer.deserialize_any(BytesVisitor) + } else { + deserializer.deserialize_byte_buf(BytesVisitor) + } } } #[cfg(test)] mod tests { use super::*; + use bincode as _; use serde::Deserialize; #[derive(Debug, Deserialize)] struct TestCase { @@ -72,6 +77,10 @@ mod tests { let ser = serde_json::to_string(&bytes).unwrap(); assert_eq!(ser, "\"0x0123456789abcdef\""); assert_eq!(serde_json::from_str::(&ser).unwrap(), bytes); + + let val = serde_json::to_value(&bytes).unwrap(); + assert_eq!(val, serde_json::json! {"0x0123456789abcdef"}); + assert_eq!(serde_json::from_value::(val).unwrap(), bytes); } #[test] @@ -85,4 +94,12 @@ mod tests { Bytes::from(Vec::from([0, 1, 2, 3, 4])) ); } + + #[test] + fn test_bincode_roundtrip() { + let bytes = Bytes::from_static(&[1, 35, 69, 103, 137, 171, 205, 239]); + + let bin = bincode::serialize(&bytes).unwrap(); + assert_eq!(bincode::deserialize::(&bin).unwrap(), bytes); + } }