snarkvm_synthesizer_program/function/
bytes.rs1use super::*;
17
18impl<N: Network> FromBytes for FunctionCore<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 > u16::try_from(N::MAX_INPUTS).map_err(error)? {
28 return Err(error(format!("Failed to deserialize a function: too many inputs ({num_inputs})")));
29 }
30 let mut inputs = Vec::with_capacity(num_inputs as usize);
31 for _ in 0..num_inputs {
32 inputs.push(Input::read_le(&mut reader)?);
33 }
34
35 let num_instructions = u32::read_le(&mut reader)?;
37 if num_instructions > u32::try_from(N::MAX_INSTRUCTIONS).map_err(error)? {
38 return Err(error(format!("Failed to deserialize a function: too many instructions ({num_instructions})")));
39 }
40 let mut instructions = Vec::with_capacity(num_instructions as usize);
41 for _ in 0..num_instructions {
42 instructions.push(Instruction::read_le(&mut reader)?);
43 }
44
45 let num_outputs = u16::read_le(&mut reader)?;
47 if num_outputs > u16::try_from(N::MAX_OUTPUTS).map_err(error)? {
48 return Err(error(format!("Failed to deserialize a function: too many outputs ({num_outputs})")));
49 }
50 let mut outputs = Vec::with_capacity(num_outputs as usize);
51 for _ in 0..num_outputs {
52 outputs.push(Output::read_le(&mut reader)?);
53 }
54
55 let variant = u8::read_le(&mut reader)?;
57 let finalize = match variant {
58 0 => None,
59 1 => Some(FinalizeCore::read_le(&mut reader)?),
60 _ => return Err(error(format!("Failed to deserialize a function: invalid finalize variant ({variant})"))),
61 };
62
63 let mut function = Self::new(name);
65 inputs.into_iter().try_for_each(|input| function.add_input(input)).map_err(error)?;
66 instructions.into_iter().try_for_each(|instruction| function.add_instruction(instruction)).map_err(error)?;
67 outputs.into_iter().try_for_each(|output| function.add_output(output)).map_err(error)?;
68 finalize.map(|finalize| function.add_finalize(finalize));
69
70 Ok(function)
71 }
72}
73
74impl<N: Network> ToBytes for FunctionCore<N> {
75 #[inline]
77 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
78 self.name.write_le(&mut writer)?;
80
81 let num_inputs = self.inputs.len();
83 match num_inputs <= N::MAX_INPUTS {
84 true => u16::try_from(num_inputs).map_err(error)?.write_le(&mut writer)?,
85 false => return Err(error(format!("Failed to write {num_inputs} inputs as bytes"))),
86 }
87
88 for input in self.inputs.iter() {
90 input.write_le(&mut writer)?;
91 }
92
93 let num_instructions = self.instructions.len();
95 match num_instructions <= N::MAX_INSTRUCTIONS {
96 true => u32::try_from(num_instructions).map_err(error)?.write_le(&mut writer)?,
97 false => return Err(error(format!("Failed to write {num_instructions} instructions as bytes"))),
98 }
99
100 for instruction in self.instructions.iter() {
102 instruction.write_le(&mut writer)?;
103 }
104
105 let num_outputs = self.outputs.len();
107 match num_outputs <= N::MAX_OUTPUTS {
108 true => u16::try_from(num_outputs).map_err(error)?.write_le(&mut writer)?,
109 false => return Err(error(format!("Failed to write {num_outputs} outputs as bytes"))),
110 }
111
112 for output in self.outputs.iter() {
114 output.write_le(&mut writer)?;
115 }
116
117 match &self.finalize_logic {
119 None => 0u8.write_le(&mut writer)?,
120 Some(logic) => {
121 1u8.write_le(&mut writer)?;
122 logic.write_le(&mut writer)?;
124 }
125 }
126
127 Ok(())
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134 use crate::Function;
135 use console::network::MainnetV0;
136
137 type CurrentNetwork = MainnetV0;
138
139 #[test]
140 fn test_function_bytes() -> Result<()> {
141 let function_string = r"
142function main:
143 input r0 as field.public;
144 input r1 as field.private;
145 add r0 r1 into r2;
146 add r0 r1 into r3;
147 add r0 r1 into r4;
148 add r0 r1 into r5;
149 add r0 r1 into r6;
150 add r0 r1 into r7;
151 add r0 r1 into r8;
152 add r0 r1 into r9;
153 add r0 r1 into r10;
154 add r0 r1 into r11;
155 output r11 as field.private;";
156
157 let expected = Function::<CurrentNetwork>::from_str(function_string)?;
158 let expected_bytes = expected.to_bytes_le()?;
159 println!("String size: {:?}, Bytecode size: {:?}", function_string.len(), expected_bytes.len());
160
161 let candidate = Function::<CurrentNetwork>::from_bytes_le(&expected_bytes)?;
162 assert_eq!(expected.to_string(), candidate.to_string());
163 assert_eq!(expected_bytes, candidate.to_bytes_le()?);
164 Ok(())
165 }
166}