diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b77c7568..82804b9e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,12 +1,10 @@ CODEOWNERS @brunoffranca /node/actors/consensus/ @brunoffranca @moshababo -/node/actors/executor/ @brunoffranca @pompon0 @slowli /node/actors/network/ @pompon0 /node/actors/sync_blocks/ @slowli /node/libs/concurrency/ @pompon0 /node/libs/crypto/ @brunoffranca /node/libs/protobuf/ @pompon0 -/node/libs/protobuf_build/ @pompon0 -/node/libs/storage/ @slowli \ No newline at end of file +/node/libs/protobuf_build/ @pompon0 \ No newline at end of file diff --git a/node/libs/protobuf/src/lib.rs b/node/libs/protobuf/src/lib.rs index 49958df5..2ad12b50 100644 --- a/node/libs/protobuf/src/lib.rs +++ b/node/libs/protobuf/src/lib.rs @@ -5,6 +5,8 @@ pub mod build; pub mod proto; mod proto_fmt; +pub mod repr; +pub use repr::{read_required_repr, ProtoRepr}; pub mod serde; mod std_conv; pub mod testonly; diff --git a/node/libs/protobuf/src/repr.rs b/node/libs/protobuf/src/repr.rs new file mode 100644 index 00000000..e8659715 --- /dev/null +++ b/node/libs/protobuf/src/repr.rs @@ -0,0 +1,33 @@ +//! Trait for defining proto conversion for external types. + +use crate::build::prost_reflect::ReflectMessage; +use anyhow::Context as _; + +/// Trait reverse to `zksync_protobuf::ProtoFmt` for cases where +/// you would like to specify a custom proto encoding for an externally defined type. +pub trait ProtoRepr: ReflectMessage + Default { + /// The externally defined type associated with the proto Self. + type Type; + /// Converts proto Self to `Type`. + fn read(&self) -> anyhow::Result; + /// Converts `Type` to proto Self. + fn build(this: &Self::Type) -> Self; +} + +/// Parses a required proto field. +pub fn read_required_repr(field: &Option

) -> anyhow::Result { + field.as_ref().context("missing field")?.read() +} + +/// Encodes a proto message. +/// Currently it outputs a canonical encoding, but `decode` accepts +/// non-canonical encoding as well. +pub fn encode(msg: &P::Type) -> Vec { + let msg = P::build(msg); + super::canonical_raw(&msg.encode_to_vec(), &msg.descriptor()).unwrap() +} + +/// Decodes a proto message. +pub fn decode(bytes: &[u8]) -> anyhow::Result { + P::read(&P::decode(bytes)?) +} diff --git a/node/libs/protobuf/src/testonly/gen_value.rs b/node/libs/protobuf/src/testonly/gen_value.rs new file mode 100644 index 00000000..4c091e37 --- /dev/null +++ b/node/libs/protobuf/src/testonly/gen_value.rs @@ -0,0 +1,27 @@ +//! Util types for generating random values in tests. + +use rand::Rng; + +/// Generator of random values. +pub struct GenValue<'a, R: Rng> { + /// Underlying RNG. + pub rng: &'a mut R, + /// Generate values with only required fields. + pub required_only: bool, + /// Generate decimal fractions for f64 + /// to avoid rounding errors of decimal encodings. + pub decimal_fractions: bool, +} + +impl<'a, R: Rng> GenValue<'a, R> { + /// Generates a random value of type `C`. + pub fn gen(&mut self) -> C { + C::sample(self) + } +} + +/// Types that can be used to generate a random instance. +pub trait RandomValue { + /// Generates a random value. + fn sample(g: &mut GenValue) -> Self; +} diff --git a/node/libs/protobuf/src/testonly.rs b/node/libs/protobuf/src/testonly/mod.rs similarity index 98% rename from node/libs/protobuf/src/testonly.rs rename to node/libs/protobuf/src/testonly/mod.rs index bae47cf0..e86a6479 100644 --- a/node/libs/protobuf/src/testonly.rs +++ b/node/libs/protobuf/src/testonly/mod.rs @@ -1,5 +1,8 @@ //! Testonly utilities. + +pub mod gen_value; use super::{canonical, canonical_raw, decode, encode, read_fields, ProtoFmt, Wire}; +pub use gen_value::*; use prost::Message as _; use prost_reflect::ReflectMessage as _; use rand::{