bytes.rs
1 // Copyright (c) 2025-2026 ACDC Network 2 // This file is part of the alphavm library. 3 // 4 // Alpha Chain | Delta Chain Protocol 5 // International Monetary Graphite. 6 // 7 // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com). 8 // They built world-class ZK infrastructure. We installed the EASY button. 9 // Their cryptography: elegant. Our modifications: bureaucracy-compatible. 10 // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours. 11 // 12 // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0 13 // All modifications and new work: CC0 1.0 Universal Public Domain Dedication. 14 // No rights reserved. No permission required. No warranty. No refunds. 15 // 16 // https://creativecommons.org/publicdomain/zero/1.0/ 17 // SPDX-License-Identifier: CC0-1.0 18 19 use super::*; 20 use crate::{Identifier, LiteralType}; 21 22 impl<N: Network> FromBytes for ArrayType<N> { 23 fn read_le<R: Read>(mut reader: R) -> IoResult<Self> { 24 // Read the innermost element type. 25 let variant = u8::read_le(&mut reader)?; 26 let element_type = match variant { 27 0 => PlaintextType::Literal(LiteralType::read_le(&mut reader)?), 28 1 => PlaintextType::Struct(Identifier::read_le(&mut reader)?), 29 2.. => return Err(error(format!("Failed to deserialize element type {variant}"))), 30 }; 31 32 // Read the number of dimensions of the array. 33 let dimensions = u8::read_le(&mut reader)? as usize; 34 35 // Ensure the dimensions of the array are valid. 36 match dimensions { 37 0 => return Err(error("Array type must have at least one dimension.")), 38 dimensions if dimensions <= N::MAX_DATA_DEPTH => (), 39 _ => return Err(error(format!("Array type exceeds the maximum depth of {}.", N::MAX_DATA_DEPTH))), 40 } 41 42 // Read the lengths of the array. 43 let mut lengths = Vec::with_capacity(dimensions); 44 for _ in 0..dimensions { 45 lengths.push(U32::read_le(&mut reader)?); 46 } 47 48 // Construct the array type. 49 ArrayType::new(element_type, lengths).map_err(|e| error(format!("{e}"))) 50 } 51 } 52 53 impl<N: Network> ToBytes for ArrayType<N> { 54 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> { 55 // Initialize the components to serialize. 56 let mut element_type = *self.element_type.clone(); 57 let mut lengths = Vec::new(); 58 lengths.push(*self.length()); 59 60 // Collect the each dimension of the array. 61 // Note that the lengths are in the order of the outermost dimension to the innermost dimension. 62 for _ in 1..N::MAX_DATA_DEPTH { 63 element_type = match element_type { 64 PlaintextType::Literal(_) | PlaintextType::Struct(_) => break, 65 PlaintextType::Array(array_type) => { 66 lengths.push(*array_type.length()); 67 array_type.next_element_type().clone() 68 } 69 }; 70 } 71 72 // Check that the array type does not exceed the maximum depth. 73 if let PlaintextType::Array(_) = element_type { 74 return Err(error(format!("Array type exceeds the maximum depth of {}.", N::MAX_DATA_DEPTH))); 75 } 76 77 // Write the innermost element type. 78 match element_type { 79 PlaintextType::Literal(literal_type) => { 80 0u8.write_le(&mut writer)?; 81 literal_type.write_le(&mut writer)?; 82 } 83 PlaintextType::Struct(identifier) => { 84 1u8.write_le(&mut writer)?; 85 identifier.write_le(&mut writer)?; 86 } 87 PlaintextType::Array(_) => { 88 // This is technically unreachable by definition, however we return an error 89 // out of an abundance of caution. 90 return Err(error(format!("Array type exceeds the maximum depth of {}.", N::MAX_DATA_DEPTH))); 91 } 92 } 93 94 // Write the number of dimensions of the array. 95 u8::try_from(lengths.len()).map_err(error)?.write_le(&mut writer)?; 96 97 // Write the lengths of the array. 98 for length in lengths { 99 length.write_le(&mut writer)?; 100 } 101 102 Ok(()) 103 } 104 } 105 106 #[cfg(test)] 107 mod tests { 108 use super::*; 109 110 type CurrentNetwork = alphavm_console_network::MainnetV0; 111 112 #[test] 113 fn test_array_maximum_depth() { 114 // Construct the array type. 115 let array_type = { 116 let mut string = "[u8; 1u32]".to_string(); 117 for i in 1..CurrentNetwork::MAX_DATA_DEPTH { 118 string = format!("[{}; {}u32]", string, i + 1); 119 } 120 let array_type = ArrayType::<CurrentNetwork>::from_str(&string).unwrap(); 121 assert_eq!(array_type.length(), &U32::new(u32::try_from(CurrentNetwork::MAX_DATA_DEPTH).unwrap())); 122 assert_eq!(array_type.base_element_type(), &PlaintextType::Literal(LiteralType::U8)); 123 array_type 124 }; 125 126 // Serialize and deserialize the array type. 127 let mut bytes = Vec::new(); 128 array_type.write_le(&mut bytes).unwrap(); 129 let array_type = ArrayType::<CurrentNetwork>::read_le(&bytes[..]).unwrap(); 130 assert_eq!(array_type.length(), &U32::new(u32::try_from(CurrentNetwork::MAX_DATA_DEPTH).unwrap())); 131 assert_eq!(array_type.base_element_type(), &PlaintextType::Literal(LiteralType::U8)) 132 } 133 }