From 9f8b4f836ec8d7a039383eb80ba4a6369411f9cf Mon Sep 17 00:00:00 2001 From: teor Date: Wed, 26 May 2021 15:34:20 +1000 Subject: [PATCH] Test round-trip serialization for gossiped `MetaAddr`s --- zebra-network/src/meta_addr/tests/prop.rs | 66 +++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/zebra-network/src/meta_addr/tests/prop.rs b/zebra-network/src/meta_addr/tests/prop.rs index 8533d7285..f72d3b076 100644 --- a/zebra-network/src/meta_addr/tests/prop.rs +++ b/zebra-network/src/meta_addr/tests/prop.rs @@ -4,6 +4,8 @@ use super::{super::MetaAddr, check}; use proptest::prelude::*; +use zebra_chain::serialization::{ZcashDeserialize, ZcashSerialize}; + proptest! { /// Make sure that the sanitize function reduces time and state metadata /// leaks. @@ -13,4 +15,68 @@ proptest! { check::sanitize_avoids_leaks(&entry); } + + /// Test round-trip serialization for gossiped MetaAddrs + #[test] + fn gossiped_roundtrip( + mut gossiped_addr in MetaAddr::gossiped_strategy() + ) { + zebra_test::init(); + + // Zebra's deserialization sanitizes `services` to known flags + gossiped_addr.services &= PeerServices::all(); + + // Check that malicious peers can't make Zebra's serialization fail + let addr_bytes = gossiped_addr.zcash_serialize_to_vec(); + prop_assert!( + addr_bytes.is_ok(), + "unexpected serialization error: {:?}, addr: {:?}", + addr_bytes, + gossiped_addr + ); + let addr_bytes = addr_bytes.unwrap(); + + // Assume other implementations deserialize like Zebra + let deserialized_addr = MetaAddr::zcash_deserialize(addr_bytes.as_slice()); + prop_assert!( + deserialized_addr.is_ok(), + "unexpected deserialization error: {:?}, addr: {:?}, bytes: {:?}", + deserialized_addr, + gossiped_addr, + hex::encode(addr_bytes), + ); + let deserialized_addr = deserialized_addr.unwrap(); + + // Check that the addrs are equal + prop_assert_eq!( + gossiped_addr, + deserialized_addr, + "unexpected round-trip mismatch with bytes: {:?}", + hex::encode(addr_bytes), + ); + + // Now check that the re-serialized bytes are equal + // (`impl PartialEq for MetaAddr` might not match serialization equality) + let addr_bytes2 = deserialized_addr.zcash_serialize_to_vec(); + prop_assert!( + addr_bytes2.is_ok(), + "unexpected serialization error after round-trip: {:?}, original addr: {:?}, bytes: {:?}, deserialized addr: {:?}", + addr_bytes2, + gossiped_addr, + hex::encode(addr_bytes), + deserialized_addr, + ); + let addr_bytes2 = addr_bytes2.unwrap(); + + prop_assert_eq!( + &addr_bytes, + &addr_bytes2, + "unexpected round-trip bytes mismatch: original addr: {:?}, bytes: {:?}, deserialized addr: {:?}, bytes: {:?}", + gossiped_addr, + hex::encode(&addr_bytes), + deserialized_addr, + hex::encode(&addr_bytes2), + ); + + } }