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 ClosureCore<N> { 19 /// Reads the closure from a buffer. 20 #[inline] 21 fn read_le<R: Read>(mut reader: R) -> IoResult<Self> { 22 // Read the closure 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.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 // Read the instructions. 39 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 // Read the outputs. 52 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 // Initialize a new closure. 62 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 71 impl<N: Network> ToBytes for ClosureCore<N> { 72 /// Writes the closure to a buffer. 73 #[inline] 74 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> { 75 // Write the closure name. 76 self.name.write_le(&mut writer)?; 77 78 // Write the number of inputs for the closure. 79 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 // Write the inputs. 86 for input in self.inputs.iter() { 87 input.write_le(&mut writer)?; 88 } 89 90 // Write the number of instructions for the closure. 91 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 // Write the instructions. 98 for instruction in self.instructions.iter() { 99 instruction.write_le(&mut writer)?; 100 } 101 102 // Write the number of outputs for the closure. 103 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 // Write the outputs. 110 for output in self.outputs.iter() { 111 output.write_le(&mut writer)?; 112 } 113 114 Ok(()) 115 } 116 } 117 118 #[cfg(test)] 119 mod 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" 129 closure 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.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 }