/ console / program / src / data / record / bytes.rs
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  
 21  impl<N: Network, Private: Visibility> FromBytes for Record<N, Private> {
 22      /// Reads the record from a buffer.
 23      fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
 24          // Read the variant.
 25          let variant = U8::<N>::new(u8::read_le(&mut reader)?);
 26  
 27          // Set the version based on the variant.
 28          let version = match *variant {
 29              0 | 1 => U8::zero(),
 30              2 | 3 => U8::one(),
 31              4.. => return Err(error(format!("Failed to decode record variant ({variant}) for the version"))),
 32          };
 33  
 34          // Read the owner.
 35          let owner = match *variant {
 36              0 | 2 => Owner::Public(Address::read_le(&mut reader)?),
 37              1 | 3 => Owner::Private(Private::read_le(&mut reader)?),
 38              4.. => return Err(error(format!("Failed to decode record variant ({variant}) for the owner"))),
 39          };
 40  
 41          // Read the number of entries in the record data.
 42          let num_entries = u8::read_le(&mut reader)?;
 43          // Read the record data.
 44          let mut data = IndexMap::with_capacity(num_entries as usize);
 45          for _ in 0..num_entries {
 46              // Read the identifier.
 47              let identifier = Identifier::<N>::read_le(&mut reader)?;
 48              // Read the entry value (in 2 steps to prevent infinite recursion).
 49              let num_bytes = u16::read_le(&mut reader)?;
 50              // Read the entry bytes.
 51              let mut bytes = Vec::new();
 52              (&mut reader).take(num_bytes as u64).read_to_end(&mut bytes)?;
 53              // Recover the entry value.
 54              let entry = Entry::read_le(&mut bytes.as_slice())?;
 55              // Add the entry.
 56              data.insert(identifier, entry);
 57          }
 58  
 59          // Read the nonce.
 60          let nonce = Group::read_le(&mut reader)?;
 61  
 62          // Prepare the reserved entry names.
 63          let reserved = [Identifier::from_str("owner").map_err(|e| error(e.to_string()))?];
 64          // Ensure the entries has no duplicate names.
 65          if has_duplicates(data.keys().chain(reserved.iter())) {
 66              return Err(error("Duplicate entry type found in record"));
 67          }
 68          // Ensure the number of entries is within the maximum limit.
 69          if data.len() > N::MAX_DATA_ENTRIES {
 70              return Err(error("Failed to parse record - too many entries"));
 71          }
 72  
 73          Ok(Self { owner, data, nonce, version })
 74      }
 75  }
 76  
 77  impl<N: Network, Private: Visibility> ToBytes for Record<N, Private> {
 78      /// Writes the record to a buffer.
 79      fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
 80          // Set the variant.
 81          let variant = match (*self.version, self.owner.is_public()) {
 82              (0, true) => 0u8,
 83              (0, false) => 1u8,
 84              (1, true) => 2u8,
 85              (1, false) => 3u8,
 86              (_, _) => {
 87                  return Err(error(format!(
 88                      "Failed to encode record - variant mismatch (version = {}, hiding = {}, owner = {})",
 89                      self.version,
 90                      self.is_hiding(),
 91                      self.owner.is_public()
 92                  )));
 93              }
 94          };
 95  
 96          #[cfg(debug_assertions)]
 97          {
 98              // Ensure the version is correct.
 99              let is_version_correct = match (!self.is_hiding(), self.owner.is_public()) {
100                  (true, true) => variant == 0,
101                  (true, false) => variant == 1,
102                  (false, true) => variant == 2,
103                  (false, false) => variant == 3,
104              };
105              if !is_version_correct {
106                  return Err(error(format!(
107                      "Failed to encode record - version mismatch (version = {}, hiding = {}, owner = {})",
108                      self.version,
109                      self.is_hiding(),
110                      self.owner.is_public()
111                  )));
112              }
113          }
114  
115          // Write the variant.
116          variant.write_le(&mut writer)?;
117  
118          // Write the owner.
119          match &self.owner {
120              Owner::Public(owner) => owner.write_le(&mut writer)?,
121              Owner::Private(owner) => owner.write_le(&mut writer)?,
122          };
123  
124          // Write the number of entries in the record data.
125          u8::try_from(self.data.len()).or_halt_with::<N>("Record length exceeds u8::MAX").write_le(&mut writer)?;
126          // Write each entry.
127          for (entry_name, entry_value) in &self.data {
128              // Write the entry name.
129              entry_name.write_le(&mut writer)?;
130              // Write the entry value (performed in 2 steps to prevent infinite recursion).
131              let bytes = entry_value.to_bytes_le().map_err(|e| error(e.to_string()))?;
132              // Write the number of bytes.
133              u16::try_from(bytes.len())
134                  .or_halt_with::<N>("Record entry exceeds u16::MAX bytes")
135                  .write_le(&mut writer)?;
136              // Write the bytes.
137              bytes.write_le(&mut writer)?;
138          }
139  
140          // Write the nonce.
141          self.nonce.write_le(&mut writer)
142      }
143  }
144  
145  #[cfg(test)]
146  mod tests {
147      use super::*;
148      use alphavm_console_network::MainnetV0;
149  
150      type CurrentNetwork = MainnetV0;
151  
152      #[test]
153      fn test_bytes() -> Result<()> {
154          // Construct a new record.
155          let expected = Record::<CurrentNetwork, Plaintext<CurrentNetwork>>::from_str(
156              "{ owner: ax150w2lvhdzychwvzu54ys5zas7tm5s0ycdyw563pms83g9u0vucgqe5fs5w.private, token_amount: 100u64.private, _nonce: 0group.public }",
157          )?;
158  
159          // Check the byte representation.
160          let expected_bytes = expected.to_bytes_le()?;
161          assert_eq!(expected, Record::read_le(&expected_bytes[..])?);
162  
163          // Construct a new record.
164          let expected = Record::<CurrentNetwork, Plaintext<CurrentNetwork>>::from_str(
165              "{ owner: ax150w2lvhdzychwvzu54ys5zas7tm5s0ycdyw563pms83g9u0vucgqe5fs5w.private, token_amount: 100u64.private, _nonce: 0group.public, _version: 1u8.public }",
166          )?;
167  
168          // Check the byte representation.
169          let expected_bytes = expected.to_bytes_le()?;
170          assert_eq!(expected, Record::read_le(&expected_bytes[..])?);
171          Ok(())
172      }
173  }