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  }