/ ledger / block / src / transaction / execution / 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 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  }