use super::*;
impl<N: Network> FromBytes for Transition<N> {
fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
let version = u8::read_le(&mut reader)?;
if version != 1 {
return Err(error(format!("Invalid transition version: {version}")));
}
let transition_id = N::TransitionID::read_le(&mut reader)?;
let program_id = FromBytes::read_le(&mut reader)?;
let function_name = FromBytes::read_le(&mut reader)?;
let num_inputs: u8 = FromBytes::read_le(&mut reader)?;
if num_inputs as usize > N::MAX_INPUTS {
return Err(error(format!(
"Transition (from 'read_le') has too many inputs ({} > {})",
num_inputs,
N::MAX_INPUTS
)));
}
let mut inputs = Vec::with_capacity(num_inputs as usize);
for _ in 0..num_inputs {
inputs.push(FromBytes::read_le(&mut reader)?);
}
let num_outputs: u8 = FromBytes::read_le(&mut reader)?;
if num_outputs as usize > N::MAX_OUTPUTS {
return Err(error(format!(
"Transition (from 'read_le') has too many outputs ({} > {})",
num_outputs,
N::MAX_OUTPUTS
)));
}
let mut outputs = Vec::with_capacity(num_outputs as usize);
for _ in 0..num_outputs {
outputs.push(FromBytes::read_le(&mut reader)?);
}
let tpk = FromBytes::read_le(&mut reader)?;
let tcm = FromBytes::read_le(&mut reader)?;
let scm = FromBytes::read_le(&mut reader)?;
let transition =
Self::new(program_id, function_name, inputs, outputs, tpk, tcm, scm).map_err(|e| error(e.to_string()))?;
match transition_id == *transition.id() {
true => Ok(transition),
false => Err(error("Transition ID is incorrect, possible data corruption")),
}
}
}
impl<N: Network> ToBytes for Transition<N> {
fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
1u8.write_le(&mut writer)?;
self.id.write_le(&mut writer)?;
self.program_id.write_le(&mut writer)?;
self.function_name.write_le(&mut writer)?;
(u8::try_from(self.inputs.len()).map_err(|e| error(e.to_string()))?).write_le(&mut writer)?;
self.inputs.write_le(&mut writer)?;
(u8::try_from(self.outputs.len()).map_err(|e| error(e.to_string()))?).write_le(&mut writer)?;
self.outputs.write_le(&mut writer)?;
self.tpk.write_le(&mut writer)?;
self.tcm.write_le(&mut writer)?;
self.scm.write_le(&mut writer)?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bytes() -> Result<()> {
let rng = &mut TestRng::default();
let expected = crate::transition::test_helpers::sample_transition(rng);
let expected_bytes = expected.to_bytes_le()?;
assert_eq!(expected, Transition::read_le(&expected_bytes[..])?);
Ok(())
}
}