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