bytes.rs
1 // Copyright (c) 2019-2025 Alpha-Delta Network Inc. 2 // This file is part of the deltavm library. 3 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 8 // http://www.apache.org/licenses/LICENSE-2.0 9 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 use super::*; 17 18 impl<N: Network> FromBytes for FunctionCore<N> { 19 /// Reads the function from a buffer. 20 #[inline] 21 fn read_le<R: Read>(mut reader: R) -> IoResult<Self> { 22 // Read the function name. 23 let name = Identifier::<N>::read_le(&mut reader)?; 24 25 // Read the inputs. 26 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 // Read the instructions. 36 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 // Read the outputs. 46 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 // Determine if there is a finalize scope. 56 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 // Initialize a new function. 64 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 74 impl<N: Network> ToBytes for FunctionCore<N> { 75 /// Writes the function to a buffer. 76 #[inline] 77 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> { 78 // Write the function name. 79 self.name.write_le(&mut writer)?; 80 81 // Write the number of inputs for the function. 82 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 // Write the inputs. 89 for input in self.inputs.iter() { 90 input.write_le(&mut writer)?; 91 } 92 93 // Write the number of instructions for the function. 94 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 // Write the instructions. 101 for instruction in self.instructions.iter() { 102 instruction.write_le(&mut writer)?; 103 } 104 105 // Write the number of outputs for the function. 106 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 // Write the outputs. 113 for output in self.outputs.iter() { 114 output.write_le(&mut writer)?; 115 } 116 117 // If the finalize scope exists, write it. 118 match &self.finalize_logic { 119 None => 0u8.write_le(&mut writer)?, 120 Some(logic) => { 121 1u8.write_le(&mut writer)?; 122 // Write the finalize scope logic. 123 logic.write_le(&mut writer)?; 124 } 125 } 126 127 Ok(()) 128 } 129 } 130 131 #[cfg(test)] 132 mod 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" 142 function 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 }