snarkvm_synthesizer/restrictions/
serialize.rs1use super::*;
17
18use snarkvm_utilities::DeserializeExt;
19
20impl<N: Network + Serialize> Serialize for Restrictions<N> {
21 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
22 where
23 S: Serializer,
24 {
25 let mut state = serializer.serialize_struct("Restrictions", 4)?;
26 state.serialize_field("restrictions_id", &self.restrictions_id)?;
27 state.serialize_field("programs", &self.programs)?;
28 state.serialize_field("functions", &self.functions)?;
29 state.serialize_field("arguments", &self.arguments)?;
30 state.end()
31 }
32}
33
34impl<'de, N: Network> Deserialize<'de> for Restrictions<N> {
35 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
37 let mut restrictions = serde_json::Value::deserialize(deserializer)?;
38
39 Ok(Self {
41 restrictions_id: DeserializeExt::take_from_value::<D>(&mut restrictions, "restrictions_id")?,
42 programs: DeserializeExt::take_from_value::<D>(&mut restrictions, "programs")?,
43 functions: DeserializeExt::take_from_value::<D>(&mut restrictions, "functions")?,
44 arguments: DeserializeExt::take_from_value::<D>(&mut restrictions, "arguments")?,
45 })
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52 use console::types::Address;
53
54 use rand::seq::SliceRandom;
55
56 type CurrentNetwork = console::network::MainnetV0;
57
58 const ITERATIONS: usize = 100;
59
60 const TEST_PROGRAM_CASES: &[&str] = &["testing.aleo", "hello.aleo", "abc_def.aleo", "a1234.aleo"];
61 const TEST_FUNCTION_CASES: &[&str] = &["testing", "transfer", "hello", "foo", "bar"];
62
63 fn sample_program_id<R: Rng + CryptoRng>(rng: &mut R) -> ProgramID<CurrentNetwork> {
65 ProgramID::from_str(TEST_PROGRAM_CASES.choose(rng).unwrap()).unwrap()
66 }
67
68 fn sample_locator<R: Rng + CryptoRng>(rng: &mut R) -> Locator<CurrentNetwork> {
70 let program_id = ProgramID::from_str(TEST_PROGRAM_CASES.choose(rng).unwrap()).unwrap();
71 let function_name = Identifier::from_str(TEST_FUNCTION_CASES.choose(rng).unwrap()).unwrap();
72 Locator::new(program_id, function_name)
73 }
74
75 fn sample_block_range<R: Rng + CryptoRng>(rng: &mut R) -> BlockRange {
77 let variant = rng.gen_range(0..5);
78 match variant {
79 0 => {
80 let start = rng.r#gen();
81 let end = rng.gen_range(start..=u32::MAX);
82 BlockRange::Range(start..end)
83 }
84 1 => BlockRange::RangeFrom(rng.r#gen()..),
85 2 => BlockRange::RangeTo(..rng.r#gen()),
86 3 => {
87 let start = rng.r#gen();
88 let end = rng.gen_range(start..=u32::MAX);
89 BlockRange::RangeInclusive(start..=end)
90 }
91 4 => BlockRange::FullRange,
92 _ => unreachable!(),
93 }
94 }
95
96 fn sample_restrictions<R: Rng + CryptoRng>(rng: &mut R) -> Restrictions<CurrentNetwork> {
98 const NUM_RESTRICTIONS: usize = 10;
99
100 let mut restrictions = Restrictions::<CurrentNetwork>::new_blank().unwrap();
101 for _ in 0..NUM_RESTRICTIONS {
103 let program_id = sample_program_id(rng);
104 let range = sample_block_range(rng);
105 restrictions.programs.insert(program_id, range);
106 }
107 for _ in 0..NUM_RESTRICTIONS {
109 let locator = sample_locator(rng);
110 let range = sample_block_range(rng);
111 restrictions.functions.insert(locator, range);
112 }
113 for _ in 0..NUM_RESTRICTIONS {
115 let locator = sample_locator(rng);
116
117 let mut arguments = IndexMap::new();
119 for _ in 0..NUM_RESTRICTIONS {
120 let argument_locator = ArgumentLocator::new(rng.r#gen(), rng.gen_range(0..16));
121
122 let mut literals = IndexMap::new();
124 for _ in 0..NUM_RESTRICTIONS {
125 let literal = Literal::Address(Address::rand(rng));
126 let range = sample_block_range(rng);
127 literals.insert(literal, range);
128 }
129 arguments.insert(argument_locator, literals);
130 }
131 restrictions.arguments.insert(locator, arguments);
132 }
133 restrictions.restrictions_id = Restrictions::compute_restrictions_id(
135 &restrictions.programs,
136 &restrictions.functions,
137 &restrictions.arguments,
138 )
139 .unwrap();
140 restrictions
142 }
143
144 fn check_serde_json<T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr>(
145 expected: T,
146 ) {
147 let expected_string = expected.to_string();
149 let candidate_string = serde_json::to_string_pretty(&expected).unwrap();
150 let candidate = serde_json::from_str::<T>(&candidate_string).unwrap();
151 assert_eq!(expected, candidate);
152 assert_eq!(expected_string, candidate_string);
153 assert_eq!(expected_string, candidate.to_string());
154
155 assert_eq!(expected, T::from_str(&expected_string).unwrap_or_else(|_| panic!("FromStr: {expected_string}")));
157 assert_eq!(expected, serde_json::from_str(&candidate_string).unwrap());
158 }
159
160 #[test]
161 fn test_serde_json() {
162 let rng = &mut TestRng::default();
163
164 for _ in 0..ITERATIONS {
165 let expected = sample_restrictions(rng);
166 check_serde_json(expected);
167 }
168 }
169}