/ ledger / block / src / transactions / bytes.rs
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 Transactions<N> {
19      /// Deserialize either unchecked or checked based on the given boolean flag.
20      #[inline]
21      fn read_le_with_unchecked<R: Read>(mut reader: R, unchecked: bool) -> IoResult<Self> {
22          // Read the version.
23          let version = u8::read_le(&mut reader)?;
24          // Ensure the version is valid.
25          if version != 1 {
26              return Err(error("Invalid transactions version"));
27          }
28          // Read the number of transactions.
29          let num_txs: u32 = FromBytes::read_le(&mut reader)?;
30          // Ensure the number of transactions is within bounds.
31          if num_txs as usize > Self::MAX_TRANSACTIONS {
32              return Err(error("Failed to read transactions: too many transactions"));
33          }
34          // Read the transactions.
35          let transactions = (0..num_txs)
36              .map(|_| FromBytes::read_le_with_unchecked(&mut reader, unchecked))
37              .collect::<Result<Vec<_>, _>>()?;
38          // Return the transactions.
39          Ok(Self::from(&transactions))
40      }
41  
42      /// Reads the transactions from buffer.
43      #[inline]
44      fn read_le<R: Read>(reader: R) -> IoResult<Self> {
45          Self::read_le_with_unchecked(reader, false)
46      }
47  
48      /// Reads the transactions from the buffer without performing any checks on the data.
49      #[inline]
50      fn read_le_unchecked<R: Read>(reader: R) -> IoResult<Self> {
51          Self::read_le_with_unchecked(reader, true)
52      }
53  }
54  
55  impl<N: Network> ToBytes for Transactions<N> {
56      /// Writes the transactions to a buffer.
57      #[inline]
58      fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
59          // Write the version.
60          1u8.write_le(&mut writer)?;
61          // Write the number of transactions.
62          u32::try_from(self.transactions.len()).map_err(error)?.write_le(&mut writer)?;
63          // Write the transactions.
64          self.transactions.values().try_for_each(|transaction| transaction.write_le(&mut writer))
65      }
66  }
67  
68  #[cfg(test)]
69  mod tests {
70      use super::*;
71  
72      #[test]
73      fn test_bytes() -> Result<()> {
74          let rng = &mut TestRng::default();
75  
76          for expected in [crate::transactions::test_helpers::sample_block_transactions(rng)].into_iter() {
77              // Check the byte representation.
78              let expected_bytes = expected.to_bytes_le()?;
79              assert_eq!(expected, Transactions::read_le(&expected_bytes[..])?);
80          }
81          Ok(())
82      }
83  }