bytes.rs
1 // Copyright (c) 2019-2025 Alpha-Delta Network Inc. 2 // This file is part of the alphavm 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 Plaintext<N> { 19 /// Reads the plaintext from a buffer. 20 fn read_le<R: Read>(mut reader: R) -> IoResult<Self> { 21 Self::read_le_internal(&mut reader, 0) 22 } 23 } 24 25 impl<N: Network> Plaintext<N> { 26 /// Reads the plaintext from a buffer, while tracking the depth of the data. 27 fn read_le_internal<R: Read>(mut reader: R, depth: usize) -> IoResult<Self> { 28 // Ensure that the depth is within the maximum limit. 29 if depth > N::MAX_DATA_DEPTH { 30 return Err(error(format!( 31 "Failed to deserialize plaintext: Depth exceeds maximum limit: {}", 32 N::MAX_DATA_DEPTH 33 ))); 34 } 35 // Read the index. 36 let index = u8::read_le(&mut reader)?; 37 // Read the plaintext. 38 let plaintext = match index { 39 0 => Self::Literal(Literal::read_le(&mut reader)?, Default::default()), 40 1 => { 41 // Read the number of members in the struct. 42 let num_members = u8::read_le(&mut reader)?; 43 // Read the members. 44 let mut members = IndexMap::with_capacity(num_members as usize); 45 for _ in 0..num_members { 46 // Read the identifier. 47 let identifier = Identifier::<N>::read_le(&mut reader)?; 48 // Read the plaintext value (in 2 steps to prevent infinite recursion). 49 let num_bytes = u16::read_le(&mut reader)?; 50 // Read the plaintext bytes. 51 let mut bytes = Vec::new(); 52 (&mut reader).take(num_bytes as u64).read_to_end(&mut bytes)?; 53 // Recover the plaintext value. 54 let plaintext = Self::read_le_internal(&mut bytes.as_slice(), depth + 1)?; 55 // Add the member. 56 members.insert(identifier, plaintext); 57 } 58 // Return the struct. 59 Self::Struct(members, Default::default()) 60 } 61 2 => { 62 // Read the length of the array. 63 let num_elements = u32::read_le(&mut reader)?; 64 if num_elements as usize > N::MAX_ARRAY_ELEMENTS { 65 return Err(error("Failed to deserialize plaintext: Array exceeds maximum length")); 66 } 67 // Read the elements. 68 let mut elements = Vec::with_capacity(num_elements as usize); 69 for _ in 0..num_elements { 70 // Read the plaintext value (in 2 steps to prevent infinite recursion). 71 let num_bytes = u16::read_le(&mut reader)?; 72 // Read the plaintext bytes. 73 let mut bytes = Vec::new(); 74 (&mut reader).take(num_bytes as u64).read_to_end(&mut bytes)?; 75 // Recover the plaintext value. 76 let plaintext = Self::read_le_internal(&mut bytes.as_slice(), depth + 1)?; 77 // Add the element. 78 elements.push(plaintext); 79 } 80 // Return the array. 81 Self::Array(elements, Default::default()) 82 } 83 3.. => return Err(error(format!("Failed to decode plaintext variant {index}"))), 84 }; 85 Ok(plaintext) 86 } 87 } 88 89 impl<N: Network> ToBytes for Plaintext<N> { 90 /// Writes the plaintext to a buffer. 91 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> { 92 match self { 93 Self::Literal(literal, ..) => { 94 0u8.write_le(&mut writer)?; 95 literal.write_le(&mut writer) 96 } 97 Self::Struct(struct_, ..) => { 98 1u8.write_le(&mut writer)?; 99 100 // Write the number of members in the struct. 101 u8::try_from(struct_.len()).map_err(error)?.write_le(&mut writer)?; 102 103 // Write each member. 104 for (member_name, member_value) in struct_ { 105 // Write the member name. 106 member_name.write_le(&mut writer)?; 107 108 // Write the member value (performed in 2 steps to prevent infinite recursion). 109 let bytes = member_value.to_bytes_le().map_err(|e| error(e.to_string()))?; 110 // Write the number of bytes. 111 u16::try_from(bytes.len()).map_err(error)?.write_le(&mut writer)?; 112 // Write the bytes. 113 bytes.write_le(&mut writer)?; 114 } 115 Ok(()) 116 } 117 Self::Array(array, ..) => { 118 2u8.write_le(&mut writer)?; 119 120 // Write the length of the array. 121 u32::try_from(array.len()).map_err(error)?.write_le(&mut writer)?; 122 123 // Write each element. 124 for element in array { 125 // Write the element (performed in 2 steps to prevent infinite recursion). 126 let bytes = element.to_bytes_le().map_err(error)?; 127 // Write the number of bytes. 128 u16::try_from(bytes.len()).map_err(error)?.write_le(&mut writer)?; 129 // Write the bytes. 130 bytes.write_le(&mut writer)?; 131 } 132 Ok(()) 133 } 134 } 135 } 136 } 137 138 #[cfg(test)] 139 mod tests { 140 use super::*; 141 use alphavm_console_network::MainnetV0; 142 143 type CurrentNetwork = MainnetV0; 144 145 const ITERATIONS: u32 = 1000; 146 147 fn check_bytes(expected: Plaintext<CurrentNetwork>) -> Result<()> { 148 // Check the byte representation. 149 let expected_bytes = expected.to_bytes_le()?; 150 assert_eq!(expected, Plaintext::read_le(&expected_bytes[..])?); 151 Ok(()) 152 } 153 154 #[test] 155 fn test_bytes() -> Result<()> { 156 let rng = &mut TestRng::default(); 157 158 for _ in 0..ITERATIONS { 159 let private_key = alphavm_console_account::PrivateKey::<CurrentNetwork>::new(rng)?; 160 161 // Address 162 check_bytes(Plaintext::Literal( 163 Literal::<CurrentNetwork>::Address(Address::try_from(private_key)?), 164 Default::default(), 165 ))?; 166 // Boolean 167 check_bytes(Plaintext::Literal( 168 Literal::<CurrentNetwork>::Boolean(Boolean::new(Uniform::rand(rng))), 169 Default::default(), 170 ))?; 171 // Field 172 check_bytes(Plaintext::Literal(Literal::<CurrentNetwork>::Field(Uniform::rand(rng)), Default::default()))?; 173 // Group 174 check_bytes(Plaintext::Literal(Literal::<CurrentNetwork>::Group(Uniform::rand(rng)), Default::default()))?; 175 // I8 176 check_bytes(Plaintext::Literal( 177 Literal::<CurrentNetwork>::I8(I8::new(Uniform::rand(rng))), 178 Default::default(), 179 ))?; 180 // I16 181 check_bytes(Plaintext::Literal( 182 Literal::<CurrentNetwork>::I16(I16::new(Uniform::rand(rng))), 183 Default::default(), 184 ))?; 185 // I32 186 check_bytes(Plaintext::Literal( 187 Literal::<CurrentNetwork>::I32(I32::new(Uniform::rand(rng))), 188 Default::default(), 189 ))?; 190 // I64 191 check_bytes(Plaintext::Literal( 192 Literal::<CurrentNetwork>::I64(I64::new(Uniform::rand(rng))), 193 Default::default(), 194 ))?; 195 // I128 196 check_bytes(Plaintext::Literal( 197 Literal::<CurrentNetwork>::I128(I128::new(Uniform::rand(rng))), 198 Default::default(), 199 ))?; 200 // U8 201 check_bytes(Plaintext::Literal( 202 Literal::<CurrentNetwork>::U8(U8::new(Uniform::rand(rng))), 203 Default::default(), 204 ))?; 205 // U16 206 check_bytes(Plaintext::Literal( 207 Literal::<CurrentNetwork>::U16(U16::new(Uniform::rand(rng))), 208 Default::default(), 209 ))?; 210 // U32 211 check_bytes(Plaintext::Literal( 212 Literal::<CurrentNetwork>::U32(U32::new(Uniform::rand(rng))), 213 Default::default(), 214 ))?; 215 // U64 216 check_bytes(Plaintext::Literal( 217 Literal::<CurrentNetwork>::U64(U64::new(Uniform::rand(rng))), 218 Default::default(), 219 ))?; 220 // U128 221 check_bytes(Plaintext::Literal( 222 Literal::<CurrentNetwork>::U128(U128::new(Uniform::rand(rng))), 223 Default::default(), 224 ))?; 225 // Scalar 226 check_bytes(Plaintext::Literal(Literal::<CurrentNetwork>::Scalar(Uniform::rand(rng)), Default::default()))?; 227 // String 228 check_bytes(Plaintext::Literal( 229 Literal::<CurrentNetwork>::String(StringType::rand(rng)), 230 Default::default(), 231 ))?; 232 } 233 234 // Check the struct manually. 235 let expected = Plaintext::<CurrentNetwork>::from_str( 236 "{ owner: ax150w2lvhdzychwvzu54ys5zas7tm5s0ycdyw563pms83g9u0vucgqe5fs5w, token_amount: 100u64 }", 237 )?; 238 239 // Check the byte representation. 240 let expected_bytes = expected.to_bytes_le()?; 241 assert_eq!(expected, Plaintext::read_le(&expected_bytes[..])?); 242 243 // Check the array manually. 244 let expected = Plaintext::<CurrentNetwork>::from_str("[ 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8 ]")?; 245 246 // Check the byte representation. 247 let expected_bytes = expected.to_bytes_le()?; 248 assert_eq!(expected, Plaintext::read_le(&expected_bytes[..])?); 249 250 Ok(()) 251 } 252 253 // A helper function to get the depth of the plaintext. 254 fn get_depth(plaintext: &Plaintext<CurrentNetwork>) -> usize { 255 match plaintext { 256 Plaintext::Literal(_, _) => 0, 257 Plaintext::Struct(members, _) => members.values().map(get_depth).max().unwrap_or(0) + 1, 258 Plaintext::Array(elements, _) => elements.iter().map(get_depth).max().unwrap_or(0) + 1, 259 } 260 } 261 262 #[test] 263 fn test_deeply_nested_plaintext() { 264 // Creates a nested array-like `Plaintext` structure by wrapping a root value `depth` times. 265 fn create_nested_array(depth: usize, root: impl Display) -> Vec<u8> { 266 // Start from the innermost value. 267 let mut result = Plaintext::<CurrentNetwork>::from_str(&root.to_string()).unwrap().to_bytes_le().unwrap(); 268 // Reverse the bytes. 269 result.reverse(); 270 // Build up the structure in reverse. 271 for _ in 0..depth { 272 // Write the size of the object in bytes in reverse. 273 let mut length = (u16::try_from(result.len()).unwrap()).to_bytes_le().unwrap(); 274 length.reverse(); 275 result.extend(length); 276 // Write the number of elements in the array in reverse. 277 let mut num_elements = 1u32.to_bytes_le().unwrap(); 278 num_elements.reverse(); 279 result.extend(num_elements); 280 // Write the plaintext variant in reverse. 281 let mut variant = 2u8.to_bytes_le().unwrap(); 282 variant.reverse(); 283 result.extend(variant); 284 } 285 // Reverse the result to get the correct order. 286 result.reverse(); 287 result 288 } 289 290 // Creates a nested struct-like `Plaintext` structure by wrapping a root value `depth` times. 291 fn create_nested_struct(depth: usize, root: impl Display) -> Vec<u8> { 292 // Start from the innermost value. 293 let mut result = Plaintext::<CurrentNetwork>::from_str(&root.to_string()).unwrap().to_bytes_le().unwrap(); 294 // Reverse the bytes. 295 result.reverse(); 296 // Build up the structure in reverse. 297 for _ in 0..depth { 298 // Write the size of the object in bytes in reverse. 299 let mut length = (u16::try_from(result.len()).unwrap()).to_bytes_le().unwrap(); 300 length.reverse(); 301 result.extend(length); 302 // Write the member name in reverse. 303 let mut member_name = Identifier::<CurrentNetwork>::from_str("inner").unwrap().to_bytes_le().unwrap(); 304 member_name.reverse(); 305 result.extend(member_name); 306 // Write the number of members in the struct in reverse. 307 let mut num_members = 1u8.to_bytes_le().unwrap(); 308 num_members.reverse(); 309 result.extend(num_members); 310 // Write the plaintext variant in reverse. 311 let mut variant = 1u8.to_bytes_le().unwrap(); 312 variant.reverse(); 313 result.extend(variant); 314 } 315 // Reverse the result to get the correct order. 316 result.reverse(); 317 result 318 } 319 320 // Creates a nested `Plaintext` structure with alternating array and struct wrappers. 321 fn create_alternated_nested(depth: usize, root: impl Display) -> Vec<u8> { 322 // Start from the innermost value. 323 let mut result = Plaintext::<CurrentNetwork>::from_str(&root.to_string()).unwrap().to_bytes_le().unwrap(); 324 // Reverse the bytes. 325 result.reverse(); 326 // Build up the structure in reverse. 327 for i in 0..depth { 328 // Write the size of the object in bytes in reverse. 329 let mut length = (u16::try_from(result.len()).unwrap()).to_bytes_le().unwrap(); 330 length.reverse(); 331 result.extend(length); 332 // Determine the type of the wrapper (array or struct) and handle accordingly. 333 if i % 2 == 0 { 334 // Write the number of elements in the array in reverse. 335 let mut num_elements = 1u32.to_bytes_le().unwrap(); 336 num_elements.reverse(); 337 result.extend(num_elements); 338 // Write the plaintext variant for array in reverse. 339 let mut variant = 2u8.to_bytes_le().unwrap(); 340 variant.reverse(); 341 result.extend(variant); 342 } else { 343 // Write the member name in reverse. 344 let mut member_name = 345 Identifier::<CurrentNetwork>::from_str("inner").unwrap().to_bytes_le().unwrap(); 346 member_name.reverse(); 347 result.extend(member_name); 348 // Write the number of members in the struct in reverse. 349 let mut num_members = 1u8.to_bytes_le().unwrap(); 350 num_members.reverse(); 351 result.extend(num_members); 352 // Write the plaintext variant for struct in reverse. 353 let mut variant = 1u8.to_bytes_le().unwrap(); 354 variant.reverse(); 355 result.extend(variant); 356 } 357 } 358 // Reverse the result to get the correct order. 359 result.reverse(); 360 result 361 } 362 363 // A helper function to run the test. 364 fn run_test(expected_depth: usize, input: Vec<u8>, expected_error: bool) { 365 // Parse the input string. 366 let result = Plaintext::<CurrentNetwork>::read_le(&*input); 367 // Check if the result is an error. 368 match expected_error { 369 true => { 370 assert!(result.is_err()); 371 return; 372 } 373 false => assert!(result.is_ok()), 374 }; 375 // Unwrap the result. 376 let candidate = result.unwrap(); 377 // Check if the candidate is equal to the input. 378 assert_eq!(input, candidate.to_bytes_le().unwrap()); 379 // Check if the candidate is equal to the expected depth. 380 assert_eq!(get_depth(&candidate), expected_depth); 381 } 382 383 // Initialize a sequence of depths to check. 384 // Note that 6500 is approximate maximum depth that can be constructed in this test. 385 let mut depths = (0usize..100).collect_vec(); 386 depths.extend((100..6500).step_by(100)); 387 388 // Test deeply nested arrays with different literal types. 389 for i in depths.iter().copied() { 390 run_test(i, create_nested_array(i, "false"), i > CurrentNetwork::MAX_DATA_DEPTH); 391 run_test(i, create_nested_array(i, "1u8"), i > CurrentNetwork::MAX_DATA_DEPTH); 392 run_test(i, create_nested_array(i, "0u128"), i > CurrentNetwork::MAX_DATA_DEPTH); 393 run_test(i, create_nested_array(i, "10field"), i > CurrentNetwork::MAX_DATA_DEPTH); 394 } 395 396 // Test deeply nested structs with different literal types. 397 for i in depths.iter().copied() { 398 run_test(i, create_nested_struct(i, "false"), i > CurrentNetwork::MAX_DATA_DEPTH); 399 run_test(i, create_nested_struct(i, "1u8"), i > CurrentNetwork::MAX_DATA_DEPTH); 400 run_test(i, create_nested_struct(i, "0u128"), i > CurrentNetwork::MAX_DATA_DEPTH); 401 run_test(i, create_nested_struct(i, "10field"), i > CurrentNetwork::MAX_DATA_DEPTH); 402 } 403 404 // Test alternating nested arrays and structs. 405 for i in depths.iter().copied() { 406 run_test(i, create_alternated_nested(i, "false"), i > CurrentNetwork::MAX_DATA_DEPTH); 407 run_test(i, create_alternated_nested(i, "1u8"), i > CurrentNetwork::MAX_DATA_DEPTH); 408 run_test(i, create_alternated_nested(i, "0u128"), i > CurrentNetwork::MAX_DATA_DEPTH); 409 run_test(i, create_alternated_nested(i, "10field"), i > CurrentNetwork::MAX_DATA_DEPTH); 410 } 411 } 412 }