use super::*;
impl<N: Network> FromBytes for Transition<N> {
fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
let version = u16::read_le(&mut reader)?;
if version != 0 {
return Err(error("Invalid transition 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: u16 = FromBytes::read_le(&mut reader)?;
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: u16 = FromBytes::read_le(&mut reader)?;
let mut outputs = Vec::with_capacity(num_outputs as usize);
for _ in 0..num_outputs {
outputs.push(FromBytes::read_le(&mut reader)?);
}
let finalize_variant = u8::read_le(&mut reader)?;
let finalize = match finalize_variant {
0 => None,
1 => {
let num_finalize_inputs = u16::read_le(&mut reader)?;
let mut finalize = Vec::with_capacity(num_finalize_inputs as usize);
for _ in 0..num_finalize_inputs {
finalize.push(FromBytes::read_le(&mut reader)?);
}
Some(finalize)
}
2.. => return Err(error(format!("Invalid transition finalize variant ({finalize_variant})"))),
};
let proof = FromBytes::read_le(&mut reader)?;
let tpk = FromBytes::read_le(&mut reader)?;
let tcm = FromBytes::read_le(&mut reader)?;
let fee = FromBytes::read_le(&mut reader)?;
let transition = Self::new(program_id, function_name, inputs, outputs, finalize, proof, tpk, tcm, fee)
.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<()> {
0u16.write_le(&mut writer)?;
self.id.write_le(&mut writer)?;
self.program_id.write_le(&mut writer)?;
self.function_name.write_le(&mut writer)?;
(self.inputs.len() as u16).write_le(&mut writer)?;
self.inputs.write_le(&mut writer)?;
(self.outputs.len() as u16).write_le(&mut writer)?;
self.outputs.write_le(&mut writer)?;
match &self.finalize {
None => {
0u8.write_le(&mut writer)?;
}
Some(finalize) => {
1u8.write_le(&mut writer)?;
(finalize.len() as u16).write_le(&mut writer)?;
finalize.write_le(&mut writer)?;
}
}
self.proof.write_le(&mut writer)?;
self.tpk.write_le(&mut writer)?;
self.tcm.write_le(&mut writer)?;
self.fee.write_le(&mut writer)
}
}
#[cfg(test)]
mod tests {
use super::*;
use console::network::Testnet3;
type CurrentNetwork = Testnet3;
#[test]
fn test_bytes() -> Result<()> {
let expected = crate::process::test_helpers::sample_transition();
let expected_bytes = expected.to_bytes_le()?;
assert_eq!(expected, Transition::read_le(&expected_bytes[..])?);
assert!(Transition::<CurrentNetwork>::read_le(&expected_bytes[1..]).is_err());
Ok(())
}
}