snarkvm_ledger_narwhal_batch_certificate/
bytes.rs

1// Copyright (c) 2019-2025 Provable Inc.
2// This file is part of the snarkVM 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
16use super::*;
17
18impl<N: Network> FromBytes for BatchCertificate<N> {
19    /// Reads the batch certificate from the buffer.
20    fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
21        // Read the version.
22        let version = u8::read_le(&mut reader)?;
23        // Ensure the version is valid.
24        if version != 1 {
25            return Err(error("Invalid batch certificate version"));
26        }
27
28        // Read the batch header.
29        let batch_header = BatchHeader::read_le(&mut reader)?;
30        // Read the number of signatures.
31        let num_signatures = u16::read_le(&mut reader)?;
32        // Ensure the number of signatures is within bounds.
33        if num_signatures > Self::max_signatures().map_err(error)? {
34            return Err(error(format!(
35                "Number of signatures ({num_signatures}) exceeds the maximum ({})",
36                Self::max_signatures().map_err(error)?
37            )));
38        }
39        // Read the signature bytes.
40        let mut signature_bytes = vec![0u8; num_signatures as usize * Signature::<N>::size_in_bytes()];
41        reader.read_exact(&mut signature_bytes)?;
42        // Read the signatures.
43        let signatures = cfg_chunks!(signature_bytes, Signature::<N>::size_in_bytes())
44            .map(Signature::read_le)
45            .collect::<Result<IndexSet<_>, _>>()?;
46        // Return the batch certificate.
47        Self::from(batch_header, signatures).map_err(error)
48    }
49}
50
51impl<N: Network> ToBytes for BatchCertificate<N> {
52    /// Writes the batch certificate to the buffer.
53    fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
54        // Write the version.
55        1u8.write_le(&mut writer)?;
56        // Write the batch header.
57        self.batch_header.write_le(&mut writer)?;
58        // Write the number of signatures.
59        u16::try_from(self.signatures.len()).map_err(error)?.write_le(&mut writer)?;
60        // Write the signatures.
61        for signature in self.signatures.iter() {
62            // Write the signature.
63            signature.write_le(&mut writer)?;
64        }
65        Ok(())
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    fn test_bytes() {
75        let rng = &mut TestRng::default();
76
77        for expected in crate::test_helpers::sample_batch_certificates(rng) {
78            // Check the byte representation.
79            let expected_bytes = expected.to_bytes_le().unwrap();
80            assert_eq!(expected, BatchCertificate::read_le(&expected_bytes[..]).unwrap());
81        }
82    }
83}