From bc4696b9717a21fc567318d55c470ef7314d4636 Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Mon, 9 Sep 2024 12:10:47 +0100 Subject: [PATCH 01/18] Add CompactWidth relation decoding --- encoding/src/compact_width.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/encoding/src/compact_width.rs b/encoding/src/compact_width.rs index 8e7fc75..b9e440f 100644 --- a/encoding/src/compact_width.rs +++ b/encoding/src/compact_width.rs @@ -148,7 +148,23 @@ pub mod encoding { Ok(()) } + /// Decode the bytes representing a [`CompactWidth`]-bytes integer into a `usize` as encoding relation. + pub async fn decode_relation_compact_width_be>( + compact_width: CompactWidth, + producer: &mut Producer, + ) -> Result> { + let decoded = match compact_width { + CompactWidth::One => U8BE::decode(producer).await.map(u64::from), + CompactWidth::Two => U16BE::decode(producer).await.map(u64::from), + CompactWidth::Four => U32BE::decode(producer).await.map(u64::from), + CompactWidth::Eight => U64BE::decode(producer).await.map(u64::from), + }?; + + Ok(decoded) + } + /// Decode the bytes representing a [`CompactWidth`]-bytes integer into a `usize`. + /// Will fail if the decoded value could have been encoded with a smaller [`CompactWidth`]. pub async fn decode_compact_width_be>( compact_width: CompactWidth, producer: &mut Producer, From 80ce3b462d06e8f18da7a0b71e5f183f9cbd6cbe Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Mon, 9 Sep 2024 18:01:21 +0100 Subject: [PATCH 02/18] Syncify fuzz tests --- Cargo.lock | 1 + earthstar/Cargo.toml | 1 + earthstar/src/cinn25519.rs | 154 ++++++++++-------- earthstar/src/identity_id.rs | 51 +++--- earthstar/src/namespace_id.rs | 49 ++++-- fuzz/fuzz_targets/area_rel_area_encoding.rs | 13 +- .../area_rel_area_encoding_random.rs | 13 +- fuzz/fuzz_targets/entry_encoding.rs | 4 +- fuzz/fuzz_targets/entry_encoding_random.rs | 4 +- fuzz/fuzz_targets/entry_rel_entry_encoding.rs | 13 +- .../entry_rel_entry_encoding_random.rs | 13 +- .../entry_rel_namespace_area_encoding.rs | 13 +- ...ntry_rel_namespace_area_encoding_random.rs | 13 +- .../entry_rel_namespace_range_encoding.rs | 13 +- ...try_rel_namespace_range_encoding_random.rs | 13 +- .../mc_capability_rel_area_encoding.rs | 13 +- .../mc_capability_rel_area_encoding_random.rs | 11 +- .../mc_subspace_capability_encoding.rs | 11 +- .../mc_subspace_capability_encoding_random.rs | 9 +- fuzz/fuzz_targets/path_encoding.rs | 4 +- fuzz/fuzz_targets/path_encoding2.rs | 4 +- fuzz/fuzz_targets/path_encoding3.rs | 4 +- fuzz/fuzz_targets/path_encoding_random.rs | 4 +- fuzz/fuzz_targets/path_encoding_random2.rs | 4 +- fuzz/fuzz_targets/path_encoding_random3.rs | 4 +- fuzz/fuzz_targets/path_rel_path_encoding.rs | 13 +- fuzz/fuzz_targets/path_rel_path_encoding2.rs | 13 +- fuzz/fuzz_targets/path_rel_path_encoding3.rs | 13 +- .../path_rel_path_encoding_random.rs | 8 +- .../path_rel_path_encoding_random2.rs | 8 +- .../path_rel_path_encoding_random3.rs | 8 +- .../range3d_rel_rang3d_encoding_random.rs | 13 +- .../range3d_rel_range3d_encoding.rs | 13 +- fuzz/fuzz_targets/u16be_encoding.rs | 4 +- fuzz/fuzz_targets/u16be_encoding_random.rs | 4 +- fuzz/fuzz_targets/u32be_encoding.rs | 4 +- fuzz/fuzz_targets/u32be_encoding_random.rs | 4 +- fuzz/fuzz_targets/u64be_encoding.rs | 4 +- fuzz/fuzz_targets/u64be_encoding_random.rs | 4 +- fuzz/fuzz_targets/u8be_encoding.rs | 4 +- fuzz/fuzz_targets/u8be_encoding_random.rs | 4 +- fuzz/rust-toolchain.toml | 2 + fuzz/src/encode.rs | 55 +++---- 43 files changed, 275 insertions(+), 339 deletions(-) create mode 100644 fuzz/rust-toolchain.toml diff --git a/Cargo.lock b/Cargo.lock index da9b7c4..a13a7a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -218,6 +218,7 @@ version = "0.1.0" dependencies = [ "arbitrary", "either", + "syncify", "ufotofu", "willow-data-model", "willow-encoding", diff --git a/earthstar/Cargo.toml b/earthstar/Cargo.toml index ebfa9f4..eced8a1 100644 --- a/earthstar/Cargo.toml +++ b/earthstar/Cargo.toml @@ -9,6 +9,7 @@ willow-data-model = { path = "../data-model" } arbitrary = { version = "1.0.2", features = ["derive"]} ufotofu = { version = "0.4.2", features = ["std"] } willow-encoding = { path = "../encoding" } +syncify = "0.1.0" [lints] workspace = true diff --git a/earthstar/src/cinn25519.rs b/earthstar/src/cinn25519.rs index 7dd8a98..4a2fe42 100644 --- a/earthstar/src/cinn25519.rs +++ b/earthstar/src/cinn25519.rs @@ -3,8 +3,6 @@ use arbitrary::{ Arbitrary, Error as ArbitraryError, }; use either::Either; -use ufotofu::local_nb::{BulkConsumer, BulkProducer}; -use willow_encoding::{Decodable, DecodeError, Encodable}; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct Shortname(pub Vec); @@ -97,50 +95,96 @@ impl Cinn25519PublicKey Encodable - for Cinn25519PublicKey -{ - async fn encode(&self, consumer: &mut Consumer) -> Result<(), Consumer::Error> - where - Consumer: BulkConsumer, +use syncify::syncify; +use syncify::syncify_replace; + +#[syncify(encoding_sync)] +pub(super) mod encoding { + use super::*; + + #[syncify_replace(use ufotofu::sync::{BulkConsumer, BulkProducer};)] + use ufotofu::local_nb::{BulkConsumer, BulkProducer}; + use willow_encoding::DecodeError; + #[syncify_replace(use willow_encoding::sync::{Encodable, Decodable};)] + use willow_encoding::{Decodable, Encodable}; + + impl Encodable + for Cinn25519PublicKey { - let mut vec = Vec::new(); + async fn encode(&self, consumer: &mut Consumer) -> Result<(), Consumer::Error> + where + Consumer: BulkConsumer, + { + let mut vec = Vec::new(); - vec.extend_from_slice(&self.shortname.0); + vec.extend_from_slice(&self.shortname.0); - consumer - .bulk_consume_full_slice(&self.shortname.0) - .await - .map_err(|f| f.reason)?; + consumer + .bulk_consume_full_slice(&self.shortname.0) + .await + .map_err(|f| f.reason)?; - if MIN_LENGTH < MAX_LENGTH { - consumer.consume(0x0).await?; - } + if MIN_LENGTH < MAX_LENGTH { + consumer.consume(0x0).await?; + } - consumer - .bulk_consume_full_slice(&self.underlying) - .await - .map_err(|f| f.reason)?; + consumer + .bulk_consume_full_slice(&self.underlying) + .await + .map_err(|f| f.reason)?; - Ok(()) + Ok(()) + } } -} -impl Decodable - for Cinn25519PublicKey -{ - async fn decode( - producer: &mut Producer, - ) -> Result::Error>> - where - Producer: BulkProducer, + impl Decodable + for Cinn25519PublicKey { - if MIN_LENGTH == MAX_LENGTH { - let mut shortname_box = vec![0; MIN_LENGTH].into_boxed_slice(); + async fn decode( + producer: &mut Producer, + ) -> Result::Error>> + where + Producer: BulkProducer, + { + if MIN_LENGTH == MAX_LENGTH { + let mut shortname_box = vec![0; MIN_LENGTH].into_boxed_slice(); + + producer + .bulk_overwrite_full_slice(shortname_box.as_mut()) + .await?; + + let mut underlying_slice = [0u8; 32]; + + producer + .bulk_overwrite_full_slice(&mut underlying_slice) + .await?; + + return Ok(Self { + shortname: Shortname(shortname_box.into()), + underlying: underlying_slice, + }); + } - producer - .bulk_overwrite_full_slice(shortname_box.as_mut()) - .await?; + let mut shortname_vec: Vec = Vec::new(); + + loop { + match producer.produce().await { + Ok(Either::Left(item)) => { + // if item is 0x0, stop + if item == 0x0 { + break; + } + + shortname_vec.push(item); + } + Ok(Either::Right(_)) => { + // whatever happens, we won't be able to make a full public key. + // Error! + return Err(DecodeError::InvalidInput); + } + Err(err) => return Err(DecodeError::Producer(err)), + } + } let mut underlying_slice = [0u8; 32]; @@ -148,43 +192,11 @@ impl Decodable .bulk_overwrite_full_slice(&mut underlying_slice) .await?; - return Ok(Self { - shortname: Shortname(shortname_box.into()), + Ok(Self { + shortname: Shortname(shortname_vec), underlying: underlying_slice, - }); + }) } - - let mut shortname_vec: Vec = Vec::new(); - - loop { - match producer.produce().await { - Ok(Either::Left(item)) => { - // if item is 0x0, stop - if item == 0x0 { - break; - } - - shortname_vec.push(item); - } - Ok(Either::Right(_)) => { - // whatever happens, we won't be able to make a full public key. - // Error! - return Err(DecodeError::InvalidInput); - } - Err(err) => return Err(DecodeError::Producer(err)), - } - } - - let mut underlying_slice = [0u8; 32]; - - producer - .bulk_overwrite_full_slice(&mut underlying_slice) - .await?; - - Ok(Self { - shortname: Shortname(shortname_vec), - underlying: underlying_slice, - }) } } diff --git a/earthstar/src/identity_id.rs b/earthstar/src/identity_id.rs index eed7691..e6eedd0 100644 --- a/earthstar/src/identity_id.rs +++ b/earthstar/src/identity_id.rs @@ -1,9 +1,6 @@ +use crate::cinn25519::{Cinn25519PublicKey, Shortname}; use arbitrary::Arbitrary; -use ufotofu::local_nb::{BulkConsumer, BulkProducer}; use willow_data_model::SubspaceId; -use willow_encoding::{Decodable, DecodeError, Encodable}; - -use crate::cinn25519::{Cinn25519PublicKey, Shortname}; #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Arbitrary)] pub struct IdentityIdentifier(Cinn25519PublicKey<4, 4>); @@ -17,24 +14,38 @@ impl Default for IdentityIdentifier { } } -impl Encodable for IdentityIdentifier { - async fn encode(&self, consumer: &mut C) -> Result<(), C::Error> - where - C: BulkConsumer, - { - self.0.encode(consumer).await?; - Ok(()) +use syncify::syncify; +use syncify::syncify_replace; + +#[syncify(encoding_sync)] +pub(super) mod encoding { + use super::*; + + #[syncify_replace(use ufotofu::sync::{BulkConsumer, BulkProducer};)] + use ufotofu::local_nb::{BulkConsumer, BulkProducer}; + use willow_encoding::DecodeError; + #[syncify_replace(use willow_encoding::sync::{Encodable, Decodable};)] + use willow_encoding::{Decodable, Encodable}; + + impl Encodable for IdentityIdentifier { + async fn encode(&self, consumer: &mut C) -> Result<(), C::Error> + where + C: BulkConsumer, + { + self.0.encode(consumer).await?; + Ok(()) + } } -} -impl Decodable for IdentityIdentifier { - async fn decode

(producer: &mut P) -> Result> - where - P: BulkProducer, - { - match Cinn25519PublicKey::decode(producer).await { - Ok(pk) => Ok(Self(pk)), - Err(err) => Err(err), + impl Decodable for IdentityIdentifier { + async fn decode

(producer: &mut P) -> Result> + where + P: BulkProducer, + { + match Cinn25519PublicKey::decode(producer).await { + Ok(pk) => Ok(Self(pk)), + Err(err) => Err(err), + } } } } diff --git a/earthstar/src/namespace_id.rs b/earthstar/src/namespace_id.rs index 43737f5..0b2e84c 100644 --- a/earthstar/src/namespace_id.rs +++ b/earthstar/src/namespace_id.rs @@ -1,7 +1,6 @@ use arbitrary::Arbitrary; -use ufotofu::local_nb::{BulkConsumer, BulkProducer}; + use willow_data_model::NamespaceId; -use willow_encoding::{Decodable, DecodeError, Encodable}; use crate::cinn25519::{Cinn25519PublicKey, Shortname}; @@ -17,24 +16,38 @@ impl Default for NamespaceIdentifier { } } -impl Encodable for NamespaceIdentifier { - async fn encode(&self, consumer: &mut C) -> Result<(), C::Error> - where - C: BulkConsumer, - { - self.0.encode(consumer).await?; - Ok(()) +use syncify::syncify; +use syncify::syncify_replace; + +#[syncify(encoding_sync)] +pub(super) mod encoding { + use super::*; + + #[syncify_replace(use ufotofu::sync::{BulkConsumer, BulkProducer};)] + use ufotofu::local_nb::{BulkConsumer, BulkProducer}; + use willow_encoding::DecodeError; + #[syncify_replace(use willow_encoding::sync::{Encodable, Decodable};)] + use willow_encoding::{Decodable, Encodable}; + + impl Encodable for NamespaceIdentifier { + async fn encode(&self, consumer: &mut C) -> Result<(), C::Error> + where + C: BulkConsumer, + { + self.0.encode(consumer).await?; + Ok(()) + } } -} -impl Decodable for NamespaceIdentifier { - async fn decode

(producer: &mut P) -> Result::Error>> - where - P: BulkProducer, - { - match Cinn25519PublicKey::decode(producer).await { - Ok(pk) => Ok(Self(pk)), - Err(err) => Err(err), + impl Decodable for NamespaceIdentifier { + async fn decode

(producer: &mut P) -> Result::Error>> + where + P: BulkProducer, + { + match Cinn25519PublicKey::decode(producer).await { + Ok(pk) => Ok(Self(pk)), + Err(err) => Err(err), + } } } } diff --git a/fuzz/fuzz_targets/area_rel_area_encoding.rs b/fuzz/fuzz_targets/area_rel_area_encoding.rs index 8dd1b22..3c72156 100644 --- a/fuzz/fuzz_targets/area_rel_area_encoding.rs +++ b/fuzz/fuzz_targets/area_rel_area_encoding.rs @@ -17,12 +17,9 @@ fuzz_target!(|data: ( return; } - smol::block_on(async { - relative_encoding_roundtrip::< - Area<16, 16, 16, IdentityId>, - Area<16, 16, 16, IdentityId>, - TestConsumer, - >(a, out, &mut consumer) - .await; - }); + relative_encoding_roundtrip::< + Area<16, 16, 16, IdentityId>, + Area<16, 16, 16, IdentityId>, + TestConsumer, + >(a, out, &mut consumer) }); diff --git a/fuzz/fuzz_targets/area_rel_area_encoding_random.rs b/fuzz/fuzz_targets/area_rel_area_encoding_random.rs index b80a0a1..7095e1d 100644 --- a/fuzz/fuzz_targets/area_rel_area_encoding_random.rs +++ b/fuzz/fuzz_targets/area_rel_area_encoding_random.rs @@ -3,17 +3,14 @@ use earthstar::identity_id::IdentityIdentifier as IdentityId; use libfuzzer_sys::fuzz_target; use willow_data_model::grouping::Area; -use willow_fuzz::encode::relative_encoding_random_less_strict; +use willow_fuzz::encode::relative_encoding_relation_random; fuzz_target!(|data: (&[u8], Area<16, 16, 16, IdentityId>)| { // fuzzed code goes here let (random_bytes, area) = data; - smol::block_on(async { - relative_encoding_random_less_strict::< - Area<16, 16, 16, IdentityId>, - Area<16, 16, 16, IdentityId>, - >(area, random_bytes) - .await; - }); + relative_encoding_relation_random::, Area<16, 16, 16, IdentityId>>( + area, + random_bytes, + ) }); diff --git a/fuzz/fuzz_targets/entry_encoding.rs b/fuzz/fuzz_targets/entry_encoding.rs index e08bfda..024442b 100644 --- a/fuzz/fuzz_targets/entry_encoding.rs +++ b/fuzz/fuzz_targets/entry_encoding.rs @@ -14,7 +14,5 @@ fuzz_target!(|data: ( )| { let (entry, mut consumer) = data; - smol::block_on(async { - encoding_roundtrip::<_, TestConsumer>(entry, &mut consumer).await; - }); + encoding_roundtrip::<_, TestConsumer>(entry, &mut consumer); }); diff --git a/fuzz/fuzz_targets/entry_encoding_random.rs b/fuzz/fuzz_targets/entry_encoding_random.rs index 01fcd9b..82a85bc 100644 --- a/fuzz/fuzz_targets/entry_encoding_random.rs +++ b/fuzz/fuzz_targets/entry_encoding_random.rs @@ -9,7 +9,5 @@ use libfuzzer_sys::fuzz_target; use willow_fuzz::{encode::encoding_random, placeholder_params::FakePayloadDigest}; fuzz_target!(|data: &[u8]| { - smol::block_on(async { - encoding_random::>(data).await; - }); + encoding_random::>(data); }); diff --git a/fuzz/fuzz_targets/entry_rel_entry_encoding.rs b/fuzz/fuzz_targets/entry_rel_entry_encoding.rs index 1a084cd..d1fd8a4 100644 --- a/fuzz/fuzz_targets/entry_rel_entry_encoding.rs +++ b/fuzz/fuzz_targets/entry_rel_entry_encoding.rs @@ -15,12 +15,9 @@ fuzz_target!(|data: ( )| { let (entry_sub, entry_ref, mut consumer) = data; - smol::block_on(async { - relative_encoding_roundtrip::< - Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, - Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, - TestConsumer, - >(entry_sub, entry_ref, &mut consumer) - .await; - }); + relative_encoding_roundtrip::< + Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, + Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, + TestConsumer, + >(entry_sub, entry_ref, &mut consumer); }); diff --git a/fuzz/fuzz_targets/entry_rel_entry_encoding_random.rs b/fuzz/fuzz_targets/entry_rel_entry_encoding_random.rs index 9e2cc21..befe28d 100644 --- a/fuzz/fuzz_targets/entry_rel_entry_encoding_random.rs +++ b/fuzz/fuzz_targets/entry_rel_entry_encoding_random.rs @@ -4,7 +4,7 @@ use earthstar::identity_id::IdentityIdentifier as IdentityId; use earthstar::namespace_id::NamespaceIdentifier as EsNamespaceId; use libfuzzer_sys::fuzz_target; use willow_data_model::Entry; -use willow_fuzz::encode::relative_encoding_random_less_strict; +use willow_fuzz::encode::relative_encoding_relation_random; use willow_fuzz::placeholder_params::FakePayloadDigest; fuzz_target!(|data: ( @@ -13,11 +13,8 @@ fuzz_target!(|data: ( )| { let (random_bytes, ref_entry) = data; - smol::block_on(async { - relative_encoding_random_less_strict::< - Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, - Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, - >(ref_entry, random_bytes) - .await; - }); + relative_encoding_relation_random::< + Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, + Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, + >(ref_entry, random_bytes) }); diff --git a/fuzz/fuzz_targets/entry_rel_namespace_area_encoding.rs b/fuzz/fuzz_targets/entry_rel_namespace_area_encoding.rs index d2def9b..7f6b16e 100644 --- a/fuzz/fuzz_targets/entry_rel_namespace_area_encoding.rs +++ b/fuzz/fuzz_targets/entry_rel_namespace_area_encoding.rs @@ -22,12 +22,9 @@ fuzz_target!(|data: ( let namespace = entry.namespace_id().clone(); - smol::block_on(async { - relative_encoding_roundtrip::< - Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, - (EsNamespaceId, Area<16, 16, 16, IdentityId>), - TestConsumer, - >(entry, (namespace, area), &mut consumer) - .await; - }); + relative_encoding_roundtrip::< + Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, + (EsNamespaceId, Area<16, 16, 16, IdentityId>), + TestConsumer, + >(entry, (namespace, area), &mut consumer) }); diff --git a/fuzz/fuzz_targets/entry_rel_namespace_area_encoding_random.rs b/fuzz/fuzz_targets/entry_rel_namespace_area_encoding_random.rs index 7158f88..0cc0d82 100644 --- a/fuzz/fuzz_targets/entry_rel_namespace_area_encoding_random.rs +++ b/fuzz/fuzz_targets/entry_rel_namespace_area_encoding_random.rs @@ -5,7 +5,7 @@ use earthstar::namespace_id::NamespaceIdentifier as EsNamespaceId; use libfuzzer_sys::fuzz_target; use willow_data_model::grouping::Area; use willow_data_model::Entry; -use willow_fuzz::encode::relative_encoding_random_less_strict; +use willow_fuzz::encode::relative_encoding_relation_random; use willow_fuzz::placeholder_params::FakePayloadDigest; fuzz_target!( @@ -13,12 +13,9 @@ fuzz_target!( // fuzzed code goes here let (random_bytes, namespaced_area) = data; - smol::block_on(async { - relative_encoding_random_less_strict::< - (EsNamespaceId, Area<16, 16, 16, IdentityId>), - Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, - >(namespaced_area, random_bytes) - .await; - }); + relative_encoding_relation_random::< + (EsNamespaceId, Area<16, 16, 16, IdentityId>), + Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, + >(namespaced_area, random_bytes) } ); diff --git a/fuzz/fuzz_targets/entry_rel_namespace_range_encoding.rs b/fuzz/fuzz_targets/entry_rel_namespace_range_encoding.rs index b478c7f..6a13e3a 100644 --- a/fuzz/fuzz_targets/entry_rel_namespace_range_encoding.rs +++ b/fuzz/fuzz_targets/entry_rel_namespace_range_encoding.rs @@ -22,12 +22,9 @@ fuzz_target!(|data: ( let namespace = entry.namespace_id().clone(); - smol::block_on(async { - relative_encoding_roundtrip::< - Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, - (EsNamespaceId, Range3d<16, 16, 16, IdentityId>), - TestConsumer, - >(entry, (namespace, range_3d), &mut consumer) - .await; - }); + relative_encoding_roundtrip::< + Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, + (EsNamespaceId, Range3d<16, 16, 16, IdentityId>), + TestConsumer, + >(entry, (namespace, range_3d), &mut consumer) }); diff --git a/fuzz/fuzz_targets/entry_rel_namespace_range_encoding_random.rs b/fuzz/fuzz_targets/entry_rel_namespace_range_encoding_random.rs index 45e1626..018eb57 100644 --- a/fuzz/fuzz_targets/entry_rel_namespace_range_encoding_random.rs +++ b/fuzz/fuzz_targets/entry_rel_namespace_range_encoding_random.rs @@ -5,7 +5,7 @@ use earthstar::namespace_id::NamespaceIdentifier as EsNamespaceId; use libfuzzer_sys::fuzz_target; use willow_data_model::grouping::Range3d; use willow_data_model::Entry; -use willow_fuzz::encode::relative_encoding_random_less_strict; +use willow_fuzz::encode::relative_encoding_relation_random; use willow_fuzz::placeholder_params::FakePayloadDigest; fuzz_target!( @@ -13,12 +13,9 @@ fuzz_target!( // fuzzed code goes here let (random_bytes, namespaced_range_3d) = data; - smol::block_on(async { - relative_encoding_random_less_strict::< - (EsNamespaceId, Range3d<16, 16, 16, IdentityId>), - Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, - >(namespaced_range_3d, random_bytes) - .await; - }); + relative_encoding_relation_random::< + (EsNamespaceId, Range3d<16, 16, 16, IdentityId>), + Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, + >(namespaced_range_3d, random_bytes); } ); diff --git a/fuzz/fuzz_targets/mc_capability_rel_area_encoding.rs b/fuzz/fuzz_targets/mc_capability_rel_area_encoding.rs index 63fe3f2..ea40b85 100644 --- a/fuzz/fuzz_targets/mc_capability_rel_area_encoding.rs +++ b/fuzz/fuzz_targets/mc_capability_rel_area_encoding.rs @@ -38,12 +38,9 @@ fuzz_target!(|data: ( return; } - smol::block_on(async { - relative_encoding_roundtrip::< - McCapability<3, 3, 3, SillyPublicKey, SillySig, SillyPublicKey, SillySig>, - Area<3, 3, 3, SillyPublicKey>, - TestConsumer, - >(cap_with_delegees, out, &mut consumer) - .await; - }); + relative_encoding_roundtrip::< + McCapability<3, 3, 3, SillyPublicKey, SillySig, SillyPublicKey, SillySig>, + Area<3, 3, 3, SillyPublicKey>, + TestConsumer, + >(cap_with_delegees, out, &mut consumer) }); diff --git a/fuzz/fuzz_targets/mc_capability_rel_area_encoding_random.rs b/fuzz/fuzz_targets/mc_capability_rel_area_encoding_random.rs index 6c4de9c..237922f 100644 --- a/fuzz/fuzz_targets/mc_capability_rel_area_encoding_random.rs +++ b/fuzz/fuzz_targets/mc_capability_rel_area_encoding_random.rs @@ -9,11 +9,8 @@ use willow_fuzz::silly_sigs::{SillyPublicKey, SillySig}; fuzz_target!(|data: (&[u8], Area<3, 3, 3, SillyPublicKey>,)| { let (random_bytes, out) = data; - smol::block_on(async { - relative_encoding_random::< - Area<3, 3, 3, SillyPublicKey>, - McCapability<3, 3, 3, SillyPublicKey, SillySig, SillyPublicKey, SillySig>, - >(out, random_bytes) - .await; - }); + relative_encoding_random::< + Area<3, 3, 3, SillyPublicKey>, + McCapability<3, 3, 3, SillyPublicKey, SillySig, SillyPublicKey, SillySig>, + >(out, random_bytes) }); diff --git a/fuzz/fuzz_targets/mc_subspace_capability_encoding.rs b/fuzz/fuzz_targets/mc_subspace_capability_encoding.rs index 4db3f7d..542d92f 100644 --- a/fuzz/fuzz_targets/mc_subspace_capability_encoding.rs +++ b/fuzz/fuzz_targets/mc_subspace_capability_encoding.rs @@ -23,11 +23,8 @@ fuzz_target!(|data: ( last_receiver = delegee; } - smol::block_on(async { - encoding_roundtrip::< - McSubspaceCapability, - TestConsumer, - >(cap_with_delegees, &mut consumer) - .await; - }); + encoding_roundtrip::< + McSubspaceCapability, + TestConsumer, + >(cap_with_delegees, &mut consumer) }); diff --git a/fuzz/fuzz_targets/mc_subspace_capability_encoding_random.rs b/fuzz/fuzz_targets/mc_subspace_capability_encoding_random.rs index e4d2fc9..42fe05a 100644 --- a/fuzz/fuzz_targets/mc_subspace_capability_encoding_random.rs +++ b/fuzz/fuzz_targets/mc_subspace_capability_encoding_random.rs @@ -6,10 +6,7 @@ use willow_fuzz::encode::encoding_random; use willow_fuzz::silly_sigs::{SillyPublicKey, SillySig}; fuzz_target!(|data: &[u8]| { - smol::block_on(async { - encoding_random::< - McSubspaceCapability, - >(data) - .await; - }); + encoding_random::>( + data, + ) }); diff --git a/fuzz/fuzz_targets/path_encoding.rs b/fuzz/fuzz_targets/path_encoding.rs index 5a5a00c..959cced 100644 --- a/fuzz/fuzz_targets/path_encoding.rs +++ b/fuzz/fuzz_targets/path_encoding.rs @@ -12,7 +12,5 @@ const MPL: usize = 300; fuzz_target!(|data: (Path, TestConsumer)| { let (path, mut consumer) = data; - smol::block_on(async { - encoding_roundtrip::<_, TestConsumer>(path, &mut consumer).await; - }); + encoding_roundtrip::<_, TestConsumer>(path, &mut consumer); }); diff --git a/fuzz/fuzz_targets/path_encoding2.rs b/fuzz/fuzz_targets/path_encoding2.rs index f81014b..4583a2b 100644 --- a/fuzz/fuzz_targets/path_encoding2.rs +++ b/fuzz/fuzz_targets/path_encoding2.rs @@ -12,7 +12,5 @@ const MPL: usize = 3; fuzz_target!(|data: (Path, TestConsumer)| { let (path, mut consumer) = data; - smol::block_on(async { - encoding_roundtrip::<_, TestConsumer>(path, &mut consumer).await; - }); + encoding_roundtrip::<_, TestConsumer>(path, &mut consumer); }); diff --git a/fuzz/fuzz_targets/path_encoding3.rs b/fuzz/fuzz_targets/path_encoding3.rs index 41dfa9f..1787ff7 100644 --- a/fuzz/fuzz_targets/path_encoding3.rs +++ b/fuzz/fuzz_targets/path_encoding3.rs @@ -12,7 +12,5 @@ const MPL: usize = 16; fuzz_target!(|data: (Path, TestConsumer)| { let (path, mut consumer) = data; - smol::block_on(async { - encoding_roundtrip::<_, TestConsumer>(path, &mut consumer).await; - }); + encoding_roundtrip::<_, TestConsumer>(path, &mut consumer); }); diff --git a/fuzz/fuzz_targets/path_encoding_random.rs b/fuzz/fuzz_targets/path_encoding_random.rs index 57359e7..3b3b704 100644 --- a/fuzz/fuzz_targets/path_encoding_random.rs +++ b/fuzz/fuzz_targets/path_encoding_random.rs @@ -9,7 +9,5 @@ const MCC: usize = 300; const MPL: usize = 300; fuzz_target!(|data: &[u8]| { - smol::block_on(async { - encoding_random::>(data).await; - }); + encoding_random::>(data); }); diff --git a/fuzz/fuzz_targets/path_encoding_random2.rs b/fuzz/fuzz_targets/path_encoding_random2.rs index 19e6700..a08464a 100644 --- a/fuzz/fuzz_targets/path_encoding_random2.rs +++ b/fuzz/fuzz_targets/path_encoding_random2.rs @@ -9,7 +9,5 @@ const MCC: usize = 3; const MPL: usize = 3; fuzz_target!(|data: &[u8]| { - smol::block_on(async { - encoding_random::>(data).await; - }); + encoding_random::>(data); }); diff --git a/fuzz/fuzz_targets/path_encoding_random3.rs b/fuzz/fuzz_targets/path_encoding_random3.rs index 0f441f9..bd879ff 100644 --- a/fuzz/fuzz_targets/path_encoding_random3.rs +++ b/fuzz/fuzz_targets/path_encoding_random3.rs @@ -9,7 +9,5 @@ const MCC: usize = 4; const MPL: usize = 16; fuzz_target!(|data: &[u8]| { - smol::block_on(async { - encoding_random::>(data).await; - }); + encoding_random::>(data); }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding.rs b/fuzz/fuzz_targets/path_rel_path_encoding.rs index a371b0f..1c14c10 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding.rs @@ -17,12 +17,9 @@ fuzz_target!(|data: ( )| { let (path_sub, path_ref, mut consumer) = data; - smol::block_on(async { - relative_encoding_roundtrip::< - Path, - Path, - TestConsumer, - >(path_sub, path_ref, &mut consumer) - .await; - }); + relative_encoding_roundtrip::, Path, TestConsumer>( + path_sub, + path_ref, + &mut consumer, + ) }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding2.rs b/fuzz/fuzz_targets/path_rel_path_encoding2.rs index d6cdae0..030e361 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding2.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding2.rs @@ -17,12 +17,9 @@ fuzz_target!(|data: ( )| { let (path_sub, path_ref, mut consumer) = data; - smol::block_on(async { - relative_encoding_roundtrip::< - Path, - Path, - TestConsumer, - >(path_sub, path_ref, &mut consumer) - .await; - }); + relative_encoding_roundtrip::, Path, TestConsumer>( + path_sub, + path_ref, + &mut consumer, + ) }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding3.rs b/fuzz/fuzz_targets/path_rel_path_encoding3.rs index 0a31ce5..e7cbd4b 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding3.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding3.rs @@ -17,12 +17,9 @@ fuzz_target!(|data: ( )| { let (path_sub, path_ref, mut consumer) = data; - smol::block_on(async { - relative_encoding_roundtrip::< - Path, - Path, - TestConsumer, - >(path_sub, path_ref, &mut consumer) - .await; - }); + relative_encoding_roundtrip::, Path, TestConsumer>( + path_sub, + path_ref, + &mut consumer, + ) }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding_random.rs b/fuzz/fuzz_targets/path_rel_path_encoding_random.rs index dacb0c1..23a216f 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding_random.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding_random.rs @@ -11,11 +11,5 @@ const MPL: usize = 300; fuzz_target!(|data: (&[u8], Path)| { let (random_bytes, ref_path) = data; - smol::block_on(async { - relative_encoding_random::, Path>( - ref_path, - random_bytes, - ) - .await; - }); + relative_encoding_random::, Path>(ref_path, random_bytes) }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding_random2.rs b/fuzz/fuzz_targets/path_rel_path_encoding_random2.rs index 92cc517..5d674bb 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding_random2.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding_random2.rs @@ -11,11 +11,5 @@ const MPL: usize = 3; fuzz_target!(|data: (&[u8], Path)| { let (random_bytes, ref_path) = data; - smol::block_on(async { - relative_encoding_random::, Path>( - ref_path, - random_bytes, - ) - .await; - }); + relative_encoding_random::, Path>(ref_path, random_bytes) }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding_random3.rs b/fuzz/fuzz_targets/path_rel_path_encoding_random3.rs index 746bb4c..0f2a66d 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding_random3.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding_random3.rs @@ -11,11 +11,5 @@ const MPL: usize = 16; fuzz_target!(|data: (&[u8], Path)| { let (random_bytes, ref_path) = data; - smol::block_on(async { - relative_encoding_random::, Path>( - ref_path, - random_bytes, - ) - .await; - }); + relative_encoding_random::, Path>(ref_path, random_bytes) }); diff --git a/fuzz/fuzz_targets/range3d_rel_rang3d_encoding_random.rs b/fuzz/fuzz_targets/range3d_rel_rang3d_encoding_random.rs index f2f47e2..49f9777 100644 --- a/fuzz/fuzz_targets/range3d_rel_rang3d_encoding_random.rs +++ b/fuzz/fuzz_targets/range3d_rel_rang3d_encoding_random.rs @@ -3,17 +3,14 @@ use earthstar::identity_id::IdentityIdentifier as IdentityId; use libfuzzer_sys::fuzz_target; use willow_data_model::grouping::Range3d; -use willow_fuzz::encode::relative_encoding_random_less_strict; +use willow_fuzz::encode::relative_encoding_relation_random; fuzz_target!(|data: (&[u8], Range3d<16, 16, 16, IdentityId>)| { // fuzzed code goes here let (random_bytes, area) = data; - smol::block_on(async { - relative_encoding_random_less_strict::< - Range3d<16, 16, 16, IdentityId>, - Range3d<16, 16, 16, IdentityId>, - >(area, random_bytes) - .await; - }); + relative_encoding_relation_random::< + Range3d<16, 16, 16, IdentityId>, + Range3d<16, 16, 16, IdentityId>, + >(area, random_bytes); }); diff --git a/fuzz/fuzz_targets/range3d_rel_range3d_encoding.rs b/fuzz/fuzz_targets/range3d_rel_range3d_encoding.rs index ecc3a75..073ada4 100644 --- a/fuzz/fuzz_targets/range3d_rel_range3d_encoding.rs +++ b/fuzz/fuzz_targets/range3d_rel_range3d_encoding.rs @@ -13,12 +13,9 @@ fuzz_target!(|data: ( )| { let (ran, reference, mut consumer) = data; - smol::block_on(async { - relative_encoding_roundtrip::< - Range3d<16, 16, 16, IdentityId>, - Range3d<16, 16, 16, IdentityId>, - TestConsumer, - >(ran, reference, &mut consumer) - .await; - }); + relative_encoding_roundtrip::< + Range3d<16, 16, 16, IdentityId>, + Range3d<16, 16, 16, IdentityId>, + TestConsumer, + >(ran, reference, &mut consumer); }); diff --git a/fuzz/fuzz_targets/u16be_encoding.rs b/fuzz/fuzz_targets/u16be_encoding.rs index 1c67022..fd4353a 100644 --- a/fuzz/fuzz_targets/u16be_encoding.rs +++ b/fuzz/fuzz_targets/u16be_encoding.rs @@ -8,7 +8,5 @@ use willow_fuzz::encode::encoding_roundtrip; fuzz_target!(|data: (u16, TestConsumer)| { let (n, mut consumer) = data; - smol::block_on(async { - encoding_roundtrip::<_, TestConsumer>(U16BE::from(n), &mut consumer).await; - }); + encoding_roundtrip::<_, TestConsumer>(U16BE::from(n), &mut consumer); }); diff --git a/fuzz/fuzz_targets/u16be_encoding_random.rs b/fuzz/fuzz_targets/u16be_encoding_random.rs index ef227dd..0895fc3 100644 --- a/fuzz/fuzz_targets/u16be_encoding_random.rs +++ b/fuzz/fuzz_targets/u16be_encoding_random.rs @@ -5,7 +5,5 @@ use willow_encoding::U16BE; use willow_fuzz::encode::encoding_random; fuzz_target!(|data: &[u8]| { - smol::block_on(async { - encoding_random::(data).await; - }); + encoding_random::(data); }); diff --git a/fuzz/fuzz_targets/u32be_encoding.rs b/fuzz/fuzz_targets/u32be_encoding.rs index 21962f0..38b23bf 100644 --- a/fuzz/fuzz_targets/u32be_encoding.rs +++ b/fuzz/fuzz_targets/u32be_encoding.rs @@ -8,7 +8,5 @@ use willow_fuzz::encode::encoding_roundtrip; fuzz_target!(|data: (u32, TestConsumer)| { let (n, mut consumer) = data; - smol::block_on(async { - encoding_roundtrip::<_, TestConsumer>(U32BE::from(n), &mut consumer).await; - }); + encoding_roundtrip::<_, TestConsumer>(U32BE::from(n), &mut consumer); }); diff --git a/fuzz/fuzz_targets/u32be_encoding_random.rs b/fuzz/fuzz_targets/u32be_encoding_random.rs index 5dbcc54..7b07bcd 100644 --- a/fuzz/fuzz_targets/u32be_encoding_random.rs +++ b/fuzz/fuzz_targets/u32be_encoding_random.rs @@ -5,7 +5,5 @@ use willow_encoding::U32BE; use willow_fuzz::encode::encoding_random; fuzz_target!(|data: &[u8]| { - smol::block_on(async { - encoding_random::(data).await; - }); + encoding_random::(data); }); diff --git a/fuzz/fuzz_targets/u64be_encoding.rs b/fuzz/fuzz_targets/u64be_encoding.rs index 34eb06e..56435da 100644 --- a/fuzz/fuzz_targets/u64be_encoding.rs +++ b/fuzz/fuzz_targets/u64be_encoding.rs @@ -8,7 +8,5 @@ use willow_fuzz::encode::encoding_roundtrip; fuzz_target!(|data: (u64, TestConsumer)| { let (n, mut consumer) = data; - smol::block_on(async { - encoding_roundtrip::<_, TestConsumer>(U64BE::from(n), &mut consumer).await; - }); + encoding_roundtrip::<_, TestConsumer>(U64BE::from(n), &mut consumer); }); diff --git a/fuzz/fuzz_targets/u64be_encoding_random.rs b/fuzz/fuzz_targets/u64be_encoding_random.rs index fd447f6..a2532f2 100644 --- a/fuzz/fuzz_targets/u64be_encoding_random.rs +++ b/fuzz/fuzz_targets/u64be_encoding_random.rs @@ -5,7 +5,5 @@ use willow_encoding::U64BE; use willow_fuzz::encode::encoding_random; fuzz_target!(|data: &[u8]| { - smol::block_on(async { - encoding_random::(data).await; - }); + encoding_random::(data); }); diff --git a/fuzz/fuzz_targets/u8be_encoding.rs b/fuzz/fuzz_targets/u8be_encoding.rs index 64241f1..766102d 100644 --- a/fuzz/fuzz_targets/u8be_encoding.rs +++ b/fuzz/fuzz_targets/u8be_encoding.rs @@ -8,7 +8,5 @@ use willow_fuzz::encode::encoding_roundtrip; fuzz_target!(|data: (u8, TestConsumer)| { let (n, mut consumer) = data; - smol::block_on(async { - encoding_roundtrip::<_, TestConsumer>(U8BE::from(n), &mut consumer).await; - }); + encoding_roundtrip::<_, TestConsumer>(U8BE::from(n), &mut consumer); }); diff --git a/fuzz/fuzz_targets/u8be_encoding_random.rs b/fuzz/fuzz_targets/u8be_encoding_random.rs index 27c6848..a8bce9e 100644 --- a/fuzz/fuzz_targets/u8be_encoding_random.rs +++ b/fuzz/fuzz_targets/u8be_encoding_random.rs @@ -5,7 +5,5 @@ use willow_encoding::U8BE; use willow_fuzz::encode::encoding_random; fuzz_target!(|data: &[u8]| { - smol::block_on(async { - encoding_random::(data).await; - }); + encoding_random::(data); }); diff --git a/fuzz/rust-toolchain.toml b/fuzz/rust-toolchain.toml new file mode 100644 index 0000000..5d56faf --- /dev/null +++ b/fuzz/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" diff --git a/fuzz/src/encode.rs b/fuzz/src/encode.rs index 7c65a3a..1704608 100644 --- a/fuzz/src/encode.rs +++ b/fuzz/src/encode.rs @@ -1,26 +1,27 @@ use ufotofu::{ common::consumer::TestConsumer, - local_nb::{ + sync::consumer::IntoVec, + sync::{ producer::{FromBoxedSlice, FromSlice}, BufferedConsumer, BulkConsumer, }, - sync::consumer::IntoVec, }; use willow_encoding::{ - DecodeError, {Decodable, Encodable, RelativeDecodable, RelativeEncodable}, + sync::{Decodable, Encodable, RelativeDecodable, RelativeEncodable}, + DecodeError, }; -pub async fn encoding_roundtrip(item: T, consumer: &mut TestConsumer) +pub fn encoding_roundtrip(item: T, consumer: &mut TestConsumer) where T: Encodable + Decodable + std::fmt::Debug + PartialEq + Eq, C: BulkConsumer, { - if let Err(_err) = item.encode(consumer).await { + if let Err(_err) = item.encode(consumer) { return; } - if let Err(_err) = consumer.flush().await { + if let Err(_err) = consumer.flush() { return; } @@ -32,18 +33,18 @@ where let mut producer = FromBoxedSlice::from_vec(new_vec); // Check for correct errors - let decoded_item = T::decode(&mut producer).await.unwrap(); + let decoded_item = T::decode(&mut producer).unwrap(); assert_eq!(decoded_item, item); } -pub async fn encoding_random(data: &[u8]) +pub fn encoding_random(data: &[u8]) where T: Encodable + Decodable + std::fmt::Debug, { let mut producer = FromSlice::new(data); - match T::decode(&mut producer).await { + match T::decode(&mut producer) { Ok(item) => { // println!("item {:?}", item); @@ -51,7 +52,7 @@ where // Can we turn it back into the same encoding? let mut consumer = IntoVec::::new(); - item.encode(&mut consumer).await.unwrap(); + item.encode(&mut consumer).unwrap(); let encoded = consumer.as_ref(); @@ -70,13 +71,13 @@ where }; } -pub async fn encoding_random_less_strict(data: &[u8]) +pub fn encoding_relation_random(data: &[u8]) where T: Encodable + Decodable + std::fmt::Debug + PartialEq + Eq, { let mut producer = FromSlice::new(data); - match T::decode(&mut producer).await { + match T::decode(&mut producer) { Ok(item) => { // println!("item {:?}", item); @@ -84,11 +85,11 @@ where // Can we turn it back into the same encoding? let mut consumer = IntoVec::::new(); - item.encode(&mut consumer).await.unwrap(); + item.encode(&mut consumer).unwrap(); let mut producer_2 = FromSlice::new(consumer.as_ref()); - match T::decode(&mut producer_2).await { + match T::decode(&mut producer_2) { Ok(decoded_again) => { assert_eq!(item, decoded_again); } @@ -111,7 +112,7 @@ where }; } -pub async fn relative_encoding_roundtrip( +pub fn relative_encoding_roundtrip( subject: T, reference: R, consumer: &mut TestConsumer, @@ -123,11 +124,11 @@ pub async fn relative_encoding_roundtrip( //println!("item {:?}", subject); //println!("ref {:?}", reference); - if let Err(_err) = subject.relative_encode(&reference, consumer).await { + if let Err(_err) = subject.relative_encode(&reference, consumer) { return; } - if let Err(_err) = consumer.flush().await { + if let Err(_err) = consumer.flush() { return; } @@ -139,19 +140,19 @@ pub async fn relative_encoding_roundtrip( let mut producer = FromBoxedSlice::from_vec(new_vec); // Check for correct errors - let decoded_item = T::relative_decode(&reference, &mut producer).await.unwrap(); + let decoded_item = T::relative_decode(&reference, &mut producer).unwrap(); assert_eq!(decoded_item, subject); } -pub async fn relative_encoding_random(reference: R, data: &[u8]) +pub fn relative_encoding_random(reference: R, data: &[u8]) where T: RelativeEncodable + RelativeDecodable + std::fmt::Debug, R: std::fmt::Debug, { let mut producer = FromSlice::new(data); - match T::relative_decode(&reference, &mut producer).await { + match T::relative_decode(&reference, &mut producer) { Ok(item) => { // It decoded to a valid item! Gasp! // Can we turn it back into the same encoding? @@ -160,9 +161,7 @@ where // println!("item {:?}", item); // println!("ref {:?}", reference); - item.relative_encode(&reference, &mut consumer) - .await - .unwrap(); + item.relative_encode(&reference, &mut consumer).unwrap(); let encoded = consumer.as_ref(); @@ -181,14 +180,14 @@ where }; } -pub async fn relative_encoding_random_less_strict(reference: R, data: &[u8]) +pub fn relative_encoding_relation_random(reference: R, data: &[u8]) where T: RelativeEncodable + RelativeDecodable + std::fmt::Debug + Eq, R: std::fmt::Debug, { let mut producer = FromSlice::new(data); - match T::relative_decode(&reference, &mut producer).await { + match T::relative_decode(&reference, &mut producer) { Ok(item) => { // It decoded to a valid item! Gasp! // Can we turn it back into the same encoding? @@ -197,13 +196,11 @@ where // println!("item {:?}", item); // println!("ref {:?}", reference); - item.relative_encode(&reference, &mut consumer) - .await - .unwrap(); + item.relative_encode(&reference, &mut consumer).unwrap(); let mut producer_2 = FromSlice::new(consumer.as_ref()); - match T::relative_decode(&reference, &mut producer_2).await { + match T::relative_decode(&reference, &mut producer_2) { Ok(decoded_again) => { assert_eq!(item, decoded_again); } From 1bbe2bdffcd20aaa392d602e999259912d3933cb Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Wed, 11 Sep 2024 13:01:39 +0100 Subject: [PATCH 03/18] non-building API sketch --- encoding/src/traits.rs | 68 +++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/encoding/src/traits.rs b/encoding/src/traits.rs index 0919713..1134a66 100644 --- a/encoding/src/traits.rs +++ b/encoding/src/traits.rs @@ -3,12 +3,16 @@ use std::future::Future; use crate::error::DecodeError; use ufotofu::local_nb::{BulkConsumer, BulkProducer}; -/// A type that can be encoded to a bytestring, ensuring that any value of `Self` maps to exactly one bytestring. +/// A type which can be asynchronously encoded to bytes consumed by a [`ufotofu::local_nb::BulkConsumer`] /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) pub trait Encodable { - /// Encode a value to a bytestring in a specific way that is best described over at [willowprotocol.org](https://willowprotocol.org/specs/encodings/index.html#encodings_what). + /// Encode the value with an [encoding function](https://macromania--channelclosing.deno.dev/specs/encodings/index.html#encoding_function) for the set of `Self`, ensuring that any value of `Self` maps to exactly one bytestring, such that there exists a _decoding_ function such that: /// + /// - for every value `s` in `Self` and every bytestring `b` that starts with `encode_s(s)`, we have `decode_s(b)=s`, and + /// - for every `s` in `Self` and every bytestring b that does not start with `encode_s(s)`, we have `decode_s(b) ≠ s`. + /// + /// The encoded bytestring will be consumed to the provided [`ufotofu::local_nb::BulkConsumer`]. /// [Definition](https://willowprotocol.org/specs/encodings/index.html#encode_s) fn encode( &self, @@ -18,11 +22,16 @@ pub trait Encodable { Consumer: BulkConsumer; } -/// A type that can be decoded from a bytestring, ensuring that every valid encoding maps to exactly one member of `Self`. +/// A type which can be asynchronously decoded from bytes produced by a [`ufotofu::local_nb::BulkProducer`] /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) pub trait Decodable { - /// Decade a value to a bytestring in a specific way that is best described over at [willowprotocol.org](https://willowprotocol.org/specs/encodings/index.html#encodings_what). + /// Decode a bytestring created with an [encoding function](https://macromania--channelclosing.deno.dev/specs/encodings/index.html#encoding_function) for the set of `Self`, ensuring that any value of `Self` maps to exactly one bytestring, such that there exists a _decoding_ function (provided by this trait!) such that: + /// + /// - for every value `s` in `Self` and every bytestring `b` that starts with `encode_s(s)`, we have `decode_s(b)=s`, and + /// - for every `s` in `Self` and every bytestring `b` that does not start with `encode_s(s)`, we have `decode_s(b) ≠ s`. + /// + /// Will return an error if the encoding correlates to the **encoding relation** and not the result of the aforementioned encoding function. /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#decode_s) fn decode( @@ -31,12 +40,31 @@ pub trait Decodable { where Producer: BulkProducer, Self: Sized; + + /// Decode a bytestring belonging to the **encoding relation** on the set of `Self` and the set of bytestrings, such that: + /// + /// - for every `s` in `Self`, there is at least one bytestring in relation with `s`, and + /// - no bytestring in the relation is a prefix of another bytestring in the relation. + /// + /// [Definition](https://willowprotocol.org/specs/encodings/index.html#decode_s) + fn decode_relation( + producer: &mut Producer, + ) -> impl Future>> + where + Producer: BulkProducer, + Self: Sized; } -/// A type that can be used to encode `T` to a bytestring *encoded relative to `R`*. -/// This can be used to create more compact encodings from which `T` can be derived by anyone with `R`. +/// A type relative to a reference value of type `R` which can be asynchronously encoded to bytes consumed by a [`ufotofu::local_nb::BulkConsumer`] +/// +/// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) +/// +/// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) pub trait RelativeEncodable { - /// Encode a value (relative to a reference value) to a bytestring in a specific way that is best described over at [willowprotocol.org](https://willowprotocol.org/specs/encodings/index.html#encodings_what). + /// Encode a pair of `Self` and `R` with the [encoding function](https://macromania--channelclosing.deno.dev/specs/encodings/index.html#encoding_function) for the set of `Self` relative to a value of the set of `R`, ensuring that any pair of `Self` and `R` maps to exactly one bytestring, such that there exists a _decoding_ function such that: + /// + /// - for every pair of `s` in `Self` and `r` in `R`, and every bytestring `b` that starts with `encode_s(s, r)`, we have `decode_s(b, r)=s`, and + /// - for every pair of `s` in `Self` and `r` in `R`, and every bytestring `b` that does not start with `encode_s(s, r)`, we have `decode_s(b, r) ≠ s`. fn relative_encode( &self, reference: &R, @@ -46,10 +74,19 @@ pub trait RelativeEncodable { Consumer: BulkConsumer; } -/// A type that can be used to decode `T` from a bytestring *encoded relative to `Self`*. -/// This can be used to decode a compact encoding frow which `T` can be derived by anyone with `R`. +/// A type relative to a value of type `R` which can be asynchronously decoded from bytes produced by a [`ufotofu::local_nb::BulkProducer`] +/// +/// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) pub trait RelativeDecodable { - /// Decode a value (relative to a reference value) to a bytestring in a specific way that is best described over at [willowprotocol.org](https://willowprotocol.org/specs/encodings/index.html#encodings_what). + /// + /// Decode a bytestring created with an [encoding function](https://macromania--channelclosing.deno.dev/specs/encodings/index.html#encoding_function) for the set of `Self` relative to a value of the set of `R`, ensuring that any pair of `Self` and `R` maps to exactly one bytestring, such that there exists a _decoding_ function (provided by this trait!) such that: + /// + /// - for every pair of `s` in `Self` and `r` in `R`, and every bytestring `b` that starts with `encode_s(s, r)`, we have `decode_s(b, r)=s`, and + /// - for every pair of `s` in `Self` and `r` in `R`, and every bytestring `b` that does not start with `encode_s(s, r)`, we have `decode_s(b, r) ≠ s`. + /// + /// Will return an error if the encoding correlates to the **encoding relation** and not the result of the aforementioned encoding function. + /// + /// [Definition](https://willowprotocol.org/specs/encodings/index.html#decode_s) fn relative_decode( reference: &R, producer: &mut Producer, @@ -57,4 +94,15 @@ pub trait RelativeDecodable { where Producer: BulkProducer, Self: Sized; + + /// Decode a bytestring belonging to the **encoding relation** on the set of `Self` relative to a value of the set of `R`, and the set of bytestrings, such that: + /// + /// - for every pair of `s` in `Self` and `r` in `R`, there is at least one bytestring in relation with the pair of `s` and `r`, and + /// - no bytestring in the relation is a prefix of another bytestring in the relation. + fn relative_decode_relation( + producer: &mut Producer, + ) -> impl Future>> + where + Producer: BulkProducer, + Self: Sized; } From a8aa0d68ca2a39186c1a0a0af6da49737ea73a22 Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Wed, 11 Sep 2024 16:31:01 +0100 Subject: [PATCH 04/18] Update all encodings for new Decodable API --- data-model/src/entry.rs | 16 ++--- data-model/src/path.rs | 9 ++- data-model/src/relative_encodings.rs | 71 +++++++++++----------- earthstar/src/cinn25519.rs | 2 +- earthstar/src/identity_id.rs | 4 +- earthstar/src/namespace_id.rs | 4 +- encoding/src/compact_width.rs | 16 ++--- encoding/src/traits.rs | 27 ++++++--- encoding/src/traits_sync.rs | 81 +++++++++++++++++++++---- encoding/src/unsigned_int.rs | 8 +-- fuzz/src/encode.rs | 16 ++--- fuzz/src/placeholder_params.rs | 4 +- fuzz/src/silly_sigs.rs | 4 +- meadowcap/src/mc_capability.rs | 19 +++--- meadowcap/src/mc_subspace_capability.rs | 12 ++-- 15 files changed, 183 insertions(+), 110 deletions(-) diff --git a/data-model/src/entry.rs b/data-model/src/entry.rs index f30a084..69e59ae 100644 --- a/data-model/src/entry.rs +++ b/data-model/src/entry.rs @@ -195,16 +195,18 @@ mod encoding { S: SubspaceId + Decodable, PD: PayloadDigest + Decodable, { - async fn decode(producer: &mut Prod) -> Result> + async fn decode_canonical( + producer: &mut Prod, + ) -> Result> where Prod: BulkProducer, { - let namespace_id = N::decode(producer).await?; - let subspace_id = S::decode(producer).await?; - let path = Path::::decode(producer).await?; - let timestamp = U64BE::decode(producer).await?.into(); - let payload_length = U64BE::decode(producer).await?.into(); - let payload_digest = PD::decode(producer).await?; + let namespace_id = N::decode_canonical(producer).await?; + let subspace_id = S::decode_canonical(producer).await?; + let path = Path::::decode_canonical(producer).await?; + let timestamp = U64BE::decode_canonical(producer).await?.into(); + let payload_length = U64BE::decode_canonical(producer).await?.into(); + let payload_digest = PD::decode_canonical(producer).await?; Ok(Entry { namespace_id, diff --git a/data-model/src/path.rs b/data-model/src/path.rs index 240576a..64dd729 100644 --- a/data-model/src/path.rs +++ b/data-model/src/path.rs @@ -818,7 +818,7 @@ mod encoding { } impl Decodable for Path { - async fn decode

(producer: &mut P) -> Result> + async fn decode_canonical

(producer: &mut P) -> Result> where P: BulkProducer, { @@ -854,6 +854,13 @@ mod encoding { Ok(unsafe { buf.to_path(component_count) }) } + + async fn decode_relation

(producer: &mut P) -> Result> + where + P: BulkProducer, + { + Self::decode_canonical(producer).await + } } } diff --git a/data-model/src/relative_encodings.rs b/data-model/src/relative_encodings.rs index 29728b6..4b2475e 100644 --- a/data-model/src/relative_encodings.rs +++ b/data-model/src/relative_encodings.rs @@ -73,7 +73,7 @@ pub(super) mod encoding { /// Decode a path relative to this path. /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_path_relative) - async fn relative_decode( + async fn relative_decode_canonical( reference: &Path, producer: &mut Producer, ) -> Result> @@ -84,7 +84,7 @@ pub(super) mod encoding { let lcp_component_count: usize = decode_max_power(MCC, producer).await?.try_into()?; if lcp_component_count == 0 { - let decoded = Path::::decode(producer).await?; + let decoded = Path::::decode_canonical(producer).await?; // === Necessary to produce canonic encodings. === if lcp_component_count @@ -247,7 +247,7 @@ pub(super) mod encoding { /// Decode an [`Entry`] relative from this [`Entry`]. /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_etry_relative_entry). - async fn relative_decode( + async fn relative_decode_canonical( reference: &Entry, producer: &mut Producer, ) -> Result, DecodeError> @@ -269,34 +269,31 @@ pub(super) mod encoding { let compact_width_payload_length = CompactWidth::decode_fixed_width_bitmask(header, 6); let namespace_id = if is_namespace_encoded { - N::decode(producer).await? + N::decode_canonical(producer).await? } else { reference.namespace_id().clone() }; - /* // Verify that the encoded namespace wasn't the same as ours // Which would indicate invalid input - if is_namespace_encoded && namespace_id == reference.get_namespace_id() { + if is_namespace_encoded && &namespace_id == reference.namespace_id() { return Err(DecodeError::InvalidInput); } - */ let subspace_id = if is_subspace_encoded { - S::decode(producer).await? + S::decode_canonical(producer).await? } else { reference.subspace_id().clone() }; - /* // Verify that the encoded subspace wasn't the same as ours // Which would indicate invalid input - if is_subspace_encoded && subspace_id == reference.get_subspace_id() { + if is_subspace_encoded && &subspace_id == reference.subspace_id() { return Err(DecodeError::InvalidInput); } - */ - let path = Path::::relative_decode(reference.path(), producer).await?; + let path = Path::::relative_decode_canonical(reference.path(), producer) + .await?; let time_diff = decode_compact_width_be(compact_width_time_diff, producer).await?; @@ -313,18 +310,16 @@ pub(super) mod encoding { .ok_or(DecodeError::InvalidInput)? }; - /* // Verify that the correct add_or_subtract_time_diff flag was set. - let should_have_subtracted = timestamp <= reference.get_timestamp(); + let should_have_subtracted = timestamp <= reference.timestamp(); if add_or_subtract_time_diff && should_have_subtracted { return Err(DecodeError::InvalidInput); } - */ let payload_length = decode_compact_width_be(compact_width_payload_length, producer).await?; - let payload_digest = PD::decode(producer).await?; + let payload_digest = PD::decode_canonical(producer).await?; Ok(Entry::new( namespace_id, @@ -410,7 +405,7 @@ pub(super) mod encoding { /// Decode an [`Entry`] relative to a reference [`NamespaceId`] and [`Area`]. /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_entry_in_namespace_area). - async fn relative_decode( + async fn relative_decode_canonical( reference: &(N, Area), producer: &mut Producer, ) -> Result> @@ -433,7 +428,7 @@ pub(super) mod encoding { let subspace_id = if is_subspace_encoded { match &out.subspace() { - AreaSubspace::Any => S::decode(producer).await?, + AreaSubspace::Any => S::decode_canonical(producer).await?, AreaSubspace::Id(_) => return Err(DecodeError::InvalidInput), } } else { @@ -443,7 +438,7 @@ pub(super) mod encoding { } }; - let path = Path::relative_decode(out.path(), producer).await?; + let path = Path::relative_decode_canonical(out.path(), producer).await?; if !path.is_prefixed_by(out.path()) { return Err(DecodeError::InvalidInput); @@ -453,7 +448,7 @@ pub(super) mod encoding { let payload_length = decode_compact_width_be(payload_length_compact_width, producer).await?; - let payload_digest = PD::decode(producer).await?; + let payload_digest = PD::decode_canonical(producer).await?; let timestamp = if add_time_diff_to_start { out.times().start.checked_add(time_diff) @@ -598,7 +593,7 @@ pub(super) mod encoding { /// Decode an [`Entry`] relative to a reference [`NamespaceId`] and [`Range3d`]. /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_entry_in_namespace_3drange). - async fn relative_decode( + async fn relative_decode_canonical( reference: &(N, Range3d), producer: &mut Producer, ) -> Result> @@ -627,7 +622,7 @@ pub(super) mod encoding { let payload_length_compact_width = CompactWidth::decode_fixed_width_bitmask(header, 6); let subspace_id = if is_subspace_encoded { - S::decode(producer).await? + S::decode_canonical(producer).await? } else { out.subspaces().start.clone() }; @@ -645,10 +640,12 @@ pub(super) mod encoding { } let path = if decode_path_relative_to_start { - Path::relative_decode(&out.paths().start, producer).await? + Path::relative_decode_canonical(&out.paths().start, producer).await? } else { match &out.paths().end { - RangeEnd::Closed(end_path) => Path::relative_decode(end_path, producer).await?, + RangeEnd::Closed(end_path) => { + Path::relative_decode_canonical(end_path, producer).await? + } RangeEnd::Open => return Err(DecodeError::InvalidInput), } }; @@ -680,7 +677,7 @@ pub(super) mod encoding { let payload_length = decode_compact_width_be(payload_length_compact_width, producer).await?; - let payload_digest = PD::decode(producer).await?; + let payload_digest = PD::decode_canonical(producer).await?; let timestamp = if add_time_diff_with_start { out.times().start.checked_add(time_diff) @@ -815,7 +812,7 @@ pub(super) mod encoding { /// Decode an [`Area`] relative to another [`Area`] which [includes](https://willowprotocol.org/specs/grouping-entries/index.html#area_include_area) it. /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_area_in_area). - async fn relative_decode( + async fn relative_decode_canonical( out: &Area, producer: &mut Producer, ) -> Result> @@ -855,7 +852,7 @@ pub(super) mod encoding { // =============================================== let subspace = if is_subspace_encoded { - let id = S::decode(producer).await?; + let id = S::decode_canonical(producer).await?; let sub = AreaSubspace::Id(id); // === Necessary to produce canonic encodings. === @@ -884,7 +881,7 @@ pub(super) mod encoding { } } - let path = Path::relative_decode(out.path(), producer).await?; + let path = Path::relative_decode_canonical(out.path(), producer).await?; // Verify the decoded path is prefixed by the reference path if !path.is_prefixed_by(out.path()) { @@ -1174,7 +1171,7 @@ pub(super) mod encoding { /// Encode an [`Range3d`] relative to another [`Range3d`] which [includes](https://willowprotocol.org/specs/grouping-entries/index.html#area_include_area) it. /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_area_in_area). - async fn relative_decode( + async fn relative_decode_canonical( reference: &Range3d, producer: &mut Producer, ) -> Result> @@ -1209,7 +1206,7 @@ pub(super) mod encoding { RangeEnd::Open => Err(DecodeError::InvalidInput)?, }, // This can only be 0b1100_0000 - _ => S::decode(producer).await?, + _ => S::decode_canonical(producer).await?, }; let subspace_end = match subspace_end_flags { @@ -1220,18 +1217,18 @@ pub(super) mod encoding { RangeEnd::Open => Err(DecodeError::InvalidInput)?, }, // This can only be 0b0011_0000 - _ => RangeEnd::Closed(S::decode(producer).await?), + _ => RangeEnd::Closed(S::decode_canonical(producer).await?), }; let path_start = match (is_path_start_rel_to_start, &reference.paths().end) { (true, RangeEnd::Closed(_)) => { - Path::relative_decode(&reference.paths().start, producer).await? + Path::relative_decode_canonical(&reference.paths().start, producer).await? } (true, RangeEnd::Open) => { - Path::relative_decode(&reference.paths().start, producer).await? + Path::relative_decode_canonical(&reference.paths().start, producer).await? } (false, RangeEnd::Closed(path_end)) => { - Path::relative_decode(path_end, producer).await? + Path::relative_decode_canonical(path_end, producer).await? } (false, RangeEnd::Open) => Err(DecodeError::InvalidInput)?, }; @@ -1239,11 +1236,13 @@ pub(super) mod encoding { let path_end = if is_path_end_open { RangeEnd::Open } else if is_path_end_rel_to_start { - RangeEnd::Closed(Path::relative_decode(&reference.paths().start, producer).await?) + RangeEnd::Closed( + Path::relative_decode_canonical(&reference.paths().start, producer).await?, + ) } else { match &reference.paths().end { RangeEnd::Closed(end) => { - RangeEnd::Closed(Path::relative_decode(end, producer).await?) + RangeEnd::Closed(Path::relative_decode_canonical(end, producer).await?) } RangeEnd::Open => Err(DecodeError::InvalidInput)?, } diff --git a/earthstar/src/cinn25519.rs b/earthstar/src/cinn25519.rs index 4a2fe42..ad35de1 100644 --- a/earthstar/src/cinn25519.rs +++ b/earthstar/src/cinn25519.rs @@ -140,7 +140,7 @@ pub(super) mod encoding { impl Decodable for Cinn25519PublicKey { - async fn decode( + async fn decode_canonical( producer: &mut Producer, ) -> Result::Error>> where diff --git a/earthstar/src/identity_id.rs b/earthstar/src/identity_id.rs index e6eedd0..aede138 100644 --- a/earthstar/src/identity_id.rs +++ b/earthstar/src/identity_id.rs @@ -38,11 +38,11 @@ pub(super) mod encoding { } impl Decodable for IdentityIdentifier { - async fn decode

(producer: &mut P) -> Result> + async fn decode_canonical

(producer: &mut P) -> Result> where P: BulkProducer, { - match Cinn25519PublicKey::decode(producer).await { + match Cinn25519PublicKey::decode_canonical(producer).await { Ok(pk) => Ok(Self(pk)), Err(err) => Err(err), } diff --git a/earthstar/src/namespace_id.rs b/earthstar/src/namespace_id.rs index 0b2e84c..7c8a309 100644 --- a/earthstar/src/namespace_id.rs +++ b/earthstar/src/namespace_id.rs @@ -40,11 +40,11 @@ pub(super) mod encoding { } impl Decodable for NamespaceIdentifier { - async fn decode

(producer: &mut P) -> Result::Error>> + async fn decode_canonical

(producer: &mut P) -> Result::Error>> where P: BulkProducer, { - match Cinn25519PublicKey::decode(producer).await { + match Cinn25519PublicKey::decode_canonical(producer).await { Ok(pk) => Ok(Self(pk)), Err(err) => Err(err), } diff --git a/encoding/src/compact_width.rs b/encoding/src/compact_width.rs index b9e440f..e8269dd 100644 --- a/encoding/src/compact_width.rs +++ b/encoding/src/compact_width.rs @@ -154,10 +154,10 @@ pub mod encoding { producer: &mut Producer, ) -> Result> { let decoded = match compact_width { - CompactWidth::One => U8BE::decode(producer).await.map(u64::from), - CompactWidth::Two => U16BE::decode(producer).await.map(u64::from), - CompactWidth::Four => U32BE::decode(producer).await.map(u64::from), - CompactWidth::Eight => U64BE::decode(producer).await.map(u64::from), + CompactWidth::One => U8BE::decode_canonical(producer).await.map(u64::from), + CompactWidth::Two => U16BE::decode_canonical(producer).await.map(u64::from), + CompactWidth::Four => U32BE::decode_canonical(producer).await.map(u64::from), + CompactWidth::Eight => U64BE::decode_canonical(producer).await.map(u64::from), }?; Ok(decoded) @@ -170,10 +170,10 @@ pub mod encoding { producer: &mut Producer, ) -> Result> { let decoded = match compact_width { - CompactWidth::One => U8BE::decode(producer).await.map(u64::from), - CompactWidth::Two => U16BE::decode(producer).await.map(u64::from), - CompactWidth::Four => U32BE::decode(producer).await.map(u64::from), - CompactWidth::Eight => U64BE::decode(producer).await.map(u64::from), + CompactWidth::One => U8BE::decode_canonical(producer).await.map(u64::from), + CompactWidth::Two => U16BE::decode_canonical(producer).await.map(u64::from), + CompactWidth::Four => U32BE::decode_canonical(producer).await.map(u64::from), + CompactWidth::Eight => U64BE::decode_canonical(producer).await.map(u64::from), }?; let real_width = CompactWidth::from_u64(decoded); diff --git a/encoding/src/traits.rs b/encoding/src/traits.rs index 1134a66..049795e 100644 --- a/encoding/src/traits.rs +++ b/encoding/src/traits.rs @@ -7,7 +7,7 @@ use ufotofu::local_nb::{BulkConsumer, BulkProducer}; /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) pub trait Encodable { - /// Encode the value with an [encoding function](https://macromania--channelclosing.deno.dev/specs/encodings/index.html#encoding_function) for the set of `Self`, ensuring that any value of `Self` maps to exactly one bytestring, such that there exists a _decoding_ function such that: + /// Encode the value with an [encoding function](https://willowprotocol.org/specs/encodings/index.html#encoding_function) for the set of `Self`, ensuring that any value of `Self` maps to exactly one bytestring, such that there exists a _decoding_ function such that: /// /// - for every value `s` in `Self` and every bytestring `b` that starts with `encode_s(s)`, we have `decode_s(b)=s`, and /// - for every `s` in `Self` and every bytestring b that does not start with `encode_s(s)`, we have `decode_s(b) ≠ s`. @@ -26,15 +26,15 @@ pub trait Encodable { /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) pub trait Decodable { - /// Decode a bytestring created with an [encoding function](https://macromania--channelclosing.deno.dev/specs/encodings/index.html#encoding_function) for the set of `Self`, ensuring that any value of `Self` maps to exactly one bytestring, such that there exists a _decoding_ function (provided by this trait!) such that: + /// Decode a bytestring created with an [encoding function](https://willowprotocol.org/specs/encodings/index.html#encoding_function) for the set of `Self`, ensuring that any value of `Self` maps to exactly one bytestring, such that there exists a _decoding_ function (provided by this trait!) such that: /// /// - for every value `s` in `Self` and every bytestring `b` that starts with `encode_s(s)`, we have `decode_s(b)=s`, and /// - for every `s` in `Self` and every bytestring `b` that does not start with `encode_s(s)`, we have `decode_s(b) ≠ s`. /// - /// Will return an error if the encoding correlates to the **encoding relation** and not the result of the aforementioned encoding function. + /// Will return an error if the encoding has not been produced by the corresponding encoding function, even if it belongs to an encoding relation for the type. /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#decode_s) - fn decode( + fn decode_canonical( producer: &mut Producer, ) -> impl Future>> where @@ -52,7 +52,10 @@ pub trait Decodable { ) -> impl Future>> where Producer: BulkProducer, - Self: Sized; + Self: Sized, + { + Self::decode_canonical(producer) + } } /// A type relative to a reference value of type `R` which can be asynchronously encoded to bytes consumed by a [`ufotofu::local_nb::BulkConsumer`] @@ -61,7 +64,7 @@ pub trait Decodable { /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) pub trait RelativeEncodable { - /// Encode a pair of `Self` and `R` with the [encoding function](https://macromania--channelclosing.deno.dev/specs/encodings/index.html#encoding_function) for the set of `Self` relative to a value of the set of `R`, ensuring that any pair of `Self` and `R` maps to exactly one bytestring, such that there exists a _decoding_ function such that: + /// Encode a pair of `Self` and `R` with the [encoding function](https://willowprotocol.org/specs/encodings/index.html#encoding_function) for the set of `Self` relative to a value of the set of `R`, ensuring that any pair of `Self` and `R` maps to exactly one bytestring, such that there exists a _decoding_ function such that: /// /// - for every pair of `s` in `Self` and `r` in `R`, and every bytestring `b` that starts with `encode_s(s, r)`, we have `decode_s(b, r)=s`, and /// - for every pair of `s` in `Self` and `r` in `R`, and every bytestring `b` that does not start with `encode_s(s, r)`, we have `decode_s(b, r) ≠ s`. @@ -79,15 +82,15 @@ pub trait RelativeEncodable { /// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) pub trait RelativeDecodable { /// - /// Decode a bytestring created with an [encoding function](https://macromania--channelclosing.deno.dev/specs/encodings/index.html#encoding_function) for the set of `Self` relative to a value of the set of `R`, ensuring that any pair of `Self` and `R` maps to exactly one bytestring, such that there exists a _decoding_ function (provided by this trait!) such that: + /// Decode a bytestring created with an [encoding function](https://willowprotocol.org/specs/encodings/index.html#encoding_function) for the set of `Self` relative to a value of the set of `R`, ensuring that any pair of `Self` and `R` maps to exactly one bytestring, such that there exists a _decoding_ function (provided by this trait!) such that: /// /// - for every pair of `s` in `Self` and `r` in `R`, and every bytestring `b` that starts with `encode_s(s, r)`, we have `decode_s(b, r)=s`, and /// - for every pair of `s` in `Self` and `r` in `R`, and every bytestring `b` that does not start with `encode_s(s, r)`, we have `decode_s(b, r) ≠ s`. /// - /// Will return an error if the encoding correlates to the **encoding relation** and not the result of the aforementioned encoding function. + /// Will return an error if the encoding has not been produced by the corresponding encoding function, even if it belongs to an encoding relation for the type. /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#decode_s) - fn relative_decode( + fn relative_decode_canonical( reference: &R, producer: &mut Producer, ) -> impl Future>> @@ -100,9 +103,13 @@ pub trait RelativeDecodable { /// - for every pair of `s` in `Self` and `r` in `R`, there is at least one bytestring in relation with the pair of `s` and `r`, and /// - no bytestring in the relation is a prefix of another bytestring in the relation. fn relative_decode_relation( + reference: &R, producer: &mut Producer, ) -> impl Future>> where Producer: BulkProducer, - Self: Sized; + Self: Sized, + { + Self::relative_decode_canonical(reference, producer) + } } diff --git a/encoding/src/traits_sync.rs b/encoding/src/traits_sync.rs index 0632a7d..1317f5d 100644 --- a/encoding/src/traits_sync.rs +++ b/encoding/src/traits_sync.rs @@ -1,35 +1,68 @@ use crate::error::DecodeError; use ufotofu::sync::{BulkConsumer, BulkProducer}; -/// A type that can be encoded to a bytestring, ensuring that any value of `Self` maps to exactly one bytestring. +/// A type which can be encoded to bytes consumed by a [`ufotofu::local_nb::BulkConsumer`] /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) pub trait Encodable { - /// Encode a value to a bytestring in a specific way that is best described over at [willowprotocol.org](https://willowprotocol.org/specs/encodings/index.html#encodings_what). + /// Encode the value with an [encoding function](https://willowprotocol.org/specs/encodings/index.html#encoding_function) for the set of `Self`, ensuring that any value of `Self` maps to exactly one bytestring, such that there exists a _decoding_ function such that: /// + /// - for every value `s` in `Self` and every bytestring `b` that starts with `encode_s(s)`, we have `decode_s(b)=s`, and + /// - for every `s` in `Self` and every bytestring b that does not start with `encode_s(s)`, we have `decode_s(b) ≠ s`. + /// + /// The encoded bytestring will be consumed to the provided [`ufotofu::local_nb::BulkConsumer`]. /// [Definition](https://willowprotocol.org/specs/encodings/index.html#encode_s) fn encode(&self, consumer: &mut Consumer) -> Result<(), Consumer::Error> where Consumer: BulkConsumer; } -/// A type that can be decoded from a bytestring, ensuring that every valid encoding maps to exactly one member of `Self`. +/// A type which can be decoded from bytes produced by a [`ufotofu::local_nb::BulkProducer`] /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) pub trait Decodable { - /// Decode a value to a bytestring in a specific way that is best described over at [willowprotocol.org](https://willowprotocol.org/specs/encodings/index.html#encodings_what). + /// Decode a bytestring created with an [encoding function](https://willowprotocol.org/specs/encodings/index.html#encoding_function) for the set of `Self`, ensuring that any value of `Self` maps to exactly one bytestring, such that there exists a _decoding_ function (provided by this trait!) such that: + /// + /// - for every value `s` in `Self` and every bytestring `b` that starts with `encode_s(s)`, we have `decode_s(b)=s`, and + /// - for every `s` in `Self` and every bytestring `b` that does not start with `encode_s(s)`, we have `decode_s(b) ≠ s`. + /// + /// Will return an error if the encoding has not been produced by the corresponding encoding function, even if it belongs to an encoding relation for the type. /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#decode_s) - fn decode(producer: &mut Producer) -> Result> + fn decode_canonical( + producer: &mut Producer, + ) -> Result> where Producer: BulkProducer, Self: Sized; + + /// Decode a bytestring belonging to the **encoding relation** on the set of `Self` and the set of bytestrings, such that: + /// + /// - for every `s` in `Self`, there is at least one bytestring in relation with `s`, and + /// - no bytestring in the relation is a prefix of another bytestring in the relation. + /// + /// [Definition](https://willowprotocol.org/specs/encodings/index.html#decode_s) + fn decode_relation( + producer: &mut Producer, + ) -> Result> + where + Producer: BulkProducer, + Self: Sized, + { + Self::decode_canonical(producer) + } } -/// A type that can be used to encode `T` to a bytestring *encoded relative to `R`*. -/// This can be used to create more compact encodings from which `T` can be derived by anyone with `R`. +/// A type relative to a reference value of type `R` which can be encoded to bytes consumed by a [`ufotofu::local_nb::BulkConsumer`] +/// +/// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) +/// +/// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) pub trait RelativeEncodable { - /// Encode a value (relative to a reference value) to a bytestring in a specific way that is best described over at [willowprotocol.org](https://willowprotocol.org/specs/encodings/index.html#encodings_what). + /// Encode a pair of `Self` and `R` with the [encoding function](https://willowprotocol.org/specs/encodings/index.html#encoding_function) for the set of `Self` relative to a value of the set of `R`, ensuring that any pair of `Self` and `R` maps to exactly one bytestring, such that there exists a _decoding_ function such that: + /// + /// - for every pair of `s` in `Self` and `r` in `R`, and every bytestring `b` that starts with `encode_s(s, r)`, we have `decode_s(b, r)=s`, and + /// - for every pair of `s` in `Self` and `r` in `R`, and every bytestring `b` that does not start with `encode_s(s, r)`, we have `decode_s(b, r) ≠ s`. fn relative_encode( &self, reference: &R, @@ -39,15 +72,39 @@ pub trait RelativeEncodable { Consumer: BulkConsumer; } -/// A type that can be used to decode `T` from a bytestring *encoded relative to `Self`*. -/// This can be used to decode a compact encoding frow which `T` can be derived by anyone with `R`. +/// A type relative to a value of type `R` which can be decoded from bytes produced by a [`ufotofu::local_nb::BulkProducer`] +/// +/// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) pub trait RelativeDecodable { - /// Decode a value (relative to a reference value) to a bytestring in a specific way that is best described over at [willowprotocol.org](https://willowprotocol.org/specs/encodings/index.html#encodings_what). - fn relative_decode( + /// + /// Decode a bytestring created with an [encoding function](https://willowprotocol.org/specs/encodings/index.html#encoding_function) for the set of `Self` relative to a value of the set of `R`, ensuring that any pair of `Self` and `R` maps to exactly one bytestring, such that there exists a _decoding_ function (provided by this trait!) such that: + /// + /// - for every pair of `s` in `Self` and `r` in `R`, and every bytestring `b` that starts with `encode_s(s, r)`, we have `decode_s(b, r)=s`, and + /// - for every pair of `s` in `Self` and `r` in `R`, and every bytestring `b` that does not start with `encode_s(s, r)`, we have `decode_s(b, r) ≠ s`. + /// + /// Will return an error if the encoding has not been produced by the corresponding encoding function, even if it belongs to an encoding relation for the type. + /// + /// [Definition](https://willowprotocol.org/specs/encodings/index.html#decode_s) + fn relative_decode_canonical( reference: &R, producer: &mut Producer, ) -> Result> where Producer: BulkProducer, Self: Sized; + + /// Decode a bytestring belonging to the **encoding relation** on the set of `Self` relative to a value of the set of `R`, and the set of bytestrings, such that: + /// + /// - for every pair of `s` in `Self` and `r` in `R`, there is at least one bytestring in relation with the pair of `s` and `r`, and + /// - no bytestring in the relation is a prefix of another bytestring in the relation. + fn relative_decode_relation( + reference: &R, + producer: &mut Producer, + ) -> Result> + where + Producer: BulkProducer, + Self: Sized, + { + Self::relative_decode_canonical(reference, producer) + } } diff --git a/encoding/src/unsigned_int.rs b/encoding/src/unsigned_int.rs index bcd75a3..8cad125 100644 --- a/encoding/src/unsigned_int.rs +++ b/encoding/src/unsigned_int.rs @@ -94,7 +94,7 @@ mod encoding { } impl Decodable for U8BE { - async fn decode( + async fn decode_canonical( producer: &mut Producer, ) -> Result> where @@ -122,7 +122,7 @@ mod encoding { } impl Decodable for U16BE { - async fn decode( + async fn decode_canonical( producer: &mut Producer, ) -> Result> where @@ -150,7 +150,7 @@ mod encoding { } impl Decodable for U32BE { - async fn decode( + async fn decode_canonical( producer: &mut Producer, ) -> Result> where @@ -178,7 +178,7 @@ mod encoding { } impl Decodable for U64BE { - async fn decode( + async fn decode_canonical( producer: &mut Producer, ) -> Result> where diff --git a/fuzz/src/encode.rs b/fuzz/src/encode.rs index 1704608..0d80bf0 100644 --- a/fuzz/src/encode.rs +++ b/fuzz/src/encode.rs @@ -33,7 +33,7 @@ where let mut producer = FromBoxedSlice::from_vec(new_vec); // Check for correct errors - let decoded_item = T::decode(&mut producer).unwrap(); + let decoded_item = T::decode_canonical(&mut producer).unwrap(); assert_eq!(decoded_item, item); } @@ -44,7 +44,7 @@ where { let mut producer = FromSlice::new(data); - match T::decode(&mut producer) { + match T::decode_canonical(&mut producer) { Ok(item) => { // println!("item {:?}", item); @@ -77,7 +77,7 @@ where { let mut producer = FromSlice::new(data); - match T::decode(&mut producer) { + match T::decode_canonical(&mut producer) { Ok(item) => { // println!("item {:?}", item); @@ -89,7 +89,7 @@ where let mut producer_2 = FromSlice::new(consumer.as_ref()); - match T::decode(&mut producer_2) { + match T::decode_canonical(&mut producer_2) { Ok(decoded_again) => { assert_eq!(item, decoded_again); } @@ -140,7 +140,7 @@ pub fn relative_encoding_roundtrip( let mut producer = FromBoxedSlice::from_vec(new_vec); // Check for correct errors - let decoded_item = T::relative_decode(&reference, &mut producer).unwrap(); + let decoded_item = T::relative_decode_canonical(&reference, &mut producer).unwrap(); assert_eq!(decoded_item, subject); } @@ -152,7 +152,7 @@ where { let mut producer = FromSlice::new(data); - match T::relative_decode(&reference, &mut producer) { + match T::relative_decode_canonical(&reference, &mut producer) { Ok(item) => { // It decoded to a valid item! Gasp! // Can we turn it back into the same encoding? @@ -187,7 +187,7 @@ where { let mut producer = FromSlice::new(data); - match T::relative_decode(&reference, &mut producer) { + match T::relative_decode_relation(&reference, &mut producer) { Ok(item) => { // It decoded to a valid item! Gasp! // Can we turn it back into the same encoding? @@ -200,7 +200,7 @@ where let mut producer_2 = FromSlice::new(consumer.as_ref()); - match T::relative_decode(&reference, &mut producer_2) { + match T::relative_decode_relation(&reference, &mut producer_2) { Ok(decoded_again) => { assert_eq!(item, decoded_again); } diff --git a/fuzz/src/placeholder_params.rs b/fuzz/src/placeholder_params.rs index 7a05251..1e84369 100644 --- a/fuzz/src/placeholder_params.rs +++ b/fuzz/src/placeholder_params.rs @@ -25,7 +25,7 @@ impl Encodable for FakePayloadDigest { } impl Decodable for FakePayloadDigest { - async fn decode

(producer: &mut P) -> Result> + async fn decode_canonical

(producer: &mut P) -> Result> where P: BulkProducer, { @@ -51,7 +51,7 @@ impl EncodableSync for FakePayloadDigest { } impl DecodableSync for FakePayloadDigest { - fn decode

(producer: &mut P) -> Result> + fn decode_canonical

(producer: &mut P) -> Result> where P: BulkProducerSync, { diff --git a/fuzz/src/silly_sigs.rs b/fuzz/src/silly_sigs.rs index 040f0ba..9fb32f5 100644 --- a/fuzz/src/silly_sigs.rs +++ b/fuzz/src/silly_sigs.rs @@ -102,7 +102,7 @@ pub mod encoding { } impl Decodable for SillyPublicKey { - async fn decode( + async fn decode_canonical( producer: &mut Producer, ) -> Result> where @@ -126,7 +126,7 @@ pub mod encoding { } impl Decodable for SillySig { - async fn decode( + async fn decode_canonical( producer: &mut Producer, ) -> Result> where diff --git a/meadowcap/src/mc_capability.rs b/meadowcap/src/mc_capability.rs index 526b20b..a274a02 100644 --- a/meadowcap/src/mc_capability.rs +++ b/meadowcap/src/mc_capability.rs @@ -438,7 +438,7 @@ pub(super) mod encoding { NamespaceSignature: EncodableSync + Decodable + Clone, UserSignature: EncodableSync + Decodable + Clone, { - async fn relative_decode( + async fn relative_decode_canonical( out: &Area, producer: &mut Producer, ) -> Result> @@ -455,11 +455,11 @@ pub(super) mod encoding { AccessMode::Read }; - let namespace_key = NamespacePublicKey::decode(producer).await?; - let user_key = UserPublicKey::decode(producer).await?; + let namespace_key = NamespacePublicKey::decode_canonical(producer).await?; + let user_key = UserPublicKey::decode_canonical(producer).await?; let mut base_cap = if is_owned { - let initial_authorisation = NamespaceSignature::decode(producer).await?; + let initial_authorisation = NamespaceSignature::decode_canonical(producer).await?; let cap = OwnedCapability::from_existing( namespace_key, @@ -497,12 +497,13 @@ pub(super) mod encoding { let mut prev_area = out.clone(); for _ in 0..delegations_to_decode { - let area = - Area::::relative_decode(&prev_area, producer) - .await?; + let area = Area::::relative_decode_canonical( + &prev_area, producer, + ) + .await?; prev_area = area.clone(); - let user = UserPublicKey::decode(producer).await?; - let signature = UserSignature::decode(producer).await?; + let user = UserPublicKey::decode_canonical(producer).await?; + let signature = UserSignature::decode_canonical(producer).await?; base_cap .append_existing_delegation(Delegation { diff --git a/meadowcap/src/mc_subspace_capability.rs b/meadowcap/src/mc_subspace_capability.rs index 2b41f66..3a2eb49 100644 --- a/meadowcap/src/mc_subspace_capability.rs +++ b/meadowcap/src/mc_subspace_capability.rs @@ -314,7 +314,7 @@ pub(super) mod encoding { UserPublicKey: SubspaceId + EncodableSync + Decodable + Verifier, UserSignature: EncodableSync + Decodable + Clone, { - async fn decode

(producer: &mut P) -> Result> + async fn decode_canonical

(producer: &mut P) -> Result> where P: BulkProducer, { @@ -322,9 +322,9 @@ pub(super) mod encoding { let header = produce_byte(producer).await?; - let namespace_key = NamespacePublicKey::decode(producer).await?; - let user_key = UserPublicKey::decode(producer).await?; - let initial_authorisation = NamespaceSignature::decode(producer).await?; + let namespace_key = NamespacePublicKey::decode_canonical(producer).await?; + let user_key = UserPublicKey::decode_canonical(producer).await?; + let initial_authorisation = NamespaceSignature::decode_canonical(producer).await?; let mut base_cap = Self::from_existing(namespace_key, user_key, initial_authorisation) .map_err(|_| DecodeError::InvalidInput)?; @@ -354,8 +354,8 @@ pub(super) mod encoding { }; for _ in 0..delegations_to_decode { - let user = UserPublicKey::decode(producer).await?; - let signature = UserSignature::decode(producer).await?; + let user = UserPublicKey::decode_canonical(producer).await?; + let signature = UserSignature::decode_canonical(producer).await?; let delegation = SubspaceDelegation::new(user, signature); base_cap From 3e12e4156c6ef46aed269a6c6acc2e773ceac044 Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Wed, 11 Sep 2024 16:48:48 +0100 Subject: [PATCH 05/18] Update fuzz test names --- fuzz/fuzz_targets/area_rel_area_encoding.rs | 4 ++-- fuzz/fuzz_targets/entry_encoding.rs | 4 ++-- fuzz/fuzz_targets/entry_encoding_random.rs | 4 ++-- fuzz/fuzz_targets/entry_rel_entry_encoding.rs | 4 ++-- .../entry_rel_namespace_area_encoding.rs | 4 ++-- .../entry_rel_namespace_range_encoding.rs | 4 ++-- fuzz/fuzz_targets/mc_capability_rel_area_encoding.rs | 4 ++-- .../mc_capability_rel_area_encoding_random.rs | 4 ++-- fuzz/fuzz_targets/mc_subspace_capability_encoding.rs | 4 ++-- .../mc_subspace_capability_encoding_random.rs | 8 ++++---- fuzz/fuzz_targets/path_encoding.rs | 4 ++-- fuzz/fuzz_targets/path_encoding2.rs | 4 ++-- fuzz/fuzz_targets/path_encoding3.rs | 4 ++-- fuzz/fuzz_targets/path_encoding_random.rs | 4 ++-- fuzz/fuzz_targets/path_encoding_random2.rs | 4 ++-- fuzz/fuzz_targets/path_encoding_random3.rs | 4 ++-- fuzz/fuzz_targets/path_rel_path_encoding.rs | 12 ++++++------ fuzz/fuzz_targets/path_rel_path_encoding2.rs | 12 ++++++------ fuzz/fuzz_targets/path_rel_path_encoding3.rs | 12 ++++++------ fuzz/fuzz_targets/path_rel_path_encoding_random.rs | 7 +++++-- fuzz/fuzz_targets/path_rel_path_encoding_random2.rs | 7 +++++-- fuzz/fuzz_targets/path_rel_path_encoding_random3.rs | 7 +++++-- fuzz/fuzz_targets/range3d_rel_range3d_encoding.rs | 4 ++-- fuzz/fuzz_targets/u16be_encoding.rs | 4 ++-- fuzz/fuzz_targets/u16be_encoding_random.rs | 4 ++-- fuzz/fuzz_targets/u32be_encoding.rs | 4 ++-- fuzz/fuzz_targets/u32be_encoding_random.rs | 4 ++-- fuzz/fuzz_targets/u64be_encoding.rs | 4 ++-- fuzz/fuzz_targets/u64be_encoding_random.rs | 4 ++-- fuzz/fuzz_targets/u8be_encoding.rs | 4 ++-- fuzz/fuzz_targets/u8be_encoding_random.rs | 4 ++-- fuzz/src/encode.rs | 8 ++++---- 32 files changed, 89 insertions(+), 80 deletions(-) diff --git a/fuzz/fuzz_targets/area_rel_area_encoding.rs b/fuzz/fuzz_targets/area_rel_area_encoding.rs index 3c72156..944cac8 100644 --- a/fuzz/fuzz_targets/area_rel_area_encoding.rs +++ b/fuzz/fuzz_targets/area_rel_area_encoding.rs @@ -4,7 +4,7 @@ use earthstar::identity_id::IdentityIdentifier as IdentityId; use libfuzzer_sys::fuzz_target; use ufotofu::local_nb::consumer::TestConsumer; use willow_data_model::grouping::Area; -use willow_fuzz::encode::relative_encoding_roundtrip; +use willow_fuzz::encode::relative_encoding_canonical_roundtrip; fuzz_target!(|data: ( Area<16, 16, 16, IdentityId>, @@ -17,7 +17,7 @@ fuzz_target!(|data: ( return; } - relative_encoding_roundtrip::< + relative_encoding_canonical_roundtrip::< Area<16, 16, 16, IdentityId>, Area<16, 16, 16, IdentityId>, TestConsumer, diff --git a/fuzz/fuzz_targets/entry_encoding.rs b/fuzz/fuzz_targets/entry_encoding.rs index 024442b..9c51506 100644 --- a/fuzz/fuzz_targets/entry_encoding.rs +++ b/fuzz/fuzz_targets/entry_encoding.rs @@ -5,7 +5,7 @@ use earthstar::namespace_id::NamespaceIdentifier as EsNamespaceId; use libfuzzer_sys::fuzz_target; use ufotofu::local_nb::consumer::TestConsumer; use willow_data_model::Entry; -use willow_fuzz::encode::encoding_roundtrip; +use willow_fuzz::encode::encoding_canonical_roundtrip; use willow_fuzz::placeholder_params::FakePayloadDigest; fuzz_target!(|data: ( @@ -14,5 +14,5 @@ fuzz_target!(|data: ( )| { let (entry, mut consumer) = data; - encoding_roundtrip::<_, TestConsumer>(entry, &mut consumer); + encoding_canonical_roundtrip::<_, TestConsumer>(entry, &mut consumer); }); diff --git a/fuzz/fuzz_targets/entry_encoding_random.rs b/fuzz/fuzz_targets/entry_encoding_random.rs index 82a85bc..a81d329 100644 --- a/fuzz/fuzz_targets/entry_encoding_random.rs +++ b/fuzz/fuzz_targets/entry_encoding_random.rs @@ -6,8 +6,8 @@ use earthstar::namespace_id::NamespaceIdentifier as EsNamespaceId; use willow_data_model::Entry; use libfuzzer_sys::fuzz_target; -use willow_fuzz::{encode::encoding_random, placeholder_params::FakePayloadDigest}; +use willow_fuzz::{encode::encoding_canonical_random, placeholder_params::FakePayloadDigest}; fuzz_target!(|data: &[u8]| { - encoding_random::>(data); + encoding_canonical_random::>(data); }); diff --git a/fuzz/fuzz_targets/entry_rel_entry_encoding.rs b/fuzz/fuzz_targets/entry_rel_entry_encoding.rs index d1fd8a4..428744a 100644 --- a/fuzz/fuzz_targets/entry_rel_entry_encoding.rs +++ b/fuzz/fuzz_targets/entry_rel_entry_encoding.rs @@ -5,7 +5,7 @@ use earthstar::namespace_id::NamespaceIdentifier as EsNamespaceId; use libfuzzer_sys::fuzz_target; use ufotofu::local_nb::consumer::TestConsumer; use willow_data_model::Entry; -use willow_fuzz::encode::relative_encoding_roundtrip; +use willow_fuzz::encode::relative_encoding_canonical_roundtrip; use willow_fuzz::placeholder_params::FakePayloadDigest; fuzz_target!(|data: ( @@ -15,7 +15,7 @@ fuzz_target!(|data: ( )| { let (entry_sub, entry_ref, mut consumer) = data; - relative_encoding_roundtrip::< + relative_encoding_canonical_roundtrip::< Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, TestConsumer, diff --git a/fuzz/fuzz_targets/entry_rel_namespace_area_encoding.rs b/fuzz/fuzz_targets/entry_rel_namespace_area_encoding.rs index 7f6b16e..8f4943b 100644 --- a/fuzz/fuzz_targets/entry_rel_namespace_area_encoding.rs +++ b/fuzz/fuzz_targets/entry_rel_namespace_area_encoding.rs @@ -6,7 +6,7 @@ use libfuzzer_sys::fuzz_target; use ufotofu::local_nb::consumer::TestConsumer; use willow_data_model::grouping::Area; use willow_data_model::Entry; -use willow_fuzz::encode::relative_encoding_roundtrip; +use willow_fuzz::encode::relative_encoding_canonical_roundtrip; use willow_fuzz::placeholder_params::FakePayloadDigest; fuzz_target!(|data: ( @@ -22,7 +22,7 @@ fuzz_target!(|data: ( let namespace = entry.namespace_id().clone(); - relative_encoding_roundtrip::< + relative_encoding_canonical_roundtrip::< Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, (EsNamespaceId, Area<16, 16, 16, IdentityId>), TestConsumer, diff --git a/fuzz/fuzz_targets/entry_rel_namespace_range_encoding.rs b/fuzz/fuzz_targets/entry_rel_namespace_range_encoding.rs index 6a13e3a..2057269 100644 --- a/fuzz/fuzz_targets/entry_rel_namespace_range_encoding.rs +++ b/fuzz/fuzz_targets/entry_rel_namespace_range_encoding.rs @@ -6,7 +6,7 @@ use libfuzzer_sys::fuzz_target; use ufotofu::local_nb::consumer::TestConsumer; use willow_data_model::grouping::Range3d; use willow_data_model::Entry; -use willow_fuzz::encode::relative_encoding_roundtrip; +use willow_fuzz::encode::relative_encoding_canonical_roundtrip; use willow_fuzz::placeholder_params::FakePayloadDigest; fuzz_target!(|data: ( @@ -22,7 +22,7 @@ fuzz_target!(|data: ( let namespace = entry.namespace_id().clone(); - relative_encoding_roundtrip::< + relative_encoding_canonical_roundtrip::< Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, (EsNamespaceId, Range3d<16, 16, 16, IdentityId>), TestConsumer, diff --git a/fuzz/fuzz_targets/mc_capability_rel_area_encoding.rs b/fuzz/fuzz_targets/mc_capability_rel_area_encoding.rs index ea40b85..774ae64 100644 --- a/fuzz/fuzz_targets/mc_capability_rel_area_encoding.rs +++ b/fuzz/fuzz_targets/mc_capability_rel_area_encoding.rs @@ -4,7 +4,7 @@ use libfuzzer_sys::fuzz_target; use meadowcap::McCapability; use ufotofu::local_nb::consumer::TestConsumer; use willow_data_model::grouping::Area; -use willow_fuzz::encode::relative_encoding_roundtrip; +use willow_fuzz::encode::relative_encoding_canonical_roundtrip; use willow_fuzz::silly_sigs::{SillyPublicKey, SillySig}; fuzz_target!(|data: ( @@ -38,7 +38,7 @@ fuzz_target!(|data: ( return; } - relative_encoding_roundtrip::< + relative_encoding_canonical_roundtrip::< McCapability<3, 3, 3, SillyPublicKey, SillySig, SillyPublicKey, SillySig>, Area<3, 3, 3, SillyPublicKey>, TestConsumer, diff --git a/fuzz/fuzz_targets/mc_capability_rel_area_encoding_random.rs b/fuzz/fuzz_targets/mc_capability_rel_area_encoding_random.rs index 237922f..92e5922 100644 --- a/fuzz/fuzz_targets/mc_capability_rel_area_encoding_random.rs +++ b/fuzz/fuzz_targets/mc_capability_rel_area_encoding_random.rs @@ -3,13 +3,13 @@ use libfuzzer_sys::fuzz_target; use meadowcap::McCapability; use willow_data_model::grouping::Area; -use willow_fuzz::encode::relative_encoding_random; +use willow_fuzz::encode::relative_encoding_canonical_random; use willow_fuzz::silly_sigs::{SillyPublicKey, SillySig}; fuzz_target!(|data: (&[u8], Area<3, 3, 3, SillyPublicKey>,)| { let (random_bytes, out) = data; - relative_encoding_random::< + relative_encoding_canonical_random::< Area<3, 3, 3, SillyPublicKey>, McCapability<3, 3, 3, SillyPublicKey, SillySig, SillyPublicKey, SillySig>, >(out, random_bytes) diff --git a/fuzz/fuzz_targets/mc_subspace_capability_encoding.rs b/fuzz/fuzz_targets/mc_subspace_capability_encoding.rs index 542d92f..ddf82ce 100644 --- a/fuzz/fuzz_targets/mc_subspace_capability_encoding.rs +++ b/fuzz/fuzz_targets/mc_subspace_capability_encoding.rs @@ -3,7 +3,7 @@ use libfuzzer_sys::fuzz_target; use meadowcap::McSubspaceCapability; use ufotofu::local_nb::consumer::TestConsumer; -use willow_fuzz::encode::encoding_roundtrip; +use willow_fuzz::encode::encoding_canonical_roundtrip; use willow_fuzz::silly_sigs::{SillyPublicKey, SillySig}; fuzz_target!(|data: ( @@ -23,7 +23,7 @@ fuzz_target!(|data: ( last_receiver = delegee; } - encoding_roundtrip::< + encoding_canonical_roundtrip::< McSubspaceCapability, TestConsumer, >(cap_with_delegees, &mut consumer) diff --git a/fuzz/fuzz_targets/mc_subspace_capability_encoding_random.rs b/fuzz/fuzz_targets/mc_subspace_capability_encoding_random.rs index 42fe05a..72c0d28 100644 --- a/fuzz/fuzz_targets/mc_subspace_capability_encoding_random.rs +++ b/fuzz/fuzz_targets/mc_subspace_capability_encoding_random.rs @@ -2,11 +2,11 @@ use libfuzzer_sys::fuzz_target; use meadowcap::McSubspaceCapability; -use willow_fuzz::encode::encoding_random; +use willow_fuzz::encode::encoding_canonical_random; use willow_fuzz::silly_sigs::{SillyPublicKey, SillySig}; fuzz_target!(|data: &[u8]| { - encoding_random::>( - data, - ) + encoding_canonical_random::< + McSubspaceCapability, + >(data) }); diff --git a/fuzz/fuzz_targets/path_encoding.rs b/fuzz/fuzz_targets/path_encoding.rs index 959cced..719a18e 100644 --- a/fuzz/fuzz_targets/path_encoding.rs +++ b/fuzz/fuzz_targets/path_encoding.rs @@ -3,7 +3,7 @@ use libfuzzer_sys::fuzz_target; use ufotofu::local_nb::consumer::TestConsumer; use willow_data_model::Path; -use willow_fuzz::encode::encoding_roundtrip; +use willow_fuzz::encode::encoding_canonical_roundtrip; const MCL: usize = 300; const MCC: usize = 300; @@ -12,5 +12,5 @@ const MPL: usize = 300; fuzz_target!(|data: (Path, TestConsumer)| { let (path, mut consumer) = data; - encoding_roundtrip::<_, TestConsumer>(path, &mut consumer); + encoding_canonical_roundtrip::<_, TestConsumer>(path, &mut consumer); }); diff --git a/fuzz/fuzz_targets/path_encoding2.rs b/fuzz/fuzz_targets/path_encoding2.rs index 4583a2b..58ff7ac 100644 --- a/fuzz/fuzz_targets/path_encoding2.rs +++ b/fuzz/fuzz_targets/path_encoding2.rs @@ -3,7 +3,7 @@ use libfuzzer_sys::fuzz_target; use ufotofu::local_nb::consumer::TestConsumer; use willow_data_model::Path; -use willow_fuzz::encode::encoding_roundtrip; +use willow_fuzz::encode::encoding_canonical_roundtrip; const MCL: usize = 2; const MCC: usize = 3; @@ -12,5 +12,5 @@ const MPL: usize = 3; fuzz_target!(|data: (Path, TestConsumer)| { let (path, mut consumer) = data; - encoding_roundtrip::<_, TestConsumer>(path, &mut consumer); + encoding_canonical_roundtrip::<_, TestConsumer>(path, &mut consumer); }); diff --git a/fuzz/fuzz_targets/path_encoding3.rs b/fuzz/fuzz_targets/path_encoding3.rs index 1787ff7..7ac9435 100644 --- a/fuzz/fuzz_targets/path_encoding3.rs +++ b/fuzz/fuzz_targets/path_encoding3.rs @@ -3,7 +3,7 @@ use libfuzzer_sys::fuzz_target; use ufotofu::local_nb::consumer::TestConsumer; use willow_data_model::Path; -use willow_fuzz::encode::encoding_roundtrip; +use willow_fuzz::encode::encoding_canonical_roundtrip; const MCL: usize = 4; const MCC: usize = 4; @@ -12,5 +12,5 @@ const MPL: usize = 16; fuzz_target!(|data: (Path, TestConsumer)| { let (path, mut consumer) = data; - encoding_roundtrip::<_, TestConsumer>(path, &mut consumer); + encoding_canonical_roundtrip::<_, TestConsumer>(path, &mut consumer); }); diff --git a/fuzz/fuzz_targets/path_encoding_random.rs b/fuzz/fuzz_targets/path_encoding_random.rs index 3b3b704..21b1263 100644 --- a/fuzz/fuzz_targets/path_encoding_random.rs +++ b/fuzz/fuzz_targets/path_encoding_random.rs @@ -2,12 +2,12 @@ use libfuzzer_sys::fuzz_target; use willow_data_model::Path; -use willow_fuzz::encode::encoding_random; +use willow_fuzz::encode::encoding_canonical_random; const MCL: usize = 300; const MCC: usize = 300; const MPL: usize = 300; fuzz_target!(|data: &[u8]| { - encoding_random::>(data); + encoding_canonical_random::>(data); }); diff --git a/fuzz/fuzz_targets/path_encoding_random2.rs b/fuzz/fuzz_targets/path_encoding_random2.rs index a08464a..ba00c14 100644 --- a/fuzz/fuzz_targets/path_encoding_random2.rs +++ b/fuzz/fuzz_targets/path_encoding_random2.rs @@ -2,12 +2,12 @@ use libfuzzer_sys::fuzz_target; use willow_data_model::Path; -use willow_fuzz::encode::encoding_random; +use willow_fuzz::encode::encoding_canonical_random; const MCL: usize = 2; const MCC: usize = 3; const MPL: usize = 3; fuzz_target!(|data: &[u8]| { - encoding_random::>(data); + encoding_canonical_random::>(data); }); diff --git a/fuzz/fuzz_targets/path_encoding_random3.rs b/fuzz/fuzz_targets/path_encoding_random3.rs index bd879ff..10ab01c 100644 --- a/fuzz/fuzz_targets/path_encoding_random3.rs +++ b/fuzz/fuzz_targets/path_encoding_random3.rs @@ -2,12 +2,12 @@ use libfuzzer_sys::fuzz_target; use willow_data_model::Path; -use willow_fuzz::encode::encoding_random; +use willow_fuzz::encode::encoding_canonical_random; const MCL: usize = 4; const MCC: usize = 4; const MPL: usize = 16; fuzz_target!(|data: &[u8]| { - encoding_random::>(data); + encoding_canonical_random::>(data); }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding.rs b/fuzz/fuzz_targets/path_rel_path_encoding.rs index 1c14c10..80e00bb 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding.rs @@ -4,7 +4,7 @@ use libfuzzer_sys::fuzz_target; use ufotofu::local_nb::consumer::TestConsumer; use willow_data_model::Path; -use willow_fuzz::encode::relative_encoding_roundtrip; +use willow_fuzz::encode::relative_encoding_canonical_roundtrip; const MCL: usize = 300; const MCC: usize = 300; @@ -17,9 +17,9 @@ fuzz_target!(|data: ( )| { let (path_sub, path_ref, mut consumer) = data; - relative_encoding_roundtrip::, Path, TestConsumer>( - path_sub, - path_ref, - &mut consumer, - ) + relative_encoding_canonical_roundtrip::< + Path, + Path, + TestConsumer, + >(path_sub, path_ref, &mut consumer) }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding2.rs b/fuzz/fuzz_targets/path_rel_path_encoding2.rs index 030e361..ccec8d4 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding2.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding2.rs @@ -4,7 +4,7 @@ use libfuzzer_sys::fuzz_target; use ufotofu::local_nb::consumer::TestConsumer; use willow_data_model::Path; -use willow_fuzz::encode::relative_encoding_roundtrip; +use willow_fuzz::encode::relative_encoding_canonical_roundtrip; const MCL: usize = 2; const MCC: usize = 3; @@ -17,9 +17,9 @@ fuzz_target!(|data: ( )| { let (path_sub, path_ref, mut consumer) = data; - relative_encoding_roundtrip::, Path, TestConsumer>( - path_sub, - path_ref, - &mut consumer, - ) + relative_encoding_canonical_roundtrip::< + Path, + Path, + TestConsumer, + >(path_sub, path_ref, &mut consumer) }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding3.rs b/fuzz/fuzz_targets/path_rel_path_encoding3.rs index e7cbd4b..3a55324 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding3.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding3.rs @@ -4,7 +4,7 @@ use libfuzzer_sys::fuzz_target; use ufotofu::local_nb::consumer::TestConsumer; use willow_data_model::Path; -use willow_fuzz::encode::relative_encoding_roundtrip; +use willow_fuzz::encode::relative_encoding_canonical_roundtrip; const MCL: usize = 4; const MCC: usize = 4; @@ -17,9 +17,9 @@ fuzz_target!(|data: ( )| { let (path_sub, path_ref, mut consumer) = data; - relative_encoding_roundtrip::, Path, TestConsumer>( - path_sub, - path_ref, - &mut consumer, - ) + relative_encoding_canonical_roundtrip::< + Path, + Path, + TestConsumer, + >(path_sub, path_ref, &mut consumer) }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding_random.rs b/fuzz/fuzz_targets/path_rel_path_encoding_random.rs index 23a216f..4ddd01b 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding_random.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding_random.rs @@ -2,7 +2,7 @@ use libfuzzer_sys::fuzz_target; use willow_data_model::Path; -use willow_fuzz::encode::relative_encoding_random; +use willow_fuzz::encode::relative_encoding_canonical_random; const MCL: usize = 300; const MCC: usize = 300; @@ -11,5 +11,8 @@ const MPL: usize = 300; fuzz_target!(|data: (&[u8], Path)| { let (random_bytes, ref_path) = data; - relative_encoding_random::, Path>(ref_path, random_bytes) + relative_encoding_canonical_random::, Path>( + ref_path, + random_bytes, + ) }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding_random2.rs b/fuzz/fuzz_targets/path_rel_path_encoding_random2.rs index 5d674bb..b473cfa 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding_random2.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding_random2.rs @@ -2,7 +2,7 @@ use libfuzzer_sys::fuzz_target; use willow_data_model::Path; -use willow_fuzz::encode::relative_encoding_random; +use willow_fuzz::encode::relative_encoding_canonical_random; const MCL: usize = 2; const MCC: usize = 3; @@ -11,5 +11,8 @@ const MPL: usize = 3; fuzz_target!(|data: (&[u8], Path)| { let (random_bytes, ref_path) = data; - relative_encoding_random::, Path>(ref_path, random_bytes) + relative_encoding_canonical_random::, Path>( + ref_path, + random_bytes, + ) }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding_random3.rs b/fuzz/fuzz_targets/path_rel_path_encoding_random3.rs index 0f2a66d..175efcf 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding_random3.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding_random3.rs @@ -2,7 +2,7 @@ use libfuzzer_sys::fuzz_target; use willow_data_model::Path; -use willow_fuzz::encode::relative_encoding_random; +use willow_fuzz::encode::relative_encoding_canonical_random; const MCL: usize = 4; const MCC: usize = 4; @@ -11,5 +11,8 @@ const MPL: usize = 16; fuzz_target!(|data: (&[u8], Path)| { let (random_bytes, ref_path) = data; - relative_encoding_random::, Path>(ref_path, random_bytes) + relative_encoding_canonical_random::, Path>( + ref_path, + random_bytes, + ) }); diff --git a/fuzz/fuzz_targets/range3d_rel_range3d_encoding.rs b/fuzz/fuzz_targets/range3d_rel_range3d_encoding.rs index 073ada4..8ff774f 100644 --- a/fuzz/fuzz_targets/range3d_rel_range3d_encoding.rs +++ b/fuzz/fuzz_targets/range3d_rel_range3d_encoding.rs @@ -4,7 +4,7 @@ use earthstar::identity_id::IdentityIdentifier as IdentityId; use libfuzzer_sys::fuzz_target; use ufotofu::local_nb::consumer::TestConsumer; use willow_data_model::grouping::Range3d; -use willow_fuzz::encode::relative_encoding_roundtrip; +use willow_fuzz::encode::relative_encoding_canonical_roundtrip; fuzz_target!(|data: ( Range3d<16, 16, 16, IdentityId>, @@ -13,7 +13,7 @@ fuzz_target!(|data: ( )| { let (ran, reference, mut consumer) = data; - relative_encoding_roundtrip::< + relative_encoding_canonical_roundtrip::< Range3d<16, 16, 16, IdentityId>, Range3d<16, 16, 16, IdentityId>, TestConsumer, diff --git a/fuzz/fuzz_targets/u16be_encoding.rs b/fuzz/fuzz_targets/u16be_encoding.rs index fd4353a..8816a83 100644 --- a/fuzz/fuzz_targets/u16be_encoding.rs +++ b/fuzz/fuzz_targets/u16be_encoding.rs @@ -3,10 +3,10 @@ use libfuzzer_sys::fuzz_target; use ufotofu::local_nb::consumer::TestConsumer; use willow_encoding::U16BE; -use willow_fuzz::encode::encoding_roundtrip; +use willow_fuzz::encode::encoding_canonical_roundtrip; fuzz_target!(|data: (u16, TestConsumer)| { let (n, mut consumer) = data; - encoding_roundtrip::<_, TestConsumer>(U16BE::from(n), &mut consumer); + encoding_canonical_roundtrip::<_, TestConsumer>(U16BE::from(n), &mut consumer); }); diff --git a/fuzz/fuzz_targets/u16be_encoding_random.rs b/fuzz/fuzz_targets/u16be_encoding_random.rs index 0895fc3..9bb5829 100644 --- a/fuzz/fuzz_targets/u16be_encoding_random.rs +++ b/fuzz/fuzz_targets/u16be_encoding_random.rs @@ -2,8 +2,8 @@ use libfuzzer_sys::fuzz_target; use willow_encoding::U16BE; -use willow_fuzz::encode::encoding_random; +use willow_fuzz::encode::encoding_canonical_random; fuzz_target!(|data: &[u8]| { - encoding_random::(data); + encoding_canonical_random::(data); }); diff --git a/fuzz/fuzz_targets/u32be_encoding.rs b/fuzz/fuzz_targets/u32be_encoding.rs index 38b23bf..7a0170c 100644 --- a/fuzz/fuzz_targets/u32be_encoding.rs +++ b/fuzz/fuzz_targets/u32be_encoding.rs @@ -3,10 +3,10 @@ use libfuzzer_sys::fuzz_target; use ufotofu::local_nb::consumer::TestConsumer; use willow_encoding::U32BE; -use willow_fuzz::encode::encoding_roundtrip; +use willow_fuzz::encode::encoding_canonical_roundtrip; fuzz_target!(|data: (u32, TestConsumer)| { let (n, mut consumer) = data; - encoding_roundtrip::<_, TestConsumer>(U32BE::from(n), &mut consumer); + encoding_canonical_roundtrip::<_, TestConsumer>(U32BE::from(n), &mut consumer); }); diff --git a/fuzz/fuzz_targets/u32be_encoding_random.rs b/fuzz/fuzz_targets/u32be_encoding_random.rs index 7b07bcd..0e666f2 100644 --- a/fuzz/fuzz_targets/u32be_encoding_random.rs +++ b/fuzz/fuzz_targets/u32be_encoding_random.rs @@ -2,8 +2,8 @@ use libfuzzer_sys::fuzz_target; use willow_encoding::U32BE; -use willow_fuzz::encode::encoding_random; +use willow_fuzz::encode::encoding_canonical_random; fuzz_target!(|data: &[u8]| { - encoding_random::(data); + encoding_canonical_random::(data); }); diff --git a/fuzz/fuzz_targets/u64be_encoding.rs b/fuzz/fuzz_targets/u64be_encoding.rs index 56435da..5198cfc 100644 --- a/fuzz/fuzz_targets/u64be_encoding.rs +++ b/fuzz/fuzz_targets/u64be_encoding.rs @@ -3,10 +3,10 @@ use libfuzzer_sys::fuzz_target; use ufotofu::local_nb::consumer::TestConsumer; use willow_encoding::U64BE; -use willow_fuzz::encode::encoding_roundtrip; +use willow_fuzz::encode::encoding_canonical_roundtrip; fuzz_target!(|data: (u64, TestConsumer)| { let (n, mut consumer) = data; - encoding_roundtrip::<_, TestConsumer>(U64BE::from(n), &mut consumer); + encoding_canonical_roundtrip::<_, TestConsumer>(U64BE::from(n), &mut consumer); }); diff --git a/fuzz/fuzz_targets/u64be_encoding_random.rs b/fuzz/fuzz_targets/u64be_encoding_random.rs index a2532f2..d1ea8aa 100644 --- a/fuzz/fuzz_targets/u64be_encoding_random.rs +++ b/fuzz/fuzz_targets/u64be_encoding_random.rs @@ -2,8 +2,8 @@ use libfuzzer_sys::fuzz_target; use willow_encoding::U64BE; -use willow_fuzz::encode::encoding_random; +use willow_fuzz::encode::encoding_canonical_random; fuzz_target!(|data: &[u8]| { - encoding_random::(data); + encoding_canonical_random::(data); }); diff --git a/fuzz/fuzz_targets/u8be_encoding.rs b/fuzz/fuzz_targets/u8be_encoding.rs index 766102d..faad12e 100644 --- a/fuzz/fuzz_targets/u8be_encoding.rs +++ b/fuzz/fuzz_targets/u8be_encoding.rs @@ -3,10 +3,10 @@ use libfuzzer_sys::fuzz_target; use ufotofu::local_nb::consumer::TestConsumer; use willow_encoding::U8BE; -use willow_fuzz::encode::encoding_roundtrip; +use willow_fuzz::encode::encoding_canonical_roundtrip; fuzz_target!(|data: (u8, TestConsumer)| { let (n, mut consumer) = data; - encoding_roundtrip::<_, TestConsumer>(U8BE::from(n), &mut consumer); + encoding_canonical_roundtrip::<_, TestConsumer>(U8BE::from(n), &mut consumer); }); diff --git a/fuzz/fuzz_targets/u8be_encoding_random.rs b/fuzz/fuzz_targets/u8be_encoding_random.rs index a8bce9e..f044b25 100644 --- a/fuzz/fuzz_targets/u8be_encoding_random.rs +++ b/fuzz/fuzz_targets/u8be_encoding_random.rs @@ -2,8 +2,8 @@ use libfuzzer_sys::fuzz_target; use willow_encoding::U8BE; -use willow_fuzz::encode::encoding_random; +use willow_fuzz::encode::encoding_canonical_random; fuzz_target!(|data: &[u8]| { - encoding_random::(data); + encoding_canonical_random::(data); }); diff --git a/fuzz/src/encode.rs b/fuzz/src/encode.rs index 0d80bf0..22965f5 100644 --- a/fuzz/src/encode.rs +++ b/fuzz/src/encode.rs @@ -12,7 +12,7 @@ use willow_encoding::{ DecodeError, }; -pub fn encoding_roundtrip(item: T, consumer: &mut TestConsumer) +pub fn encoding_canonical_roundtrip(item: T, consumer: &mut TestConsumer) where T: Encodable + Decodable + std::fmt::Debug + PartialEq + Eq, C: BulkConsumer, @@ -38,7 +38,7 @@ where assert_eq!(decoded_item, item); } -pub fn encoding_random(data: &[u8]) +pub fn encoding_canonical_random(data: &[u8]) where T: Encodable + Decodable + std::fmt::Debug, { @@ -112,7 +112,7 @@ where }; } -pub fn relative_encoding_roundtrip( +pub fn relative_encoding_canonical_roundtrip( subject: T, reference: R, consumer: &mut TestConsumer, @@ -145,7 +145,7 @@ pub fn relative_encoding_roundtrip( assert_eq!(decoded_item, subject); } -pub fn relative_encoding_random(reference: R, data: &[u8]) +pub fn relative_encoding_canonical_random(reference: R, data: &[u8]) where T: RelativeEncodable + RelativeDecodable + std::fmt::Debug, R: std::fmt::Debug, From 95b1331b71bb8350744579a5d7d3eab3e114ce1b Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Wed, 11 Sep 2024 17:13:43 +0100 Subject: [PATCH 06/18] Update encoding fuzz tests to test both encoding function and relation --- .../area_rel_area_encoding_random.rs | 6 ++-- .../entry_rel_entry_encoding_random.rs | 6 ++-- ...ntry_rel_namespace_area_encoding_random.rs | 6 ++-- ...try_rel_namespace_range_encoding_random.rs | 6 ++-- .../mc_capability_rel_area_encoding_random.rs | 6 ++-- .../path_rel_path_encoding_random.rs | 7 ++--- .../path_rel_path_encoding_random2.rs | 7 ++--- .../path_rel_path_encoding_random3.rs | 7 ++--- .../range3d_rel_rang3d_encoding_random.rs | 10 +++--- fuzz/src/encode.rs | 31 ++++++++++++++----- 10 files changed, 50 insertions(+), 42 deletions(-) diff --git a/fuzz/fuzz_targets/area_rel_area_encoding_random.rs b/fuzz/fuzz_targets/area_rel_area_encoding_random.rs index 7095e1d..8c43c98 100644 --- a/fuzz/fuzz_targets/area_rel_area_encoding_random.rs +++ b/fuzz/fuzz_targets/area_rel_area_encoding_random.rs @@ -3,14 +3,14 @@ use earthstar::identity_id::IdentityIdentifier as IdentityId; use libfuzzer_sys::fuzz_target; use willow_data_model::grouping::Area; -use willow_fuzz::encode::relative_encoding_relation_random; +use willow_fuzz::encode::relative_encoding_random; fuzz_target!(|data: (&[u8], Area<16, 16, 16, IdentityId>)| { // fuzzed code goes here let (random_bytes, area) = data; - relative_encoding_relation_random::, Area<16, 16, 16, IdentityId>>( - area, + relative_encoding_random::, Area<16, 16, 16, IdentityId>>( + &area, random_bytes, ) }); diff --git a/fuzz/fuzz_targets/entry_rel_entry_encoding_random.rs b/fuzz/fuzz_targets/entry_rel_entry_encoding_random.rs index befe28d..36d0bb2 100644 --- a/fuzz/fuzz_targets/entry_rel_entry_encoding_random.rs +++ b/fuzz/fuzz_targets/entry_rel_entry_encoding_random.rs @@ -4,7 +4,7 @@ use earthstar::identity_id::IdentityIdentifier as IdentityId; use earthstar::namespace_id::NamespaceIdentifier as EsNamespaceId; use libfuzzer_sys::fuzz_target; use willow_data_model::Entry; -use willow_fuzz::encode::relative_encoding_relation_random; +use willow_fuzz::encode::relative_encoding_random; use willow_fuzz::placeholder_params::FakePayloadDigest; fuzz_target!(|data: ( @@ -13,8 +13,8 @@ fuzz_target!(|data: ( )| { let (random_bytes, ref_entry) = data; - relative_encoding_relation_random::< + relative_encoding_random::< Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, - >(ref_entry, random_bytes) + >(&ref_entry, random_bytes) }); diff --git a/fuzz/fuzz_targets/entry_rel_namespace_area_encoding_random.rs b/fuzz/fuzz_targets/entry_rel_namespace_area_encoding_random.rs index 0cc0d82..41aca5b 100644 --- a/fuzz/fuzz_targets/entry_rel_namespace_area_encoding_random.rs +++ b/fuzz/fuzz_targets/entry_rel_namespace_area_encoding_random.rs @@ -5,7 +5,7 @@ use earthstar::namespace_id::NamespaceIdentifier as EsNamespaceId; use libfuzzer_sys::fuzz_target; use willow_data_model::grouping::Area; use willow_data_model::Entry; -use willow_fuzz::encode::relative_encoding_relation_random; +use willow_fuzz::encode::relative_encoding_random; use willow_fuzz::placeholder_params::FakePayloadDigest; fuzz_target!( @@ -13,9 +13,9 @@ fuzz_target!( // fuzzed code goes here let (random_bytes, namespaced_area) = data; - relative_encoding_relation_random::< + relative_encoding_random::< (EsNamespaceId, Area<16, 16, 16, IdentityId>), Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, - >(namespaced_area, random_bytes) + >(&namespaced_area, random_bytes) } ); diff --git a/fuzz/fuzz_targets/entry_rel_namespace_range_encoding_random.rs b/fuzz/fuzz_targets/entry_rel_namespace_range_encoding_random.rs index 018eb57..3916229 100644 --- a/fuzz/fuzz_targets/entry_rel_namespace_range_encoding_random.rs +++ b/fuzz/fuzz_targets/entry_rel_namespace_range_encoding_random.rs @@ -5,7 +5,7 @@ use earthstar::namespace_id::NamespaceIdentifier as EsNamespaceId; use libfuzzer_sys::fuzz_target; use willow_data_model::grouping::Range3d; use willow_data_model::Entry; -use willow_fuzz::encode::relative_encoding_relation_random; +use willow_fuzz::encode::relative_encoding_random; use willow_fuzz::placeholder_params::FakePayloadDigest; fuzz_target!( @@ -13,9 +13,9 @@ fuzz_target!( // fuzzed code goes here let (random_bytes, namespaced_range_3d) = data; - relative_encoding_relation_random::< + relative_encoding_random::< (EsNamespaceId, Range3d<16, 16, 16, IdentityId>), Entry<16, 16, 16, EsNamespaceId, IdentityId, FakePayloadDigest>, - >(namespaced_range_3d, random_bytes); + >(&namespaced_range_3d, random_bytes); } ); diff --git a/fuzz/fuzz_targets/mc_capability_rel_area_encoding_random.rs b/fuzz/fuzz_targets/mc_capability_rel_area_encoding_random.rs index 92e5922..2929927 100644 --- a/fuzz/fuzz_targets/mc_capability_rel_area_encoding_random.rs +++ b/fuzz/fuzz_targets/mc_capability_rel_area_encoding_random.rs @@ -3,14 +3,14 @@ use libfuzzer_sys::fuzz_target; use meadowcap::McCapability; use willow_data_model::grouping::Area; -use willow_fuzz::encode::relative_encoding_canonical_random; +use willow_fuzz::encode::relative_encoding_random; use willow_fuzz::silly_sigs::{SillyPublicKey, SillySig}; fuzz_target!(|data: (&[u8], Area<3, 3, 3, SillyPublicKey>,)| { let (random_bytes, out) = data; - relative_encoding_canonical_random::< + relative_encoding_random::< Area<3, 3, 3, SillyPublicKey>, McCapability<3, 3, 3, SillyPublicKey, SillySig, SillyPublicKey, SillySig>, - >(out, random_bytes) + >(&out, random_bytes) }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding_random.rs b/fuzz/fuzz_targets/path_rel_path_encoding_random.rs index 4ddd01b..644aeda 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding_random.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding_random.rs @@ -2,7 +2,7 @@ use libfuzzer_sys::fuzz_target; use willow_data_model::Path; -use willow_fuzz::encode::relative_encoding_canonical_random; +use willow_fuzz::encode::relative_encoding_random; const MCL: usize = 300; const MCC: usize = 300; @@ -11,8 +11,5 @@ const MPL: usize = 300; fuzz_target!(|data: (&[u8], Path)| { let (random_bytes, ref_path) = data; - relative_encoding_canonical_random::, Path>( - ref_path, - random_bytes, - ) + relative_encoding_random::, Path>(&ref_path, random_bytes) }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding_random2.rs b/fuzz/fuzz_targets/path_rel_path_encoding_random2.rs index b473cfa..16d6e70 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding_random2.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding_random2.rs @@ -2,7 +2,7 @@ use libfuzzer_sys::fuzz_target; use willow_data_model::Path; -use willow_fuzz::encode::relative_encoding_canonical_random; +use willow_fuzz::encode::relative_encoding_random; const MCL: usize = 2; const MCC: usize = 3; @@ -11,8 +11,5 @@ const MPL: usize = 3; fuzz_target!(|data: (&[u8], Path)| { let (random_bytes, ref_path) = data; - relative_encoding_canonical_random::, Path>( - ref_path, - random_bytes, - ) + relative_encoding_random::, Path>(&ref_path, random_bytes) }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding_random3.rs b/fuzz/fuzz_targets/path_rel_path_encoding_random3.rs index 175efcf..4275232 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding_random3.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding_random3.rs @@ -2,7 +2,7 @@ use libfuzzer_sys::fuzz_target; use willow_data_model::Path; -use willow_fuzz::encode::relative_encoding_canonical_random; +use willow_fuzz::encode::relative_encoding_random; const MCL: usize = 4; const MCC: usize = 4; @@ -11,8 +11,5 @@ const MPL: usize = 16; fuzz_target!(|data: (&[u8], Path)| { let (random_bytes, ref_path) = data; - relative_encoding_canonical_random::, Path>( - ref_path, - random_bytes, - ) + relative_encoding_random::, Path>(&ref_path, random_bytes) }); diff --git a/fuzz/fuzz_targets/range3d_rel_rang3d_encoding_random.rs b/fuzz/fuzz_targets/range3d_rel_rang3d_encoding_random.rs index 49f9777..176e60c 100644 --- a/fuzz/fuzz_targets/range3d_rel_rang3d_encoding_random.rs +++ b/fuzz/fuzz_targets/range3d_rel_rang3d_encoding_random.rs @@ -3,14 +3,14 @@ use earthstar::identity_id::IdentityIdentifier as IdentityId; use libfuzzer_sys::fuzz_target; use willow_data_model::grouping::Range3d; -use willow_fuzz::encode::relative_encoding_relation_random; +use willow_fuzz::encode::relative_encoding_random; fuzz_target!(|data: (&[u8], Range3d<16, 16, 16, IdentityId>)| { // fuzzed code goes here let (random_bytes, area) = data; - relative_encoding_relation_random::< - Range3d<16, 16, 16, IdentityId>, - Range3d<16, 16, 16, IdentityId>, - >(area, random_bytes); + relative_encoding_random::, Range3d<16, 16, 16, IdentityId>>( + &area, + random_bytes, + ); }); diff --git a/fuzz/src/encode.rs b/fuzz/src/encode.rs index 22965f5..ca391f6 100644 --- a/fuzz/src/encode.rs +++ b/fuzz/src/encode.rs @@ -38,6 +38,14 @@ where assert_eq!(decoded_item, item); } +pub fn encoding_random(data: &[u8]) +where + T: Encodable + Decodable + std::fmt::Debug + PartialEq + Eq, +{ + encoding_canonical_random::(data); + encoding_relation_random::(data); +} + pub fn encoding_canonical_random(data: &[u8]) where T: Encodable + Decodable + std::fmt::Debug, @@ -145,14 +153,23 @@ pub fn relative_encoding_canonical_roundtrip( assert_eq!(decoded_item, subject); } -pub fn relative_encoding_canonical_random(reference: R, data: &[u8]) +pub fn relative_encoding_random(reference: &R, data: &[u8]) +where + T: RelativeEncodable + RelativeDecodable + std::fmt::Debug + Eq, + R: std::fmt::Debug, +{ + relative_encoding_canonical_random::(reference, data); + relative_encoding_relation_random::(reference, data); +} + +pub fn relative_encoding_canonical_random(reference: &R, data: &[u8]) where T: RelativeEncodable + RelativeDecodable + std::fmt::Debug, R: std::fmt::Debug, { let mut producer = FromSlice::new(data); - match T::relative_decode_canonical(&reference, &mut producer) { + match T::relative_decode_canonical(reference, &mut producer) { Ok(item) => { // It decoded to a valid item! Gasp! // Can we turn it back into the same encoding? @@ -161,7 +178,7 @@ where // println!("item {:?}", item); // println!("ref {:?}", reference); - item.relative_encode(&reference, &mut consumer).unwrap(); + item.relative_encode(reference, &mut consumer).unwrap(); let encoded = consumer.as_ref(); @@ -180,14 +197,14 @@ where }; } -pub fn relative_encoding_relation_random(reference: R, data: &[u8]) +pub fn relative_encoding_relation_random(reference: &R, data: &[u8]) where T: RelativeEncodable + RelativeDecodable + std::fmt::Debug + Eq, R: std::fmt::Debug, { let mut producer = FromSlice::new(data); - match T::relative_decode_relation(&reference, &mut producer) { + match T::relative_decode_relation(reference, &mut producer) { Ok(item) => { // It decoded to a valid item! Gasp! // Can we turn it back into the same encoding? @@ -196,11 +213,11 @@ where // println!("item {:?}", item); // println!("ref {:?}", reference); - item.relative_encode(&reference, &mut consumer).unwrap(); + item.relative_encode(reference, &mut consumer).unwrap(); let mut producer_2 = FromSlice::new(consumer.as_ref()); - match T::relative_decode_relation(&reference, &mut producer_2) { + match T::relative_decode_relation(reference, &mut producer_2) { Ok(decoded_again) => { assert_eq!(item, decoded_again); } From c78b5616113c3da58569a57f317f6088b9a79773 Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Fri, 13 Sep 2024 08:08:20 +0100 Subject: [PATCH 07/18] Add canonic encoding for 3dRange rel 3dRange --- data-model/src/relative_encodings.rs | 207 +++++++++++++++--- fuzz/Cargo.toml | 4 +- ...=> range3d_rel_range3d_encoding_random.rs} | 0 3 files changed, 177 insertions(+), 34 deletions(-) rename fuzz/fuzz_targets/{range3d_rel_rang3d_encoding_random.rs => range3d_rel_range3d_encoding_random.rs} (100%) diff --git a/data-model/src/relative_encodings.rs b/data-model/src/relative_encodings.rs index 8528860..64739ec 100644 --- a/data-model/src/relative_encodings.rs +++ b/data-model/src/relative_encodings.rs @@ -1059,7 +1059,7 @@ pub(super) mod encoding { self_path_end.longest_common_prefix(&reference.paths().start); let lcp_end_end = self_path_end.longest_common_prefix(ref_path_end); - if lcp_end_start.get_component_count() > lcp_end_end.get_component_count() { + if lcp_end_start.get_component_count() >= lcp_end_end.get_component_count() { header_1 |= 0b0000_0010; } } @@ -1157,7 +1157,10 @@ pub(super) mod encoding { } encode_compact_width_be(start_time_diff, consumer).await?; - encode_compact_width_be(end_time_diff, consumer).await?; + + if self.times().end != RangeEnd::Open { + encode_compact_width_be(end_time_diff, consumer).await?; + } Ok(()) } @@ -1194,7 +1197,7 @@ pub(super) mod encoding { let add_or_subtract_start_time_diff = is_bitflagged(header_2, 1); let start_time_diff_compact_width = CompactWidth::decode_fixed_width_bitmask(header_2, 2); - let is_times_end_rel_to_start = is_bitflagged(header_2, 4); + let is_time_end_rel_to_start = is_bitflagged(header_2, 4); let add_or_subtract_end_time_diff = is_bitflagged(header_2, 5); let end_time_diff_compact_width = CompactWidth::decode_fixed_width_bitmask(header_2, 6); @@ -1205,8 +1208,19 @@ pub(super) mod encoding { RangeEnd::Closed(end) => end.clone(), RangeEnd::Open => Err(DecodeError::InvalidInput)?, }, - // This can only be 0b1100_0000 - _ => S::decode_canonical(producer).await?, + 0b1100_0000 => { + let decoded_subspace = S::decode_canonical(producer).await?; + + if decoded_subspace == reference.subspaces().start + || reference.subspaces().end == decoded_subspace + { + return Err(DecodeError::InvalidInput); + } + + decoded_subspace + } + // This can only be b0000_0000 (which is not valid!) + _ => Err(DecodeError::InvalidInput)?, }; let subspace_end = match subspace_end_flags { @@ -1217,9 +1231,21 @@ pub(super) mod encoding { RangeEnd::Open => Err(DecodeError::InvalidInput)?, }, // This can only be 0b0011_0000 - _ => RangeEnd::Closed(S::decode_canonical(producer).await?), + _ => { + let decoded_subspace = RangeEnd::Closed(S::decode_canonical(producer).await?); + + if decoded_subspace == reference.subspaces().start + || reference.subspaces().end == decoded_subspace + { + return Err(DecodeError::InvalidInput); + } + + decoded_subspace + } }; + // Check subspace end... + let path_start = match (is_path_start_rel_to_start, &reference.paths().end) { (true, RangeEnd::Closed(_)) => { Path::relative_decode_canonical(&reference.paths().start, producer).await? @@ -1233,6 +1259,28 @@ pub(super) mod encoding { (false, RangeEnd::Open) => Err(DecodeError::InvalidInput)?, }; + // Canonicity check for path start + match &reference.paths().end { + RangeEnd::Closed(ref_path_end) => { + let lcp_start_start = + path_start.longest_common_prefix(&reference.paths().start); + let lcp_start_end = path_start.longest_common_prefix(ref_path_end); + + let expected_is_start_rel_to_start = lcp_start_start.get_component_count() + >= lcp_start_end.get_component_count(); + + if expected_is_start_rel_to_start != is_path_start_rel_to_start { + return Err(DecodeError::InvalidInput); + } + } + RangeEnd::Open => { + if !is_path_start_rel_to_start { + return Err(DecodeError::InvalidInput); + } + } + } + // Canonicity check for path start over + let path_end = if is_path_end_open { RangeEnd::Open } else if is_path_end_rel_to_start { @@ -1248,6 +1296,30 @@ pub(super) mod encoding { } }; + // Canonicity check for path end + match &path_end { + RangeEnd::Closed(p_end) => match &reference.paths().end { + RangeEnd::Closed(ref_end) => { + let lcp_end_start = p_end.longest_common_prefix(&reference.paths().start); + let lcp_end_end = p_end.longest_common_prefix(ref_end); + + let expected_is_path_end_rel_to_start = lcp_end_start.get_component_count() + >= lcp_end_end.get_component_count(); + + if expected_is_path_end_rel_to_start != is_path_end_rel_to_start { + return Err(DecodeError::InvalidInput); + } + } + RangeEnd::Open => {} + }, + RangeEnd::Open => { + if is_path_end_rel_to_start { + return Err(DecodeError::InvalidInput); + } + } + } + // End canonicity check + let start_time_diff = decode_compact_width_be(start_time_diff_compact_width, producer).await?; @@ -1265,44 +1337,115 @@ pub(super) mod encoding { } .ok_or(DecodeError::InvalidInput)?; - let end_time_diff = - decode_compact_width_be(end_time_diff_compact_width, producer).await?; + // Canonicity check for start time + match reference.times().end { + RangeEnd::Closed(ref_time_end) => { + let start_to_start = time_start.abs_diff(reference.times().start); + let start_to_end = time_start.abs_diff(ref_time_end); + + let expected_is_start_rel_to_start = start_to_start <= start_to_end; + + if expected_is_start_rel_to_start != is_time_start_rel_to_start { + return Err(DecodeError::InvalidInput); + } + + let expected_add_or_subtract_start_time_diff = is_time_start_rel_to_start + && time_start >= reference.times().start + || !expected_is_start_rel_to_start && time_start >= ref_time_end; + + if expected_add_or_subtract_start_time_diff != add_or_subtract_start_time_diff { + return Err(DecodeError::InvalidInput); + } + } + RangeEnd::Open => { + if !is_time_start_rel_to_start { + return Err(DecodeError::InvalidInput); + } + + // I need to very add or subtract time diff here. + let expected_add_or_subtract_time_diff = time_start >= reference.times().start; + + if expected_add_or_subtract_time_diff != add_or_subtract_start_time_diff { + return Err(DecodeError::InvalidInput); + } + } + } + // End of canonicity check for start time let time_end = if is_times_end_open { + if add_or_subtract_end_time_diff { + return Err(DecodeError::InvalidInput); + } + + if is_time_end_rel_to_start { + return Err(DecodeError::InvalidInput); + } + + let end_time_diff_compact_width_flags = 0b0000_0011; + if header_2 & end_time_diff_compact_width_flags != 0b0000_0000 { + return Err(DecodeError::InvalidInput); + } + RangeEnd::Open } else { - match (is_times_end_rel_to_start, add_or_subtract_end_time_diff) { - (true, true) => RangeEnd::Closed( - reference - .times() - .start + let end_time_diff = + decode_compact_width_be(end_time_diff_compact_width, producer).await?; + + let time_end = match (is_time_end_rel_to_start, add_or_subtract_end_time_diff) { + (true, true) => reference + .times() + .start + .checked_add(end_time_diff) + .ok_or(DecodeError::InvalidInput)?, + + (true, false) => reference + .times() + .start + .checked_sub(end_time_diff) + .ok_or(DecodeError::InvalidInput)?, + + (false, true) => match reference.times().end { + RangeEnd::Closed(ref_end) => ref_end .checked_add(end_time_diff) .ok_or(DecodeError::InvalidInput)?, - ), - (true, false) => RangeEnd::Closed( - reference - .times() - .start - .checked_sub(end_time_diff) - .ok_or(DecodeError::InvalidInput)?, - ), - (false, true) => match reference.times().end { - RangeEnd::Closed(ref_end) => RangeEnd::Closed( - ref_end - .checked_add(end_time_diff) - .ok_or(DecodeError::InvalidInput)?, - ), + RangeEnd::Open => Err(DecodeError::InvalidInput)?, }, (false, false) => match reference.times().end { - RangeEnd::Closed(ref_end) => RangeEnd::Closed( - ref_end - .checked_sub(end_time_diff) - .ok_or(DecodeError::InvalidInput)?, - ), + RangeEnd::Closed(ref_end) => ref_end + .checked_sub(end_time_diff) + .ok_or(DecodeError::InvalidInput)?, + RangeEnd::Open => Err(DecodeError::InvalidInput)?, }, + }; + + let end_to_start = time_end.abs_diff(reference.times().start); + let end_to_end = match &reference.times().end { + RangeEnd::Closed(ref_end) => time_end.abs_diff(*ref_end), + RangeEnd::Open => u64::MAX, + }; + + let expected_is_time_end_rel_to_start = end_to_start <= end_to_end; + if expected_is_time_end_rel_to_start != is_time_end_rel_to_start { + return Err(DecodeError::InvalidInput); + } + + let expected_end_time_diff = core::cmp::min(end_to_start, end_to_end); + + if expected_end_time_diff != end_time_diff { + return Err(DecodeError::InvalidInput); } + + let expected_add_or_subtract_end_time_diff = (is_time_end_rel_to_start + && time_end >= reference.times().start) + || (!is_time_end_rel_to_start && time_end >= reference.times().end); + + if expected_add_or_subtract_end_time_diff != add_or_subtract_end_time_diff { + return Err(DecodeError::InvalidInput); + } + + RangeEnd::Closed(time_end) }; Ok(Self::new( diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 1dbe6f5..9f49ba6 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -319,8 +319,8 @@ doc = false bench = false [[bin]] -name = "range3d_rel_rang3d_encoding_random" -path = "fuzz_targets/range3d_rel_rang3d_encoding_random.rs" +name = "range3d_rel_range3d_encoding_random" +path = "fuzz_targets/range3d_rel_range3d_encoding_random.rs" test = false doc = false bench = false diff --git a/fuzz/fuzz_targets/range3d_rel_rang3d_encoding_random.rs b/fuzz/fuzz_targets/range3d_rel_range3d_encoding_random.rs similarity index 100% rename from fuzz/fuzz_targets/range3d_rel_rang3d_encoding_random.rs rename to fuzz/fuzz_targets/range3d_rel_range3d_encoding_random.rs From 5d0e17e580d97278c30b026de5cde55ffe57fa33 Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Fri, 13 Sep 2024 10:59:17 +0100 Subject: [PATCH 08/18] Add command for running all fuzz tests --- README.md | 16 +++++++++++++++ fuzz/run_all.sh | 6 ++++++ fuzz/targets.txt | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100755 fuzz/run_all.sh create mode 100644 fuzz/targets.txt diff --git a/README.md b/README.md index bd71961..263e914 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,22 @@ the repo's issues, milestones, and projects. protocol. - [meadowcap-js](https://github.com/earthstar-project/meadowcap-js) - TypeScript implementation of Meadowcap + +## Fuzz tests + +This repository has many fuzz tests. To use `cargo fuzz` commands, you must first make `fuzz` the working directory so that the nightly compiler (on which cargo-fuzz relies) is used for compiling the tests. + +``` +cd fuzz +cargo fuzz run +``` + +There is also a command for running all the fuzz tests sequentially: + +``` +cd fuzz +./run_all.sh -- -max_total_time= +``` --- diff --git a/fuzz/run_all.sh b/fuzz/run_all.sh new file mode 100755 index 0000000..daf7749 --- /dev/null +++ b/fuzz/run_all.sh @@ -0,0 +1,6 @@ +#!/bin/sh +[ -e targets.txt ] || cargo fuzz list > targets.txt +i=1; N="$(cat targets.txt | wc -l)" +while cargo fuzz run "$(head -n$i targets.txt | tail -n1)" "$@"; do + i=$(( i % N + 1 )) +done \ No newline at end of file diff --git a/fuzz/targets.txt b/fuzz/targets.txt new file mode 100644 index 0000000..95bf128 --- /dev/null +++ b/fuzz/targets.txt @@ -0,0 +1,51 @@ +area_rel_area_encoding +area_rel_area_encoding_random +entry_encoding +entry_encoding_random +entry_rel_entry_encoding +entry_rel_entry_encoding_random +entry_rel_namespace_area_encoding +entry_rel_namespace_area_encoding_random +entry_rel_namespace_range_encoding +entry_rel_namespace_range_encoding_random +mc_capability_append_delegation +mc_capability_delegation +mc_capability_rel_area_encoding +mc_capability_rel_area_encoding_random +mc_is_authorised_write +mc_subspace_capability_append_delegation +mc_subspace_capability_delegation +mc_subspace_capability_encoding +mc_subspace_capability_encoding_random +path +path2 +path3 +path4 +path_encoding +path_encoding2 +path_encoding3 +path_encoding_random +path_encoding_random2 +path_encoding_random3 +path_rel_path_encoding +path_rel_path_encoding2 +path_rel_path_encoding3 +path_rel_path_encoding_random +path_rel_path_encoding_random2 +path_rel_path_encoding_random3 +path_successor +path_successor_even_more +path_successor_more +range3d_rel_range3d_encoding +range3d_rel_range3d_encoding_random +successor_of_prefix +successor_of_prefix_even_more +successor_of_prefix_more +u16be_encoding +u16be_encoding_random +u32be_encoding +u32be_encoding_random +u64be_encoding +u64be_encoding_random +u8be_encoding +u8be_encoding_random From 0cb70d2247bd12c302861195ef9770e28fb4123c Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Fri, 13 Sep 2024 11:46:23 +0100 Subject: [PATCH 09/18] entry <> entry relation decoding --- data-model/src/relative_encodings.rs | 68 +++++++++++++++++++++++++++- encoding/src/compact_width.rs | 3 +- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/data-model/src/relative_encodings.rs b/data-model/src/relative_encodings.rs index 64739ec..0127d53 100644 --- a/data-model/src/relative_encodings.rs +++ b/data-model/src/relative_encodings.rs @@ -16,8 +16,10 @@ pub(super) mod encoding { #[syncify_replace(use willow_encoding::sync::{decode_max_power, encode_max_power};)] use willow_encoding::{decode_max_power, encode_max_power}; - #[syncify_replace(use willow_encoding::sync::{ decode_compact_width_be, encode_compact_width_be};)] - use willow_encoding::{decode_compact_width_be, encode_compact_width_be}; + #[syncify_replace(use willow_encoding::sync::{ decode_compact_width_be, decode_compact_width_be_relation,encode_compact_width_be};)] + use willow_encoding::{ + decode_compact_width_be, decode_compact_width_be_relation, encode_compact_width_be, + }; #[syncify_replace(use willow_encoding::sync::produce_byte;)] use willow_encoding::produce_byte; @@ -330,6 +332,68 @@ pub(super) mod encoding { payload_digest, )) } + + async fn relative_decode_relation( + reference: &Entry, + producer: &mut Producer, + ) -> Result, DecodeError> + where + Producer: BulkProducer, + Self: Sized, + { + let header = produce_byte(producer).await?; + + let is_namespace_encoded = is_bitflagged(header, 0); + let is_subspace_encoded = is_bitflagged(header, 1); + let add_or_subtract_time_diff = is_bitflagged(header, 2); + let compact_width_time_diff = CompactWidth::decode_fixed_width_bitmask(header, 4); + let compact_width_payload_length = CompactWidth::decode_fixed_width_bitmask(header, 6); + + let namespace_id = if is_namespace_encoded { + N::decode_relation(producer).await? + } else { + reference.namespace_id().clone() + }; + + let subspace_id = if is_subspace_encoded { + S::decode_relation(producer).await? + } else { + reference.subspace_id().clone() + }; + + let path = + Path::::relative_decode_relation(reference.path(), producer).await?; + + let time_diff = + decode_compact_width_be_relation(compact_width_time_diff, producer).await?; + + // Add or subtract safely here to avoid overflows caused by malicious or faulty encodings. + let timestamp = if add_or_subtract_time_diff { + reference + .timestamp() + .checked_add(time_diff) + .ok_or(DecodeError::InvalidInput)? + } else { + reference + .timestamp() + .checked_sub(time_diff) + .ok_or(DecodeError::InvalidInput)? + }; + + let payload_length = + decode_compact_width_be_relation(compact_width_payload_length, producer).await?; + + let payload_digest = PD::decode_relation(producer).await?; + + Ok(Entry::new( + namespace_id, + subspace_id, + path, + timestamp, + payload_length, + payload_digest, + )) + } } impl diff --git a/encoding/src/compact_width.rs b/encoding/src/compact_width.rs index 4e57560..0baa470 100644 --- a/encoding/src/compact_width.rs +++ b/encoding/src/compact_width.rs @@ -149,7 +149,7 @@ pub mod encoding { } /// Decodes the bytes representing a [`CompactWidth`]-bytes integer into a `usize` as encoding relation. - pub async fn decode_relation_compact_width_be>( + pub async fn decode_compact_width_be_relation>( compact_width: CompactWidth, producer: &mut Producer, ) -> Result> { @@ -164,6 +164,7 @@ pub mod encoding { } /// Decodes the bytes representing a [`CompactWidth`]-bytes integer into a `usize`. + /// /// Will fail if the decoded value could have been encoded with a smaller [`CompactWidth`]. pub async fn decode_compact_width_be>( compact_width: CompactWidth, From 1d5c8358bc19bc8c8c5c884b3aef842eab91316e Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Fri, 13 Sep 2024 12:05:58 +0100 Subject: [PATCH 10/18] Entry <> Namespace + Area relation encoding --- data-model/src/relative_encodings.rs | 77 ++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/data-model/src/relative_encodings.rs b/data-model/src/relative_encodings.rs index 0127d53..2123e91 100644 --- a/data-model/src/relative_encodings.rs +++ b/data-model/src/relative_encodings.rs @@ -544,6 +544,83 @@ pub(super) mod encoding { payload_digest, )) } + + /// Decodes an [`Entry`] relative to a reference [`NamespaceId`] and [`Area`]. + /// + /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_entry_in_namespace_area). + async fn relative_decode_relation( + reference: &(N, Area), + producer: &mut Producer, + ) -> Result> + where + Producer: BulkProducer, + Self: Sized, + { + let (namespace, out) = reference; + + let header = produce_byte(producer).await?; + + let is_subspace_encoded = is_bitflagged(header, 0); + let add_time_diff_to_start = is_bitflagged(header, 1); + let time_diff_compact_width = CompactWidth::decode_fixed_width_bitmask(header, 2); + let payload_length_compact_width = CompactWidth::decode_fixed_width_bitmask(header, 4); + + let subspace_id = match &out.subspace() { + AreaSubspace::Any => { + if !is_subspace_encoded { + return Err(DecodeError::InvalidInput); + } + + S::decode_relation(producer).await? + } + AreaSubspace::Id(out_subspace) => { + if !is_subspace_encoded { + out_subspace.clone() + } else { + let subspace_id = S::decode_relation(producer).await?; + + if &subspace_id != out_subspace { + return Err(DecodeError::InvalidInput); + } + + subspace_id + } + } + }; + + let path = Path::relative_decode_relation(out.path(), producer).await?; + + if !path.is_prefixed_by(out.path()) { + return Err(DecodeError::InvalidInput); + } + + let time_diff = + decode_compact_width_be_relation(time_diff_compact_width, producer).await?; + let payload_length = + decode_compact_width_be_relation(payload_length_compact_width, producer).await?; + + let payload_digest = PD::decode_relation(producer).await?; + + let timestamp = if add_time_diff_to_start { + out.times().start.checked_add(time_diff) + } else { + u64::from(&out.times().end).checked_sub(time_diff) + } + .ok_or(DecodeError::InvalidInput)?; + + if !out.times().includes(×tamp) { + return Err(DecodeError::InvalidInput); + } + + Ok(Self::new( + namespace.clone(), + subspace_id, + path, + timestamp, + payload_length, + payload_digest, + )) + } } impl From ab63936375b45a84bb02ed1dd5dedecb49c0d11c Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Fri, 13 Sep 2024 12:09:13 +0100 Subject: [PATCH 11/18] Small docs update. --- data-model/src/relative_encodings.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/data-model/src/relative_encodings.rs b/data-model/src/relative_encodings.rs index 2123e91..4aea4cd 100644 --- a/data-model/src/relative_encodings.rs +++ b/data-model/src/relative_encodings.rs @@ -248,6 +248,8 @@ pub(super) mod encoding { { /// Decodes an [`Entry`] relative to the given reference [`Entry`]. /// + /// Will return an error if the encoding has not been produced by the corresponding encoding function. + /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_etry_relative_entry). async fn relative_decode_canonical( reference: &Entry, @@ -333,6 +335,9 @@ pub(super) mod encoding { )) } + /// Decodes an [`Entry`] relative to the given reference [`Entry`]. + /// + /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_etry_relative_entry). async fn relative_decode_relation( reference: &Entry, producer: &mut Producer, @@ -405,6 +410,8 @@ pub(super) mod encoding { { /// Encodes this [`Entry`] relative to a reference [`NamespaceId`] and [`Area`]. /// + /// Will return an error if the encoding has not been produced by the corresponding encoding function. + /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_entry_in_namespace_area). async fn relative_encode( &self, From 2434143872f090083ee36da17c9bf25ab26baa13 Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Fri, 13 Sep 2024 12:19:35 +0100 Subject: [PATCH 12/18] Entry <> Namespace + Range3d relation encoding --- data-model/src/relative_encodings.rs | 93 +++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/data-model/src/relative_encodings.rs b/data-model/src/relative_encodings.rs index 4aea4cd..ee1ea61 100644 --- a/data-model/src/relative_encodings.rs +++ b/data-model/src/relative_encodings.rs @@ -410,8 +410,6 @@ pub(super) mod encoding { { /// Encodes this [`Entry`] relative to a reference [`NamespaceId`] and [`Area`]. /// - /// Will return an error if the encoding has not been produced by the corresponding encoding function. - /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_entry_in_namespace_area). async fn relative_encode( &self, @@ -475,6 +473,8 @@ pub(super) mod encoding { { /// Decodes an [`Entry`] relative to a reference [`NamespaceId`] and [`Area`]. /// + /// Will return an error if the encoding has not been produced by the corresponding encoding function. + /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_entry_in_namespace_area). async fn relative_decode_canonical( reference: &(N, Area), @@ -740,6 +740,8 @@ pub(super) mod encoding { { /// Decodes an [`Entry`] relative to a reference [`NamespaceId`] and [`Range3d`]. /// + /// Will return an error if the encoding has not been produced by the corresponding encoding function. + /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_entry_in_namespace_3drange). async fn relative_decode_canonical( reference: &(N, Range3d), @@ -870,6 +872,93 @@ pub(super) mod encoding { payload_digest, )) } + + /// Decodes an [`Entry`] relative to a reference [`NamespaceId`] and [`Range3d`]. + /// + /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_entry_in_namespace_3drange). + async fn relative_decode_relation( + reference: &(N, Range3d), + producer: &mut Producer, + ) -> Result> + where + Producer: BulkProducer, + Self: Sized, + { + let (namespace, out) = reference; + + let header = produce_byte(producer).await?; + + // Decode e.get_subspace_id()? + let is_subspace_encoded = is_bitflagged(header, 0); + + // Decode e.get_path() relative to out.get_paths().start or to out.get_paths().end? + let decode_path_relative_to_start = is_bitflagged(header, 1); + + // Add time_diff to out.get_times().start, or subtract from out.get_times().end? + let add_time_diff_with_start = is_bitflagged(header, 2); + + let time_diff_compact_width = CompactWidth::decode_fixed_width_bitmask(header, 4); + let payload_length_compact_width = CompactWidth::decode_fixed_width_bitmask(header, 6); + + let subspace_id = if is_subspace_encoded { + S::decode_relation(producer).await? + } else { + out.subspaces().start.clone() + }; + + // Verify that subspace is included by range + if !out.subspaces().includes(&subspace_id) { + return Err(DecodeError::InvalidInput); + } + + let path = if decode_path_relative_to_start { + Path::relative_decode_relation(&out.paths().start, producer).await? + } else { + match &out.paths().end { + RangeEnd::Closed(end_path) => { + Path::relative_decode_relation(end_path, producer).await? + } + RangeEnd::Open => return Err(DecodeError::InvalidInput), + } + }; + + // Verify that path is included by range + if !out.paths().includes(&path) { + return Err(DecodeError::InvalidInput); + } + + let time_diff = + decode_compact_width_be_relation(time_diff_compact_width, producer).await?; + + let payload_length = + decode_compact_width_be_relation(payload_length_compact_width, producer).await?; + + let payload_digest = PD::decode_relation(producer).await?; + + let timestamp = if add_time_diff_with_start { + out.times().start.checked_add(time_diff) + } else { + match &out.times().end { + RangeEnd::Closed(end_time) => end_time.checked_sub(time_diff), + RangeEnd::Open => u64::from(&out.times().end).checked_sub(time_diff), + } + } + .ok_or(DecodeError::InvalidInput)?; + + // Verify that timestamp is included by range + if !out.times().includes(×tamp) { + return Err(DecodeError::InvalidInput); + } + + Ok(Self::new( + namespace.clone(), + subspace_id, + path, + timestamp, + payload_length, + payload_digest, + )) + } } impl From 44a7e160e95494362387d0b49d370fb1e7e837fb Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Fri, 13 Sep 2024 12:34:47 +0100 Subject: [PATCH 13/18] Area <> Area relation decoding --- data-model/src/relative_encodings.rs | 120 +++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/data-model/src/relative_encodings.rs b/data-model/src/relative_encodings.rs index ee1ea61..db5b54a 100644 --- a/data-model/src/relative_encodings.rs +++ b/data-model/src/relative_encodings.rs @@ -1048,6 +1048,8 @@ pub(super) mod encoding { { /// Decodes an [`Area`] relative to another [`Area`] which [includes](https://willowprotocol.org/specs/grouping-entries/index.html#area_include_area) it. /// + /// Will return an error if the encoding has not been produced by the corresponding encoding function. + /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_area_in_area). async fn relative_decode_canonical( out: &Area, @@ -1207,6 +1209,124 @@ pub(super) mod encoding { Ok(Self::new(subspace, path, times)) } + + /// Decodes an [`Area`] relative to another [`Area`] which [includes](https://willowprotocol.org/specs/grouping-entries/index.html#area_include_area) it. + /// + /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_area_in_area). + async fn relative_decode_relation( + out: &Area, + producer: &mut Producer, + ) -> Result> + where + Producer: BulkProducer, + Self: Sized, + { + let header = produce_byte(producer).await?; + + // Decode subspace? + let is_subspace_encoded = is_bitflagged(header, 0); + + // Decode end value of times? + let is_times_end_open = is_bitflagged(header, 1); + + // Add start_diff to out.get_times().start, or subtract from out.get_times().end? + let add_start_diff = is_bitflagged(header, 2); + + // Add end_diff to out.get_times().start, or subtract from out.get_times().end? + let add_end_diff = is_bitflagged(header, 3); + + let start_diff_compact_width = CompactWidth::decode_fixed_width_bitmask(header, 4); + let end_diff_compact_width = CompactWidth::decode_fixed_width_bitmask(header, 6); + + let subspace = if is_subspace_encoded { + let id = S::decode_relation(producer).await?; + AreaSubspace::Id(id) + } else { + out.subspace().clone() + }; + + // Verify that the decoded subspace is included by the reference subspace + match (&out.subspace(), &subspace) { + (AreaSubspace::Any, AreaSubspace::Any) => {} + (AreaSubspace::Any, AreaSubspace::Id(_)) => {} + (AreaSubspace::Id(_), AreaSubspace::Any) => { + return Err(DecodeError::InvalidInput); + } + (AreaSubspace::Id(a), AreaSubspace::Id(b)) => { + if a != b { + return Err(DecodeError::InvalidInput); + } + } + } + + let path = Path::relative_decode_relation(out.path(), producer).await?; + + // Verify the decoded path is prefixed by the reference path + if !path.is_prefixed_by(out.path()) { + return Err(DecodeError::InvalidInput); + } + + let start_diff = + decode_compact_width_be_relation(start_diff_compact_width, producer).await?; + + let start = if add_start_diff { + out.times().start.checked_add(start_diff) + } else { + u64::from(&out.times().end).checked_sub(start_diff) + } + .ok_or(DecodeError::InvalidInput)?; + + // Verify they sent correct start diff + let expected_start_diff = core::cmp::min( + start.checked_sub(out.times().start), + u64::from(&out.times().end).checked_sub(start), + ) + .ok_or(DecodeError::InvalidInput)?; + + if expected_start_diff != start_diff { + return Err(DecodeError::InvalidInput); + } + + let end = if is_times_end_open { + if add_end_diff { + return Err(DecodeError::InvalidInput); + } + + RangeEnd::Open + } else { + let end_diff = + decode_compact_width_be_relation(end_diff_compact_width, producer).await?; + + let end = if add_end_diff { + out.times().start.checked_add(end_diff) + } else { + u64::from(&out.times().end).checked_sub(end_diff) + } + .ok_or(DecodeError::InvalidInput)?; + + // Verify they sent correct end diff + let expected_end_diff = core::cmp::min( + end.checked_sub(out.times().start), + u64::from(&out.times().end).checked_sub(end), + ) + .ok_or(DecodeError::InvalidInput)?; + + if end_diff != expected_end_diff { + return Err(DecodeError::InvalidInput); + } + + RangeEnd::Closed(end) + }; + + let times = Range { start, end }; + + // Verify the decoded time range is included by the reference time range + if !out.times().includes_range(×) { + return Err(DecodeError::InvalidInput); + } + + Ok(Self::new(subspace, path, times)) + } } impl From d4b9f49591782b5837aa69378a196bcc839a9510 Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Fri, 13 Sep 2024 12:49:52 +0100 Subject: [PATCH 14/18] Range3d <> Range3d relation decoding --- data-model/src/relative_encodings.rs | 154 +++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/data-model/src/relative_encodings.rs b/data-model/src/relative_encodings.rs index db5b54a..4860392 100644 --- a/data-model/src/relative_encodings.rs +++ b/data-model/src/relative_encodings.rs @@ -1530,6 +1530,8 @@ pub(super) mod encoding { { /// Decodes a [`Range3d`] relative to another [`Range3d`] which [includes](https://willowprotocol.org/specs/grouping-entries/index.html#area_include_area) it. /// + /// Will return an error if the encoding has not been produced by the corresponding encoding function. + /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_area_in_area). async fn relative_decode_canonical( reference: &Range3d, @@ -1820,5 +1822,157 @@ pub(super) mod encoding { }, )) } + + /// Decodes a [`Range3d`] relative to another [`Range3d`] which [includes](https://willowprotocol.org/specs/grouping-entries/index.html#area_include_area) it. + /// + /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_area_in_area). + async fn relative_decode_relation( + reference: &Range3d, + producer: &mut Producer, + ) -> Result> + where + Producer: BulkProducer, + Self: Sized, + { + let header_1 = produce_byte(producer).await?; + + let subspace_start_flags = header_1 & 0b1100_0000; + let subspace_end_flags = header_1 & 0b0011_0000; + let is_path_start_rel_to_start = is_bitflagged(header_1, 4); + let is_path_end_open = is_bitflagged(header_1, 5); + let is_path_end_rel_to_start = is_bitflagged(header_1, 6); + let is_times_end_open = is_bitflagged(header_1, 7); + + let header_2 = produce_byte(producer).await?; + + let is_time_start_rel_to_start = is_bitflagged(header_2, 0); + let add_or_subtract_start_time_diff = is_bitflagged(header_2, 1); + let start_time_diff_compact_width = + CompactWidth::decode_fixed_width_bitmask(header_2, 2); + let is_time_end_rel_to_start = is_bitflagged(header_2, 4); + let add_or_subtract_end_time_diff = is_bitflagged(header_2, 5); + let end_time_diff_compact_width = CompactWidth::decode_fixed_width_bitmask(header_2, 6); + + // Decode subspace start + let subspace_start = match subspace_start_flags { + 0b0100_0000 => reference.subspaces().start.clone(), + 0b1000_0000 => match &reference.subspaces().end { + RangeEnd::Closed(end) => end.clone(), + RangeEnd::Open => Err(DecodeError::InvalidInput)?, + }, + 0b1100_0000 => S::decode_canonical(producer).await?, + // This can only be b0000_0000 (which is not valid!) + _ => Err(DecodeError::InvalidInput)?, + }; + + let subspace_end = match subspace_end_flags { + 0b0000_0000 => RangeEnd::Open, + 0b0001_0000 => RangeEnd::Closed(reference.subspaces().start.clone()), + 0b0010_0000 => match &reference.subspaces().end { + RangeEnd::Closed(end) => RangeEnd::Closed(end.clone()), + RangeEnd::Open => Err(DecodeError::InvalidInput)?, + }, + // This can only be 0b0011_0000 + _ => RangeEnd::Closed(S::decode_relation(producer).await?), + }; + + let path_start = match (is_path_start_rel_to_start, &reference.paths().end) { + (true, RangeEnd::Closed(_)) => { + Path::relative_decode_relation(&reference.paths().start, producer).await? + } + (true, RangeEnd::Open) => { + Path::relative_decode_relation(&reference.paths().start, producer).await? + } + (false, RangeEnd::Closed(path_end)) => { + Path::relative_decode_relation(path_end, producer).await? + } + (false, RangeEnd::Open) => Err(DecodeError::InvalidInput)?, + }; + + let path_end = if is_path_end_open { + RangeEnd::Open + } else if is_path_end_rel_to_start { + RangeEnd::Closed( + Path::relative_decode_relation(&reference.paths().start, producer).await?, + ) + } else { + match &reference.paths().end { + RangeEnd::Closed(end) => { + RangeEnd::Closed(Path::relative_decode_relation(end, producer).await?) + } + RangeEnd::Open => Err(DecodeError::InvalidInput)?, + } + }; + + let start_time_diff = + decode_compact_width_be_relation(start_time_diff_compact_width, producer).await?; + + let time_start = match (is_time_start_rel_to_start, add_or_subtract_start_time_diff) { + (true, true) => reference.times().start.checked_add(start_time_diff), + (true, false) => reference.times().start.checked_sub(start_time_diff), + (false, true) => match reference.times().end { + RangeEnd::Closed(ref_end) => ref_end.checked_add(start_time_diff), + RangeEnd::Open => Err(DecodeError::InvalidInput)?, + }, + (false, false) => match reference.times().end { + RangeEnd::Closed(ref_end) => ref_end.checked_sub(start_time_diff), + RangeEnd::Open => Err(DecodeError::InvalidInput)?, + }, + } + .ok_or(DecodeError::InvalidInput)?; + + let time_end = if is_times_end_open { + RangeEnd::Open + } else { + let end_time_diff = + decode_compact_width_be_relation(end_time_diff_compact_width, producer).await?; + + let time_end = match (is_time_end_rel_to_start, add_or_subtract_end_time_diff) { + (true, true) => reference + .times() + .start + .checked_add(end_time_diff) + .ok_or(DecodeError::InvalidInput)?, + + (true, false) => reference + .times() + .start + .checked_sub(end_time_diff) + .ok_or(DecodeError::InvalidInput)?, + + (false, true) => match reference.times().end { + RangeEnd::Closed(ref_end) => ref_end + .checked_add(end_time_diff) + .ok_or(DecodeError::InvalidInput)?, + + RangeEnd::Open => Err(DecodeError::InvalidInput)?, + }, + (false, false) => match reference.times().end { + RangeEnd::Closed(ref_end) => ref_end + .checked_sub(end_time_diff) + .ok_or(DecodeError::InvalidInput)?, + + RangeEnd::Open => Err(DecodeError::InvalidInput)?, + }, + }; + + RangeEnd::Closed(time_end) + }; + + Ok(Self::new( + Range { + start: subspace_start, + end: subspace_end, + }, + Range { + start: path_start, + end: path_end, + }, + Range { + start: time_start, + end: time_end, + }, + )) + } } } From af48b1800783d9e04b4d08af2bd227df53d85569 Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Fri, 13 Sep 2024 13:14:09 +0100 Subject: [PATCH 15/18] Test canonical and relation decoding results against each other! --- fuzz/src/encode.rs | 76 +++++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/fuzz/src/encode.rs b/fuzz/src/encode.rs index ca391f6..c7f8399 100644 --- a/fuzz/src/encode.rs +++ b/fuzz/src/encode.rs @@ -42,11 +42,25 @@ pub fn encoding_random(data: &[u8]) where T: Encodable + Decodable + std::fmt::Debug + PartialEq + Eq, { - encoding_canonical_random::(data); - encoding_relation_random::(data); + let res_canonical = encoding_canonical_random::(data); + let res_relation = encoding_relation_random::(data); + + match (res_canonical, res_relation) { + (Some(item_a), Some(item_b)) => { + if item_a != item_b { + panic!("The canonical and relation decoders did not produce the same result!") + } + } + (Some(_), None) => { + panic!("Found an encoding produced by the encoding function but which does not belong to the encoding relation, which is impossible!") + } + _ => { + // Expected result. + } + } } -pub fn encoding_canonical_random(data: &[u8]) +pub fn encoding_canonical_random(data: &[u8]) -> Option where T: Encodable + Decodable + std::fmt::Debug, { @@ -65,21 +79,21 @@ where let encoded = consumer.as_ref(); assert_eq!(encoded, &data[0..producer.get_offset()]); + + Some(item) } Err(err) => match err { // There was an error. DecodeError::Producer(_) => panic!("Returned producer error, when whe shouldn't!"), - DecodeError::InvalidInput => { - // GOOD. - } + DecodeError::InvalidInput => None, DecodeError::U64DoesNotFitUsize => { panic!("Returned u64DoesNotFitUsize error, when we shouldn't!") } }, - }; + } } -pub fn encoding_relation_random(data: &[u8]) +pub fn encoding_relation_random(data: &[u8]) -> Option where T: Encodable + Decodable + std::fmt::Debug + PartialEq + Eq, { @@ -106,18 +120,18 @@ where panic!("Could not decode again, argh!") } } + + Some(item) } Err(err) => match err { // There was an error. DecodeError::Producer(_) => panic!("Returned producer error, when whe shouldn't!"), - DecodeError::InvalidInput => { - // GOOD. - } + DecodeError::InvalidInput => None, DecodeError::U64DoesNotFitUsize => { panic!("Returned u64DoesNotFitUsize error, when we shouldn't!") } }, - }; + } } pub fn relative_encoding_canonical_roundtrip( @@ -158,11 +172,25 @@ where T: RelativeEncodable + RelativeDecodable + std::fmt::Debug + Eq, R: std::fmt::Debug, { - relative_encoding_canonical_random::(reference, data); - relative_encoding_relation_random::(reference, data); + let res_canonical = relative_encoding_canonical_random::(reference, data); + let res_relation = relative_encoding_relation_random::(reference, data); + + match (res_canonical, res_relation) { + (Some(item_a), Some(item_b)) => { + if item_a != item_b { + panic!("The canonical and relation decoders did not produce the same result!") + } + } + (Some(_), None) => { + panic!("Found an encoding produced by the encoding function but which does not belong to the encoding relation, which is impossible!") + } + _ => { + // Expected result. + } + } } -pub fn relative_encoding_canonical_random(reference: &R, data: &[u8]) +pub fn relative_encoding_canonical_random(reference: &R, data: &[u8]) -> Option where T: RelativeEncodable + RelativeDecodable + std::fmt::Debug, R: std::fmt::Debug, @@ -183,21 +211,21 @@ where let encoded = consumer.as_ref(); assert_eq!(encoded, &data[0..producer.get_offset()]); + + Some(item) } Err(err) => match err { // There was an error. DecodeError::Producer(_) => panic!("Returned producer error, when whe shouldn't!"), - DecodeError::InvalidInput => { - // GOOD. - } + DecodeError::InvalidInput => None, DecodeError::U64DoesNotFitUsize => { panic!("Returned u64DoesNotFitUsize error, when we shouldn't!") } }, - }; + } } -pub fn relative_encoding_relation_random(reference: &R, data: &[u8]) +pub fn relative_encoding_relation_random(reference: &R, data: &[u8]) -> Option where T: RelativeEncodable + RelativeDecodable + std::fmt::Debug + Eq, R: std::fmt::Debug, @@ -226,16 +254,16 @@ where panic!("Could not decode again, argh!") } } + + Some(item) } Err(err) => match err { // There was an error. DecodeError::Producer(_) => panic!("Returned producer error, when whe shouldn't!"), - DecodeError::InvalidInput => { - // GOOD. - } + DecodeError::InvalidInput => None, DecodeError::U64DoesNotFitUsize => { panic!("Returned u64DoesNotFitUsize error, when we shouldn't!") } }, - }; + } } From d15b46d2ea2ff481e8d39d3302fd75cd382f6f05 Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Fri, 13 Sep 2024 15:15:46 +0100 Subject: [PATCH 16/18] Fix fuzz test compilation error --- fuzz/fuzz_targets/mc_subspace_capability_encoding_random.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuzz/fuzz_targets/mc_subspace_capability_encoding_random.rs b/fuzz/fuzz_targets/mc_subspace_capability_encoding_random.rs index 72c0d28..2a9f214 100644 --- a/fuzz/fuzz_targets/mc_subspace_capability_encoding_random.rs +++ b/fuzz/fuzz_targets/mc_subspace_capability_encoding_random.rs @@ -8,5 +8,5 @@ use willow_fuzz::silly_sigs::{SillyPublicKey, SillySig}; fuzz_target!(|data: &[u8]| { encoding_canonical_random::< McSubspaceCapability, - >(data) + >(data); }); From 1acf04611f8f16374d5acfd907e98b36b4c650c4 Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Mon, 16 Sep 2024 11:34:06 +0100 Subject: [PATCH 17/18] Break out relation decoding into own trait --- data-model/src/path.rs | 14 +++--- data-model/src/relative_encodings.rs | 48 ++++++++++++++++++- earthstar/src/identity_id.rs | 6 ++- earthstar/src/namespace_id.rs | 8 ++-- encoding/src/traits.rs | 10 ++++ encoding/src/traits_sync.rs | 10 ++++ .../mc_capability_rel_area_encoding_random.rs | 6 +-- fuzz/src/encode.rs | 6 +-- fuzz/src/placeholder_params.rs | 11 ++++- fuzz/src/silly_sigs.rs | 8 +++- 10 files changed, 102 insertions(+), 25 deletions(-) diff --git a/data-model/src/path.rs b/data-model/src/path.rs index bf490c3..2fdd86e 100644 --- a/data-model/src/path.rs +++ b/data-model/src/path.rs @@ -791,8 +791,8 @@ mod encoding { use ufotofu::local_nb::{BulkConsumer, BulkProducer}; use willow_encoding::DecodeError; - #[syncify_replace(use willow_encoding::sync::{Decodable, Encodable};)] - use willow_encoding::{Decodable, Encodable}; + #[syncify_replace(use willow_encoding::sync::{Decodable, Encodable, RelationDecodable};)] + use willow_encoding::{Decodable, Encodable, RelationDecodable}; #[syncify_replace(use willow_encoding::sync::{decode_max_power, encode_max_power};)] use willow_encoding::{decode_max_power, encode_max_power}; @@ -854,13 +854,11 @@ mod encoding { Ok(unsafe { buf.to_path(component_count) }) } + } - async fn decode_relation

(producer: &mut P) -> Result> - where - P: BulkProducer, - { - Self::decode_canonical(producer).await - } + impl RelationDecodable + for Path + { } } diff --git a/data-model/src/relative_encodings.rs b/data-model/src/relative_encodings.rs index 4860392..e92e175 100644 --- a/data-model/src/relative_encodings.rs +++ b/data-model/src/relative_encodings.rs @@ -10,8 +10,11 @@ pub(super) mod encoding { use ufotofu::local_nb::{BulkConsumer, BulkProducer}; use willow_encoding::{is_bitflagged, CompactWidth, DecodeError}; - #[syncify_replace(use willow_encoding::sync::{Encodable, Decodable, RelativeDecodable, RelativeEncodable};)] - use willow_encoding::{Decodable, Encodable, RelativeDecodable, RelativeEncodable}; + #[syncify_replace(use willow_encoding::sync::{Encodable, Decodable, RelativeDecodable, RelativeEncodable, RelationDecodable, RelativeRelationDecodable};)] + use willow_encoding::{ + Decodable, Encodable, RelationDecodable, RelativeDecodable, RelativeEncodable, + RelativeRelationDecodable, + }; #[syncify_replace(use willow_encoding::sync::{decode_max_power, encode_max_power};)] use willow_encoding::{decode_max_power, encode_max_power}; @@ -175,6 +178,11 @@ pub(super) mod encoding { } } + impl + RelativeRelationDecodable> for Path + { + } + // Entry <> Entry impl @@ -334,7 +342,15 @@ pub(super) mod encoding { payload_digest, )) } + } + impl + RelativeRelationDecodable> for Entry + where + N: NamespaceId + RelationDecodable + std::fmt::Debug, + S: SubspaceId + RelationDecodable + std::fmt::Debug, + PD: PayloadDigest + RelationDecodable, + { /// Decodes an [`Entry`] relative to the given reference [`Entry`]. /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_etry_relative_entry). @@ -551,7 +567,15 @@ pub(super) mod encoding { payload_digest, )) } + } + impl + RelativeRelationDecodable<(N, Area)> for Entry + where + N: NamespaceId + RelationDecodable, + S: SubspaceId + RelationDecodable + std::fmt::Debug, + PD: PayloadDigest + RelationDecodable, + { /// Decodes an [`Entry`] relative to a reference [`NamespaceId`] and [`Area`]. /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_entry_in_namespace_area). @@ -872,7 +896,15 @@ pub(super) mod encoding { payload_digest, )) } + } + impl + RelativeRelationDecodable<(N, Range3d)> for Entry + where + N: NamespaceId + RelationDecodable, + S: SubspaceId + RelationDecodable + std::fmt::Debug, + PD: PayloadDigest + RelationDecodable, + { /// Decodes an [`Entry`] relative to a reference [`NamespaceId`] and [`Range3d`]. /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_entry_in_namespace_3drange). @@ -1209,7 +1241,13 @@ pub(super) mod encoding { Ok(Self::new(subspace, path, times)) } + } + impl + RelativeRelationDecodable> for Area + where + S: SubspaceId + RelationDecodable, + { /// Decodes an [`Area`] relative to another [`Area`] which [includes](https://willowprotocol.org/specs/grouping-entries/index.html#area_include_area) it. /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_area_in_area). @@ -1822,7 +1860,13 @@ pub(super) mod encoding { }, )) } + } + impl + RelativeRelationDecodable> for Range3d + where + S: SubspaceId + RelationDecodable + std::fmt::Debug, + { /// Decodes a [`Range3d`] relative to another [`Range3d`] which [includes](https://willowprotocol.org/specs/grouping-entries/index.html#area_include_area) it. /// /// [Definition](https://willowprotocol.org/specs/encodings/index.html#enc_area_in_area). diff --git a/earthstar/src/identity_id.rs b/earthstar/src/identity_id.rs index aede138..7c9c501 100644 --- a/earthstar/src/identity_id.rs +++ b/earthstar/src/identity_id.rs @@ -24,8 +24,8 @@ pub(super) mod encoding { #[syncify_replace(use ufotofu::sync::{BulkConsumer, BulkProducer};)] use ufotofu::local_nb::{BulkConsumer, BulkProducer}; use willow_encoding::DecodeError; - #[syncify_replace(use willow_encoding::sync::{Encodable, Decodable};)] - use willow_encoding::{Decodable, Encodable}; + #[syncify_replace(use willow_encoding::sync::{Encodable, Decodable, RelationDecodable};)] + use willow_encoding::{Decodable, Encodable, RelationDecodable}; impl Encodable for IdentityIdentifier { async fn encode(&self, consumer: &mut C) -> Result<(), C::Error> @@ -48,6 +48,8 @@ pub(super) mod encoding { } } } + + impl RelationDecodable for IdentityIdentifier {} } impl SubspaceId for IdentityIdentifier { diff --git a/earthstar/src/namespace_id.rs b/earthstar/src/namespace_id.rs index 7c8a309..23b58c4 100644 --- a/earthstar/src/namespace_id.rs +++ b/earthstar/src/namespace_id.rs @@ -26,8 +26,8 @@ pub(super) mod encoding { #[syncify_replace(use ufotofu::sync::{BulkConsumer, BulkProducer};)] use ufotofu::local_nb::{BulkConsumer, BulkProducer}; use willow_encoding::DecodeError; - #[syncify_replace(use willow_encoding::sync::{Encodable, Decodable};)] - use willow_encoding::{Decodable, Encodable}; + #[syncify_replace(use willow_encoding::sync::{Encodable, Decodable, RelationDecodable};)] + use willow_encoding::{Decodable, Encodable, RelationDecodable}; impl Encodable for NamespaceIdentifier { async fn encode(&self, consumer: &mut C) -> Result<(), C::Error> @@ -40,7 +40,7 @@ pub(super) mod encoding { } impl Decodable for NamespaceIdentifier { - async fn decode_canonical

(producer: &mut P) -> Result::Error>> + async fn decode_canonical

(producer: &mut P) -> Result> where P: BulkProducer, { @@ -50,6 +50,8 @@ pub(super) mod encoding { } } } + + impl RelationDecodable for NamespaceIdentifier {} } impl NamespaceId for NamespaceIdentifier {} diff --git a/encoding/src/traits.rs b/encoding/src/traits.rs index 049795e..f9e9771 100644 --- a/encoding/src/traits.rs +++ b/encoding/src/traits.rs @@ -40,7 +40,12 @@ pub trait Decodable { where Producer: BulkProducer, Self: Sized; +} +/// A type which can be asynchronously decoded from bytes produced by a [`ufotofu::local_nb::BulkProducer`] +/// +/// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) +pub trait RelationDecodable: Decodable { /// Decode a bytestring belonging to the **encoding relation** on the set of `Self` and the set of bytestrings, such that: /// /// - for every `s` in `Self`, there is at least one bytestring in relation with `s`, and @@ -97,7 +102,12 @@ pub trait RelativeDecodable { where Producer: BulkProducer, Self: Sized; +} +/// A type relative to a value of type `R` which can be asynchronously decoded from bytes (belonging to an encoding relation) produced by a [`ufotofu::local_nb::BulkProducer`] +/// +/// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) +pub trait RelativeRelationDecodable: RelativeDecodable { /// Decode a bytestring belonging to the **encoding relation** on the set of `Self` relative to a value of the set of `R`, and the set of bytestrings, such that: /// /// - for every pair of `s` in `Self` and `r` in `R`, there is at least one bytestring in relation with the pair of `s` and `r`, and diff --git a/encoding/src/traits_sync.rs b/encoding/src/traits_sync.rs index 1317f5d..08fcd6a 100644 --- a/encoding/src/traits_sync.rs +++ b/encoding/src/traits_sync.rs @@ -35,7 +35,12 @@ pub trait Decodable { where Producer: BulkProducer, Self: Sized; +} +/// A type which can be decoded from bytes (belonging to an encoding relation) produced by a [`ufotofu::local_nb::BulkProducer`] +/// +/// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) +pub trait RelationDecodable: Decodable { /// Decode a bytestring belonging to the **encoding relation** on the set of `Self` and the set of bytestrings, such that: /// /// - for every `s` in `Self`, there is at least one bytestring in relation with `s`, and @@ -92,7 +97,12 @@ pub trait RelativeDecodable { where Producer: BulkProducer, Self: Sized; +} +/// A type relative to a value of type `R` which can be decoded from bytes (belonging to an encoding relation) produced by a [`ufotofu::local_nb::BulkProducer`] +/// +/// [Definition](https://willowprotocol.org/specs/encodings/index.html#encodings_what) +pub trait RelativeRelationDecodable: RelativeDecodable { /// Decode a bytestring belonging to the **encoding relation** on the set of `Self` relative to a value of the set of `R`, and the set of bytestrings, such that: /// /// - for every pair of `s` in `Self` and `r` in `R`, there is at least one bytestring in relation with the pair of `s` and `r`, and diff --git a/fuzz/fuzz_targets/mc_capability_rel_area_encoding_random.rs b/fuzz/fuzz_targets/mc_capability_rel_area_encoding_random.rs index 2929927..d0cd633 100644 --- a/fuzz/fuzz_targets/mc_capability_rel_area_encoding_random.rs +++ b/fuzz/fuzz_targets/mc_capability_rel_area_encoding_random.rs @@ -3,14 +3,14 @@ use libfuzzer_sys::fuzz_target; use meadowcap::McCapability; use willow_data_model::grouping::Area; -use willow_fuzz::encode::relative_encoding_random; +use willow_fuzz::encode::relative_encoding_canonical_random; use willow_fuzz::silly_sigs::{SillyPublicKey, SillySig}; fuzz_target!(|data: (&[u8], Area<3, 3, 3, SillyPublicKey>,)| { let (random_bytes, out) = data; - relative_encoding_random::< + relative_encoding_canonical_random::< Area<3, 3, 3, SillyPublicKey>, McCapability<3, 3, 3, SillyPublicKey, SillySig, SillyPublicKey, SillySig>, - >(&out, random_bytes) + >(&out, random_bytes); }); diff --git a/fuzz/src/encode.rs b/fuzz/src/encode.rs index c7f8399..15ae568 100644 --- a/fuzz/src/encode.rs +++ b/fuzz/src/encode.rs @@ -8,7 +8,7 @@ use ufotofu::{ }; use willow_encoding::{ - sync::{Decodable, Encodable, RelativeDecodable, RelativeEncodable}, + sync::{Decodable, Encodable, RelativeDecodable, RelativeEncodable, RelativeRelationDecodable}, DecodeError, }; @@ -169,7 +169,7 @@ pub fn relative_encoding_canonical_roundtrip( pub fn relative_encoding_random(reference: &R, data: &[u8]) where - T: RelativeEncodable + RelativeDecodable + std::fmt::Debug + Eq, + T: RelativeEncodable + RelativeRelationDecodable + std::fmt::Debug + Eq, R: std::fmt::Debug, { let res_canonical = relative_encoding_canonical_random::(reference, data); @@ -227,7 +227,7 @@ where pub fn relative_encoding_relation_random(reference: &R, data: &[u8]) -> Option where - T: RelativeEncodable + RelativeDecodable + std::fmt::Debug + Eq, + T: RelativeEncodable + RelativeRelationDecodable + std::fmt::Debug + Eq, R: std::fmt::Debug, { let mut producer = FromSlice::new(data); diff --git a/fuzz/src/placeholder_params.rs b/fuzz/src/placeholder_params.rs index 1e84369..d1b1278 100644 --- a/fuzz/src/placeholder_params.rs +++ b/fuzz/src/placeholder_params.rs @@ -3,8 +3,11 @@ use ufotofu::local_nb::{BulkConsumer, BulkProducer}; use ufotofu::sync::{BulkConsumer as BulkConsumerSync, BulkProducer as BulkProducerSync}; use willow_data_model::PayloadDigest; use willow_encoding::{ - sync::{Decodable as DecodableSync, Encodable as EncodableSync}, - Decodable, DecodeError, Encodable, + sync::{ + Decodable as DecodableSync, Encodable as EncodableSync, + RelationDecodable as RelationDecodableSync, + }, + Decodable, DecodeError, Encodable, RelationDecodable, }; #[derive(Arbitrary, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)] @@ -63,4 +66,8 @@ impl DecodableSync for FakePayloadDigest { } } +impl RelationDecodable for FakePayloadDigest {} + +impl RelationDecodableSync for FakePayloadDigest {} + impl PayloadDigest for FakePayloadDigest {} diff --git a/fuzz/src/silly_sigs.rs b/fuzz/src/silly_sigs.rs index 9fb32f5..aed8be1 100644 --- a/fuzz/src/silly_sigs.rs +++ b/fuzz/src/silly_sigs.rs @@ -84,8 +84,8 @@ pub mod encoding { use ufotofu::local_nb::{BulkConsumer, BulkProducer}; use willow_encoding::DecodeError; - #[syncify_replace(use willow_encoding::sync::{Encodable, Decodable};)] - use willow_encoding::{Decodable, Encodable}; + #[syncify_replace(use willow_encoding::sync::{Encodable, Decodable, RelationDecodable};)] + use willow_encoding::{Decodable, Encodable, RelationDecodable}; #[syncify_replace(use willow_encoding::sync::produce_byte;)] use willow_encoding::produce_byte; @@ -137,4 +137,8 @@ pub mod encoding { Ok(SillySig(num)) } } + + impl RelationDecodable for SillyPublicKey {} + + impl RelationDecodable for SillySig {} } From 7ea01ff84322d154e8965fa7b463eb0be633351a Mon Sep 17 00:00:00 2001 From: Sam Gwilym Date: Mon, 16 Sep 2024 12:12:34 +0100 Subject: [PATCH 18/18] Remove RelativeRelationDecodable for Path --- data-model/src/relative_encodings.rs | 27 ++++++++----------- .../path_rel_path_encoding_random.rs | 7 +++-- .../path_rel_path_encoding_random2.rs | 7 +++-- .../path_rel_path_encoding_random3.rs | 7 +++-- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/data-model/src/relative_encodings.rs b/data-model/src/relative_encodings.rs index e92e175..92bd4ce 100644 --- a/data-model/src/relative_encodings.rs +++ b/data-model/src/relative_encodings.rs @@ -178,11 +178,6 @@ pub(super) mod encoding { } } - impl - RelativeRelationDecodable> for Path - { - } - // Entry <> Entry impl @@ -382,8 +377,8 @@ pub(super) mod encoding { reference.subspace_id().clone() }; - let path = - Path::::relative_decode_relation(reference.path(), producer).await?; + let path = Path::::relative_decode_canonical(reference.path(), producer) + .await?; let time_diff = decode_compact_width_be_relation(compact_width_time_diff, producer).await?; @@ -619,7 +614,7 @@ pub(super) mod encoding { } }; - let path = Path::relative_decode_relation(out.path(), producer).await?; + let path = Path::relative_decode_canonical(out.path(), producer).await?; if !path.is_prefixed_by(out.path()) { return Err(DecodeError::InvalidInput); @@ -944,11 +939,11 @@ pub(super) mod encoding { } let path = if decode_path_relative_to_start { - Path::relative_decode_relation(&out.paths().start, producer).await? + Path::relative_decode_canonical(&out.paths().start, producer).await? } else { match &out.paths().end { RangeEnd::Closed(end_path) => { - Path::relative_decode_relation(end_path, producer).await? + Path::relative_decode_canonical(end_path, producer).await? } RangeEnd::Open => return Err(DecodeError::InvalidInput), } @@ -1297,7 +1292,7 @@ pub(super) mod encoding { } } - let path = Path::relative_decode_relation(out.path(), producer).await?; + let path = Path::relative_decode_canonical(out.path(), producer).await?; // Verify the decoded path is prefixed by the reference path if !path.is_prefixed_by(out.path()) { @@ -1922,13 +1917,13 @@ pub(super) mod encoding { let path_start = match (is_path_start_rel_to_start, &reference.paths().end) { (true, RangeEnd::Closed(_)) => { - Path::relative_decode_relation(&reference.paths().start, producer).await? + Path::relative_decode_canonical(&reference.paths().start, producer).await? } (true, RangeEnd::Open) => { - Path::relative_decode_relation(&reference.paths().start, producer).await? + Path::relative_decode_canonical(&reference.paths().start, producer).await? } (false, RangeEnd::Closed(path_end)) => { - Path::relative_decode_relation(path_end, producer).await? + Path::relative_decode_canonical(path_end, producer).await? } (false, RangeEnd::Open) => Err(DecodeError::InvalidInput)?, }; @@ -1937,12 +1932,12 @@ pub(super) mod encoding { RangeEnd::Open } else if is_path_end_rel_to_start { RangeEnd::Closed( - Path::relative_decode_relation(&reference.paths().start, producer).await?, + Path::relative_decode_canonical(&reference.paths().start, producer).await?, ) } else { match &reference.paths().end { RangeEnd::Closed(end) => { - RangeEnd::Closed(Path::relative_decode_relation(end, producer).await?) + RangeEnd::Closed(Path::relative_decode_canonical(end, producer).await?) } RangeEnd::Open => Err(DecodeError::InvalidInput)?, } diff --git a/fuzz/fuzz_targets/path_rel_path_encoding_random.rs b/fuzz/fuzz_targets/path_rel_path_encoding_random.rs index 644aeda..6d33408 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding_random.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding_random.rs @@ -2,7 +2,7 @@ use libfuzzer_sys::fuzz_target; use willow_data_model::Path; -use willow_fuzz::encode::relative_encoding_random; +use willow_fuzz::encode::relative_encoding_canonical_random; const MCL: usize = 300; const MCC: usize = 300; @@ -11,5 +11,8 @@ const MPL: usize = 300; fuzz_target!(|data: (&[u8], Path)| { let (random_bytes, ref_path) = data; - relative_encoding_random::, Path>(&ref_path, random_bytes) + relative_encoding_canonical_random::, Path>( + &ref_path, + random_bytes, + ); }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding_random2.rs b/fuzz/fuzz_targets/path_rel_path_encoding_random2.rs index 16d6e70..202157b 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding_random2.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding_random2.rs @@ -2,7 +2,7 @@ use libfuzzer_sys::fuzz_target; use willow_data_model::Path; -use willow_fuzz::encode::relative_encoding_random; +use willow_fuzz::encode::relative_encoding_canonical_random; const MCL: usize = 2; const MCC: usize = 3; @@ -11,5 +11,8 @@ const MPL: usize = 3; fuzz_target!(|data: (&[u8], Path)| { let (random_bytes, ref_path) = data; - relative_encoding_random::, Path>(&ref_path, random_bytes) + relative_encoding_canonical_random::, Path>( + &ref_path, + random_bytes, + ); }); diff --git a/fuzz/fuzz_targets/path_rel_path_encoding_random3.rs b/fuzz/fuzz_targets/path_rel_path_encoding_random3.rs index 4275232..1676e5a 100644 --- a/fuzz/fuzz_targets/path_rel_path_encoding_random3.rs +++ b/fuzz/fuzz_targets/path_rel_path_encoding_random3.rs @@ -2,7 +2,7 @@ use libfuzzer_sys::fuzz_target; use willow_data_model::Path; -use willow_fuzz::encode::relative_encoding_random; +use willow_fuzz::encode::relative_encoding_canonical_random; const MCL: usize = 4; const MCC: usize = 4; @@ -11,5 +11,8 @@ const MPL: usize = 16; fuzz_target!(|data: (&[u8], Path)| { let (random_bytes, ref_path) = data; - relative_encoding_random::, Path>(&ref_path, random_bytes) + relative_encoding_canonical_random::, Path>( + &ref_path, + random_bytes, + ); });