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 Execution<N> { 19 /// Reads the execution from a 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 execution version")); 26 } 27 // Read the number of transitions. 28 let num_transitions = u8::read_le(&mut reader)?; 29 // Ensure the number of transitions is nonzero. 30 if num_transitions == 0 { 31 return Err(error("Execution (from 'read_le') has no transitions")); 32 } 33 // Ensure the number of transitions is within bounds. 34 if num_transitions as usize > Transaction::<N>::MAX_TRANSITIONS { 35 return Err(error(format!( 36 "Execution (from 'read_le') has too many transitions ({} > {})", 37 num_transitions, 38 Transaction::<N>::MAX_TRANSITIONS 39 ))); 40 } 41 // Read the transitions. 42 let transitions = 43 (0..num_transitions).map(|_| Transition::read_le(&mut reader)).collect::<IoResult<Vec<_>>>()?; 44 // Read the global state root. 45 let global_state_root = N::StateRoot::read_le(&mut reader)?; 46 // Read the proof variant. 47 let proof_variant = u8::read_le(&mut reader)?; 48 // Read the proof. 49 let proof = match proof_variant { 50 0 => None, 51 1 => Some(Proof::read_le(&mut reader)?), 52 _ => return Err(error(format!("Invalid proof variant '{proof_variant}'"))), 53 }; 54 // Return the new `Execution` instance. 55 Self::from(transitions.into_iter(), global_state_root, proof).map_err(|e| error(e.to_string())) 56 } 57 } 58 59 impl<N: Network> ToBytes for Execution<N> { 60 /// Writes the execution to a buffer. 61 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> { 62 // Write the version. 63 1u8.write_le(&mut writer)?; 64 // Write the number of transitions. 65 (u8::try_from(self.transitions.len()).map_err(|e| error(e.to_string()))?).write_le(&mut writer)?; 66 // Write the transitions. 67 for transition in self.transitions.values() { 68 transition.write_le(&mut writer)?; 69 } 70 // Write the global state root. 71 self.global_state_root.write_le(&mut writer)?; 72 // Write the proof. 73 match self.proof { 74 None => 0u8.write_le(&mut writer)?, 75 Some(ref proof) => { 76 1u8.write_le(&mut writer)?; 77 proof.write_le(&mut writer)?; 78 } 79 } 80 Ok(()) 81 } 82 } 83 84 #[cfg(test)] 85 mod tests { 86 use super::*; 87 88 #[test] 89 fn test_bytes() -> Result<()> { 90 let rng = &mut TestRng::default(); 91 92 // Construct a new execution. 93 let expected = crate::transaction::execution::test_helpers::sample_execution(rng, 0); 94 95 // Check the byte representation. 96 let expected_bytes = expected.to_bytes_le()?; 97 assert_eq!(expected, Execution::read_le(&expected_bytes[..])?); 98 Ok(()) 99 } 100 }