snarkvm_synthesizer_program/closure/
bytes.rs1use super::*;
17
18impl<N: Network> FromBytes for ClosureCore<N> {
19 #[inline]
21 fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
22 let name = Identifier::<N>::read_le(&mut reader)?;
24
25 let num_inputs = u16::read_le(&mut reader)?;
27 if num_inputs.is_zero() {
28 return Err(error("Failed to deserialize a closure: needs at least one input".to_string()));
29 }
30 if num_inputs > u16::try_from(N::MAX_INPUTS).map_err(error)? {
31 return Err(error(format!("Failed to deserialize a closure: too many inputs ({num_inputs})")));
32 }
33 let mut inputs = Vec::with_capacity(num_inputs as usize);
34 for _ in 0..num_inputs {
35 inputs.push(Input::read_le(&mut reader)?);
36 }
37
38 let num_instructions = u32::read_le(&mut reader)?;
40 if num_instructions.is_zero() {
41 return Err(error("Failed to deserialize a closure: needs at least one instruction".to_string()));
42 }
43 if num_instructions > u32::try_from(N::MAX_INSTRUCTIONS).map_err(error)? {
44 return Err(error(format!("Failed to deserialize a closure: too many instructions ({num_instructions})")));
45 }
46 let mut instructions = Vec::with_capacity((num_instructions as usize).min(1024));
49 for _ in 0..num_instructions {
50 instructions.push(Instruction::read_le(&mut reader)?);
51 }
52
53 let num_outputs = u16::read_le(&mut reader)?;
55 if num_outputs > u16::try_from(N::MAX_OUTPUTS).map_err(error)? {
56 return Err(error(format!("Failed to deserialize a closure: too many outputs ({num_outputs})")));
57 }
58 let mut outputs = Vec::with_capacity(num_outputs as usize);
59 for _ in 0..num_outputs {
60 outputs.push(Output::read_le(&mut reader)?);
61 }
62
63 let mut closure = Self::new(name);
65 inputs.into_iter().try_for_each(|input| closure.add_input(input)).map_err(error)?;
66 instructions.into_iter().try_for_each(|instruction| closure.add_instruction(instruction)).map_err(error)?;
67 outputs.into_iter().try_for_each(|output| closure.add_output(output)).map_err(error)?;
68
69 Ok(closure)
70 }
71}
72
73impl<N: Network> ToBytes for ClosureCore<N> {
74 #[inline]
76 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
77 self.name.write_le(&mut writer)?;
79
80 let num_inputs = self.inputs.len();
82 match 0 < num_inputs && num_inputs <= N::MAX_INPUTS {
83 true => u16::try_from(num_inputs).map_err(error)?.write_le(&mut writer)?,
84 false => return Err(error(format!("Failed to write {num_inputs} inputs as bytes"))),
85 }
86
87 for input in self.inputs.iter() {
89 input.write_le(&mut writer)?;
90 }
91
92 let num_instructions = self.instructions.len();
94 match 0 < num_instructions && num_instructions <= N::MAX_INSTRUCTIONS {
95 true => u32::try_from(num_instructions).map_err(error)?.write_le(&mut writer)?,
96 false => return Err(error(format!("Failed to write {num_instructions} instructions as bytes"))),
97 }
98
99 for instruction in self.instructions.iter() {
101 instruction.write_le(&mut writer)?;
102 }
103
104 let num_outputs = self.outputs.len();
106 match num_outputs <= N::MAX_OUTPUTS {
107 true => u16::try_from(num_outputs).map_err(error)?.write_le(&mut writer)?,
108 false => return Err(error(format!("Failed to write {num_outputs} outputs as bytes"))),
109 }
110
111 for output in self.outputs.iter() {
113 output.write_le(&mut writer)?;
114 }
115
116 Ok(())
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123 use crate::Closure;
124 use console::network::MainnetV0;
125
126 type CurrentNetwork = MainnetV0;
127
128 #[test]
129 fn test_closure_bytes() -> Result<()> {
130 let closure_string = r"
131closure main:
132 input r0 as field;
133 input r1 as field;
134 add r0 r1 into r2;
135 add r0 r1 into r3;
136 add r0 r1 into r4;
137 add r0 r1 into r5;
138 add r0 r1 into r6;
139 add r0 r1 into r7;
140 add r0 r1 into r8;
141 add r0 r1 into r9;
142 add r0 r1 into r10;
143 add r0 r1 into r11;
144 output r11 as field;";
145
146 let expected = Closure::<CurrentNetwork>::from_str(closure_string)?;
147 let expected_bytes = expected.to_bytes_le()?;
148 println!("String size: {:?}, Bytecode size: {:?}", closure_string.len(), expected_bytes.len());
149
150 let candidate = Closure::<CurrentNetwork>::from_bytes_le(&expected_bytes)?;
151 assert_eq!(expected.to_string(), candidate.to_string());
152 assert_eq!(expected_bytes, candidate.to_bytes_le()?);
153 Ok(())
154 }
155}