snarkvm_synthesizer/restrictions/
serialize.rsuse super::*;
use utilities::DeserializeExt;
impl<N: Network + Serialize> Serialize for Restrictions<N> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("Restrictions", 4)?;
state.serialize_field("restrictions_id", &self.restrictions_id)?;
state.serialize_field("programs", &self.programs)?;
state.serialize_field("functions", &self.functions)?;
state.serialize_field("arguments", &self.arguments)?;
state.end()
}
}
impl<'de, N: Network> Deserialize<'de> for Restrictions<N> {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let mut restrictions = serde_json::Value::deserialize(deserializer)?;
Ok(Self {
restrictions_id: DeserializeExt::take_from_value::<D>(&mut restrictions, "restrictions_id")?,
programs: DeserializeExt::take_from_value::<D>(&mut restrictions, "programs")?,
functions: DeserializeExt::take_from_value::<D>(&mut restrictions, "functions")?,
arguments: DeserializeExt::take_from_value::<D>(&mut restrictions, "arguments")?,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use console::types::Address;
use rand::seq::SliceRandom;
type CurrentNetwork = console::network::MainnetV0;
const ITERATIONS: usize = 100;
const TEST_PROGRAM_CASES: &[&str] = &["testing.aleo", "hello.aleo", "abc_def.aleo", "a1234.aleo"];
const TEST_FUNCTION_CASES: &[&str] = &["testing", "transfer", "hello", "foo", "bar"];
fn sample_program_id<R: Rng + CryptoRng>(rng: &mut R) -> ProgramID<CurrentNetwork> {
ProgramID::from_str(TEST_PROGRAM_CASES.choose(rng).unwrap()).unwrap()
}
fn sample_locator<R: Rng + CryptoRng>(rng: &mut R) -> Locator<CurrentNetwork> {
let program_id = ProgramID::from_str(TEST_PROGRAM_CASES.choose(rng).unwrap()).unwrap();
let function_name = Identifier::from_str(TEST_FUNCTION_CASES.choose(rng).unwrap()).unwrap();
Locator::new(program_id, function_name)
}
fn sample_block_range<R: Rng + CryptoRng>(rng: &mut R) -> BlockRange {
let variant = rng.gen_range(0..5);
match variant {
0 => {
let start = rng.gen();
let end = rng.gen_range(start..=u32::MAX);
BlockRange::Range(start..end)
}
1 => BlockRange::RangeFrom(rng.gen()..),
2 => BlockRange::RangeTo(..rng.gen()),
3 => {
let start = rng.gen();
let end = rng.gen_range(start..=u32::MAX);
BlockRange::RangeInclusive(start..=end)
}
4 => BlockRange::FullRange,
_ => unreachable!(),
}
}
fn sample_restrictions<R: Rng + CryptoRng>(rng: &mut R) -> Restrictions<CurrentNetwork> {
const NUM_RESTRICTIONS: usize = 10;
let mut restrictions = Restrictions::<CurrentNetwork>::new_blank().unwrap();
for _ in 0..NUM_RESTRICTIONS {
let program_id = sample_program_id(rng);
let range = sample_block_range(rng);
restrictions.programs.insert(program_id, range);
}
for _ in 0..NUM_RESTRICTIONS {
let locator = sample_locator(rng);
let range = sample_block_range(rng);
restrictions.functions.insert(locator, range);
}
for _ in 0..NUM_RESTRICTIONS {
let locator = sample_locator(rng);
let mut arguments = IndexMap::new();
for _ in 0..NUM_RESTRICTIONS {
let argument_locator = ArgumentLocator::new(rng.gen(), rng.gen_range(0..16));
let mut literals = IndexMap::new();
for _ in 0..NUM_RESTRICTIONS {
let literal = Literal::Address(Address::rand(rng));
let range = sample_block_range(rng);
literals.insert(literal, range);
}
arguments.insert(argument_locator, literals);
}
restrictions.arguments.insert(locator, arguments);
}
restrictions.restrictions_id = Restrictions::compute_restrictions_id(
&restrictions.programs,
&restrictions.functions,
&restrictions.arguments,
)
.unwrap();
restrictions
}
fn check_serde_json<T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr>(
expected: T,
) {
let expected_string = expected.to_string();
let candidate_string = serde_json::to_string_pretty(&expected).unwrap();
let candidate = serde_json::from_str::<T>(&candidate_string).unwrap();
assert_eq!(expected, candidate);
assert_eq!(expected_string, candidate_string);
assert_eq!(expected_string, candidate.to_string());
assert_eq!(expected, T::from_str(&expected_string).unwrap_or_else(|_| panic!("FromStr: {expected_string}")));
assert_eq!(expected, serde_json::from_str(&candidate_string).unwrap());
}
#[test]
fn test_serde_json() {
let rng = &mut TestRng::default();
for _ in 0..ITERATIONS {
let expected = sample_restrictions(rng);
check_serde_json(expected);
}
}
}