use super::*;
impl<N: Network> FromBytes for Transaction<N> {
#[inline]
fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
let version = u16::read_le(&mut reader)?;
if version != 0 {
return Err(error("Invalid transaction version"));
}
let variant = u8::read_le(&mut reader)?;
let (id, transaction) = match variant {
0 => {
let id = N::TransactionID::read_le(&mut reader)?;
let deployment = Deployment::read_le(&mut reader)?;
let additional_fee = AdditionalFee::read_le(&mut reader)?;
let transaction =
Self::from_deployment(deployment, additional_fee).map_err(|e| error(e.to_string()))?;
(id, transaction)
}
1 => {
let id = N::TransactionID::read_le(&mut reader)?;
let execution = Execution::read_le(&mut reader)?;
let additional_fee_variant = u8::read_le(&mut reader)?;
let additional_fee = match additional_fee_variant {
0u8 => None,
1u8 => Some(AdditionalFee::read_le(&mut reader)?),
_ => return Err(error("Invalid additional fee variant")),
};
let transaction = Self::from_execution(execution, additional_fee).map_err(|e| error(e.to_string()))?;
(id, transaction)
}
_ => return Err(error("Invalid transaction variant")),
};
match transaction.id() == id {
true => Ok(transaction),
false => Err(error("Transaction ID mismatch")),
}
}
}
impl<N: Network> ToBytes for Transaction<N> {
#[inline]
fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
0u16.write_le(&mut writer)?;
match self {
Self::Deploy(id, deployment, additional_fee) => {
0u8.write_le(&mut writer)?;
id.write_le(&mut writer)?;
deployment.write_le(&mut writer)?;
additional_fee.write_le(&mut writer)
}
Self::Execute(id, execution, additional_fee) => {
1u8.write_le(&mut writer)?;
id.write_le(&mut writer)?;
execution.write_le(&mut writer)?;
match additional_fee {
None => 0u8.write_le(&mut writer),
Some(additional_fee) => {
1u8.write_le(&mut writer)?;
additional_fee.write_le(&mut writer)
}
}
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use console::network::Testnet3;
type CurrentNetwork = Testnet3;
#[test]
fn test_bytes() -> Result<()> {
for expected in [
crate::ledger::vm::test_helpers::sample_deployment_transaction(),
crate::ledger::vm::test_helpers::sample_execution_transaction(),
]
.into_iter()
{
let expected_bytes = expected.to_bytes_le()?;
assert_eq!(expected, Transaction::read_le(&expected_bytes[..])?);
assert!(Transaction::<CurrentNetwork>::read_le(&expected_bytes[1..]).is_err());
}
Ok(())
}
}