/ console / program / src / id / to_bits.rs
to_bits.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> ToBits for ProgramID<N> {
 19      /// Returns the little-endian bits of the program ID.
 20      fn write_bits_le(&self, vec: &mut Vec<bool>) {
 21          (&self).write_bits_le(vec);
 22      }
 23  
 24      /// Returns the big-endian bits of the program ID.
 25      fn write_bits_be(&self, vec: &mut Vec<bool>) {
 26          (&self).write_bits_be(vec);
 27      }
 28  }
 29  
 30  impl<N: Network> ToBits for &ProgramID<N> {
 31      /// Returns the little-endian bits of the program ID.
 32      fn write_bits_le(&self, vec: &mut Vec<bool>) {
 33          self.name().write_bits_le(vec);
 34          self.network().write_bits_le(vec);
 35      }
 36  
 37      /// Returns the big-endian bits of the program ID.
 38      fn write_bits_be(&self, vec: &mut Vec<bool>) {
 39          self.name().write_bits_be(vec);
 40          self.network().write_bits_be(vec);
 41      }
 42  }
 43  
 44  #[cfg(test)]
 45  mod tests {
 46      use super::*;
 47      use crate::data::identifier::tests::sample_lowercase_identifier_as_string;
 48      use alphavm_console_network::MainnetV0;
 49  
 50      type CurrentNetwork = MainnetV0;
 51  
 52      const ITERATIONS: usize = 100;
 53  
 54      #[test]
 55      fn test_to_bits_le() -> Result<()> {
 56          let mut rng = TestRng::default();
 57  
 58          for _ in 0..ITERATIONS {
 59              // Sample a random fixed-length alphanumeric string, that always starts with an alphabetic character.
 60              let expected_name_string = sample_lowercase_identifier_as_string::<CurrentNetwork>(&mut rng)?;
 61              // Recover the field element from the bits.
 62              let expected_name_field = Field::<CurrentNetwork>::from_bits_le(&expected_name_string.to_bits_le())?;
 63              let expected_network_field = Field::<CurrentNetwork>::from_bits_le(&"alpha".to_string().to_bits_le())?;
 64              // Compute the expected bits.
 65              let mut expected_bits = expected_name_field.to_bits_le()[..expected_name_string.len() * 8].to_vec();
 66              expected_bits.extend(&expected_network_field.to_bits_le()[..5 * 8]);
 67  
 68              let candidate = ProgramID::<CurrentNetwork>::from_str(&format!("{expected_name_string}.alpha"))?;
 69              assert_eq!(
 70                  expected_name_field.to_bits_le()[..expected_name_string.len() * 8],
 71                  candidate.name().to_bits_le()
 72              );
 73              assert_eq!(expected_network_field.to_bits_le()[..5 * 8], candidate.network().to_bits_le());
 74              assert_eq!(expected_bits, candidate.to_bits_le());
 75          }
 76          Ok(())
 77      }
 78  
 79      #[test]
 80      fn test_to_bits_be() -> Result<()> {
 81          let mut rng = TestRng::default();
 82  
 83          for _ in 0..ITERATIONS {
 84              // Sample a random fixed-length alphanumeric string, that always starts with an alphabetic character.
 85              let expected_name_string = sample_lowercase_identifier_as_string::<CurrentNetwork>(&mut rng)?;
 86              // Recover the field element from the bits.
 87              let expected_name_field = Field::<CurrentNetwork>::from_bits_le(&expected_name_string.to_bits_le())?;
 88              let expected_network_field = Field::<CurrentNetwork>::from_bits_le(&"alpha".to_string().to_bits_le())?;
 89              // Compute the expected bits.
 90              let mut expected_bits = expected_name_field.to_bits_le()[..expected_name_string.len() * 8]
 91                  .iter()
 92                  .rev()
 93                  .copied()
 94                  .collect::<Vec<_>>();
 95              expected_bits.extend(expected_network_field.to_bits_le()[..5 * 8].iter().rev().copied());
 96  
 97              let candidate = ProgramID::<CurrentNetwork>::from_str(&format!("{expected_name_string}.alpha"))?;
 98              assert_eq!(
 99                  expected_name_field.to_bits_le()[..expected_name_string.len() * 8]
100                      .iter()
101                      .rev()
102                      .copied()
103                      .collect::<Vec<_>>(),
104                  candidate.name().to_bits_be()
105              );
106              assert_eq!(
107                  expected_network_field.to_bits_le()[..5 * 8].iter().rev().copied().collect::<Vec<_>>(),
108                  candidate.network().to_bits_be()
109              );
110              assert_eq!(expected_bits, candidate.to_bits_be());
111          }
112          Ok(())
113      }
114  }