snarkvm_ledger_block/
bytes.rs1use super::*;
17
18impl<N: Network> FromBytes for Block<N> {
19 fn read_le_with_unchecked<R: Read>(mut reader: R, unchecked: bool) -> IoResult<Self> {
21 let version = u8::read_le(&mut reader)?;
23 if version != 1 {
25 return Err(error("Invalid block version"));
26 }
27
28 let block_hash: N::BlockHash = FromBytes::read_le_with_unchecked(&mut reader, unchecked)?;
30 let previous_hash = FromBytes::read_le_with_unchecked(&mut reader, unchecked)?;
32 let header = FromBytes::read_le_with_unchecked(&mut reader, unchecked)?;
34
35 let authority = Authority::<N>::read_le_with_unchecked(&mut reader, unchecked)?;
37
38 let ratifications = Ratifications::read_le_with_unchecked(&mut reader, unchecked)?;
40
41 let solutions: Solutions<N> = FromBytes::read_le_with_unchecked(&mut reader, unchecked)?;
43
44 let num_aborted_solutions = u32::read_le(&mut reader)?;
46 if num_aborted_solutions as usize > Solutions::<N>::max_aborted_solutions().map_err(error)? {
48 return Err(error("Invalid number of aborted solutions IDs in the block"));
49 }
50 let mut aborted_solution_ids = Vec::with_capacity(num_aborted_solutions as usize);
52 for _ in 0..num_aborted_solutions {
53 aborted_solution_ids.push(FromBytes::read_le_with_unchecked(&mut reader, unchecked)?);
54 }
55
56 let transactions = FromBytes::read_le_with_unchecked(&mut reader, unchecked)?;
58
59 let num_aborted_transactions = u32::read_le(&mut reader)?;
61 if num_aborted_transactions as usize > Transactions::<N>::max_aborted_transactions().map_err(error)? {
63 return Err(error("Invalid number of aborted transaction IDs in the block"));
64 }
65 let mut aborted_transaction_ids = Vec::with_capacity(num_aborted_transactions as usize);
67 for _ in 0..num_aborted_transactions {
68 aborted_transaction_ids.push(FromBytes::read_le_with_unchecked(&mut reader, unchecked)?);
69 }
70
71 let block = if unchecked {
73 Self::from_unchecked(
74 block_hash,
75 previous_hash,
76 header,
77 authority,
78 ratifications,
79 solutions,
80 aborted_solution_ids,
81 transactions,
82 aborted_transaction_ids,
83 )
84 } else {
85 Self::from(
86 previous_hash,
87 header,
88 authority,
89 ratifications,
90 solutions,
91 aborted_solution_ids,
92 transactions,
93 aborted_transaction_ids,
94 )
95 }
96 .map_err(error)?;
97
98 match block_hash == block.hash() {
100 true => Ok(block),
101 false => Err(error("Mismatching block hash, possible data corruption")),
102 }
103 }
104
105 fn read_le<R: Read>(reader: R) -> IoResult<Self> {
107 Self::read_le_with_unchecked(reader, false)
108 }
109
110 fn read_le_unchecked<R: Read>(reader: R) -> IoResult<Self> {
112 Self::read_le_with_unchecked(reader, true)
113 }
114}
115
116impl<N: Network> ToBytes for Block<N> {
117 #[inline]
119 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
120 1u8.write_le(&mut writer)?;
122
123 self.block_hash.write_le(&mut writer)?;
125 self.previous_hash.write_le(&mut writer)?;
127 self.header.write_le(&mut writer)?;
129
130 self.authority.write_le(&mut writer)?;
132
133 self.ratifications.write_le(&mut writer)?;
135
136 self.solutions.write_le(&mut writer)?;
138
139 (u32::try_from(self.aborted_solution_ids.len()).map_err(error))?.write_le(&mut writer)?;
141 self.aborted_solution_ids.write_le(&mut writer)?;
142
143 self.transactions.write_le(&mut writer)?;
145
146 (u32::try_from(self.aborted_transaction_ids.len()).map_err(error))?.write_le(&mut writer)?;
148 self.aborted_transaction_ids.write_le(&mut writer)
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use super::*;
155 use console::network::MainnetV0;
156
157 type CurrentNetwork = MainnetV0;
158
159 #[test]
160 fn test_bytes() -> Result<()> {
161 let rng = &mut TestRng::default();
162
163 for expected in [crate::test_helpers::sample_genesis_block(rng)].into_iter() {
164 let expected_bytes = expected.to_bytes_le()?;
166 assert_eq!(expected, Block::read_le(&expected_bytes[..])?);
167 assert_eq!(expected, Block::read_le_unchecked(&expected_bytes[..])?);
168 }
169 Ok(())
170 }
171
172 #[test]
173 fn test_genesis_bytes() -> Result<()> {
174 let genesis_block = Block::<CurrentNetwork>::read_le(CurrentNetwork::genesis_bytes()).unwrap();
176
177 let expected_bytes = genesis_block.to_bytes_le()?;
179 assert_eq!(genesis_block, Block::read_le(&expected_bytes[..])?);
180 assert_eq!(genesis_block, Block::read_le_unchecked(&expected_bytes[..])?);
181
182 Ok(())
183 }
184
185 #[test]
186 fn test_bincode() -> Result<()> {
187 let genesis_block = Block::<CurrentNetwork>::read_le(CurrentNetwork::genesis_bytes()).unwrap();
189
190 let bincode_data = bincode::serialize(&genesis_block)?;
191 let block = bincode::deserialize(&bincode_data)?;
192
193 assert_eq!(genesis_block, block);
194
195 Ok(())
196 }
197}