snarkvm_ledger_block/
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 Block<N> {
19    /// Reads the block from the buffer.
20    #[inline]
21    fn read_le<R: Read>(mut reader: R) -> 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 block version"));
27        }
28
29        // Read the block hash.
30        let block_hash: N::BlockHash = FromBytes::read_le(&mut reader)?;
31        // Read the previous block hash.
32        let previous_hash = FromBytes::read_le(&mut reader)?;
33        // Read the header.
34        let header = FromBytes::read_le(&mut reader)?;
35
36        // Read the authority.
37        let authority = FromBytes::read_le(&mut reader)?;
38
39        // Read the ratifications.
40        let ratifications = Ratifications::read_le(&mut reader)?;
41
42        // Read the solutions.
43        let solutions: Solutions<N> = FromBytes::read_le(&mut reader)?;
44
45        // Read the number of aborted solution IDs.
46        let num_aborted_solutions = u32::read_le(&mut reader)?;
47        // Ensure the number of aborted solutions IDs is within bounds (this is an early safety check).
48        if num_aborted_solutions as usize > Solutions::<N>::max_aborted_solutions().map_err(error)? {
49            return Err(error("Invalid number of aborted solutions IDs in the block"));
50        }
51        // Read the aborted solution IDs.
52        let mut aborted_solution_ids = Vec::with_capacity(num_aborted_solutions as usize);
53        for _ in 0..num_aborted_solutions {
54            aborted_solution_ids.push(FromBytes::read_le(&mut reader)?);
55        }
56
57        // Read the transactions.
58        let transactions = FromBytes::read_le(&mut reader)?;
59
60        // Read the number of aborted transaction IDs.
61        let num_aborted_transactions = u32::read_le(&mut reader)?;
62        // Ensure the number of aborted transaction IDs is within bounds (this is an early safety check).
63        if num_aborted_transactions as usize > Transactions::<N>::max_aborted_transactions().map_err(error)? {
64            return Err(error("Invalid number of aborted transaction IDs in the block"));
65        }
66        // Read the aborted transaction IDs.
67        let mut aborted_transaction_ids = Vec::with_capacity(num_aborted_transactions as usize);
68        for _ in 0..num_aborted_transactions {
69            aborted_transaction_ids.push(FromBytes::read_le(&mut reader)?);
70        }
71
72        // Construct the block.
73        let block = Self::from(
74            previous_hash,
75            header,
76            authority,
77            ratifications,
78            solutions,
79            aborted_solution_ids,
80            transactions,
81            aborted_transaction_ids,
82        )
83        .map_err(error)?;
84
85        // Ensure the block hash matches.
86        match block_hash == block.hash() {
87            true => Ok(block),
88            false => Err(error("Mismatching block hash, possible data corruption")),
89        }
90    }
91}
92
93impl<N: Network> ToBytes for Block<N> {
94    /// Writes the block to the buffer.
95    #[inline]
96    fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
97        // Write the version.
98        1u8.write_le(&mut writer)?;
99
100        // Write the block hash.
101        self.block_hash.write_le(&mut writer)?;
102        // Write the previous block hash.
103        self.previous_hash.write_le(&mut writer)?;
104        // Write the header.
105        self.header.write_le(&mut writer)?;
106
107        // Write the authority.
108        self.authority.write_le(&mut writer)?;
109
110        // Write the ratifications.
111        self.ratifications.write_le(&mut writer)?;
112
113        // Write the solutions.
114        self.solutions.write_le(&mut writer)?;
115
116        // Write the aborted solution IDs.
117        (u32::try_from(self.aborted_solution_ids.len()).map_err(error))?.write_le(&mut writer)?;
118        self.aborted_solution_ids.write_le(&mut writer)?;
119
120        // Write the transactions.
121        self.transactions.write_le(&mut writer)?;
122
123        // Write the aborted transaction IDs.
124        (u32::try_from(self.aborted_transaction_ids.len()).map_err(error))?.write_le(&mut writer)?;
125        self.aborted_transaction_ids.write_le(&mut writer)
126    }
127}
128
129#[cfg(test)]
130mod tests {
131    use super::*;
132    use console::network::MainnetV0;
133
134    type CurrentNetwork = MainnetV0;
135
136    #[test]
137    fn test_bytes() -> Result<()> {
138        let rng = &mut TestRng::default();
139
140        for expected in [crate::test_helpers::sample_genesis_block(rng)].into_iter() {
141            // Check the byte representation.
142            let expected_bytes = expected.to_bytes_le()?;
143            assert_eq!(expected, Block::read_le(&expected_bytes[..])?);
144        }
145        Ok(())
146    }
147
148    #[test]
149    fn test_genesis_bytes() -> Result<()> {
150        // Load the genesis block.
151        let genesis_block = Block::<CurrentNetwork>::read_le(CurrentNetwork::genesis_bytes()).unwrap();
152
153        // Check the byte representation.
154        let expected_bytes = genesis_block.to_bytes_le()?;
155        assert_eq!(genesis_block, Block::read_le(&expected_bytes[..])?);
156
157        Ok(())
158    }
159}