snarkvm_synthesizer_program/closure/
bytes.rs1use super::*;
17
18impl<N: Network, Instruction: InstructionTrait<N>> FromBytes for ClosureCore<N, Instruction> {
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);
47 for _ in 0..num_instructions {
48 instructions.push(Instruction::read_le(&mut reader)?);
49 }
50
51 let num_outputs = u16::read_le(&mut reader)?;
53 if num_outputs > u16::try_from(N::MAX_OUTPUTS).map_err(error)? {
54 return Err(error(format!("Failed to deserialize a closure: too many outputs ({num_outputs})")));
55 }
56 let mut outputs = Vec::with_capacity(num_outputs as usize);
57 for _ in 0..num_outputs {
58 outputs.push(Output::read_le(&mut reader)?);
59 }
60
61 let mut closure = Self::new(name);
63 inputs.into_iter().try_for_each(|input| closure.add_input(input)).map_err(error)?;
64 instructions.into_iter().try_for_each(|instruction| closure.add_instruction(instruction)).map_err(error)?;
65 outputs.into_iter().try_for_each(|output| closure.add_output(output)).map_err(error)?;
66
67 Ok(closure)
68 }
69}
70
71impl<N: Network, Instruction: InstructionTrait<N>> ToBytes for ClosureCore<N, Instruction> {
72 #[inline]
74 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
75 self.name.write_le(&mut writer)?;
77
78 let num_inputs = self.inputs.len();
80 match 0 < num_inputs && num_inputs <= N::MAX_INPUTS {
81 true => u16::try_from(num_inputs).map_err(error)?.write_le(&mut writer)?,
82 false => return Err(error(format!("Failed to write {num_inputs} inputs as bytes"))),
83 }
84
85 for input in self.inputs.iter() {
87 input.write_le(&mut writer)?;
88 }
89
90 let num_instructions = self.instructions.len();
92 match 0 < num_instructions && num_instructions <= N::MAX_INSTRUCTIONS {
93 true => u32::try_from(num_instructions).map_err(error)?.write_le(&mut writer)?,
94 false => return Err(error(format!("Failed to write {num_instructions} instructions as bytes"))),
95 }
96
97 for instruction in self.instructions.iter() {
99 instruction.write_le(&mut writer)?;
100 }
101
102 let num_outputs = self.outputs.len();
104 match num_outputs <= N::MAX_OUTPUTS {
105 true => u16::try_from(num_outputs).map_err(error)?.write_le(&mut writer)?,
106 false => return Err(error(format!("Failed to write {num_outputs} outputs as bytes"))),
107 }
108
109 for output in self.outputs.iter() {
111 output.write_le(&mut writer)?;
112 }
113
114 Ok(())
115 }
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121 use crate::Closure;
122 use console::network::MainnetV0;
123
124 type CurrentNetwork = MainnetV0;
125
126 #[test]
127 fn test_closure_bytes() -> Result<()> {
128 let closure_string = r"
129closure main:
130 input r0 as field;
131 input r1 as field;
132 add r0 r1 into r2;
133 add r0 r1 into r3;
134 add r0 r1 into r4;
135 add r0 r1 into r5;
136 add r0 r1 into r6;
137 add r0 r1 into r7;
138 add r0 r1 into r8;
139 add r0 r1 into r9;
140 add r0 r1 into r10;
141 add r0 r1 into r11;
142 output r11 as field;";
143
144 let expected = Closure::<CurrentNetwork>::from_str(closure_string)?;
145 let expected_bytes = expected.to_bytes_le()?;
146 println!("String size: {:?}, Bytecode size: {:?}", closure_string.as_bytes().len(), expected_bytes.len());
147
148 let candidate = Closure::<CurrentNetwork>::from_bytes_le(&expected_bytes)?;
149 assert_eq!(expected.to_string(), candidate.to_string());
150 assert_eq!(expected_bytes, candidate.to_bytes_le()?);
151 Ok(())
152 }
153}