snarkvm_ledger_block/transaction/
bytes.rs1use super::*;
17
18impl<N: Network> FromBytes for Transaction<N> {
19 #[inline]
21 fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
22 let version = u8::read_le(&mut reader)?;
24 if version != 1 {
26 return Err(error("Invalid transaction version"));
27 }
28
29 let variant = u8::read_le(&mut reader)?;
31 let (id, transaction) = match variant {
33 0 => {
34 let id = N::TransactionID::read_le(&mut reader)?;
36 let owner = ProgramOwner::read_le(&mut reader)?;
38 let deployment = Deployment::read_le(&mut reader)?;
40 let fee = Fee::read_le(&mut reader)?;
42
43 let transaction = Self::from_deployment(owner, deployment, fee).map_err(|e| error(e.to_string()))?;
45 (id, transaction)
47 }
48 1 => {
49 let id = N::TransactionID::read_le(&mut reader)?;
51 let execution = Execution::read_le(&mut reader)?;
53
54 let fee_variant = u8::read_le(&mut reader)?;
56 let fee = match fee_variant {
58 0u8 => None,
59 1u8 => Some(Fee::read_le(&mut reader)?),
60 _ => return Err(error("Invalid fee variant")),
61 };
62
63 let transaction = Self::from_execution(execution, fee).map_err(|e| error(e.to_string()))?;
65 (id, transaction)
67 }
68 2 => {
69 let id = N::TransactionID::read_le(&mut reader)?;
71 let fee = Fee::read_le(&mut reader)?;
73
74 let transaction = Self::from_fee(fee).map_err(|e| error(e.to_string()))?;
76 (id, transaction)
78 }
79 3.. => return Err(error("Invalid transaction variant")),
80 };
81
82 match transaction.id() == id {
84 true => Ok(transaction),
86 false => Err(error("Transaction ID mismatch")),
87 }
88 }
89}
90
91impl<N: Network> ToBytes for Transaction<N> {
92 #[inline]
94 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
95 1u8.write_le(&mut writer)?;
97
98 match self {
102 Self::Deploy(id, _, owner, deployment, fee) => {
103 0u8.write_le(&mut writer)?;
105 id.write_le(&mut writer)?;
107 owner.write_le(&mut writer)?;
109 deployment.write_le(&mut writer)?;
111 fee.write_le(&mut writer)
113 }
114 Self::Execute(id, _, execution, fee) => {
115 1u8.write_le(&mut writer)?;
117 id.write_le(&mut writer)?;
119 execution.write_le(&mut writer)?;
121 match fee {
123 None => 0u8.write_le(&mut writer),
124 Some(fee) => {
125 1u8.write_le(&mut writer)?;
126 fee.write_le(&mut writer)
127 }
128 }
129 }
130 Self::Fee(id, fee) => {
131 2u8.write_le(&mut writer)?;
133 id.write_le(&mut writer)?;
135 fee.write_le(&mut writer)
137 }
138 }
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use super::*;
145
146 #[test]
147 fn test_bytes() -> Result<()> {
148 let rng = &mut TestRng::default();
149
150 for expected in [
151 crate::transaction::test_helpers::sample_deployment_transaction(1, Uniform::rand(rng), false, true, rng),
152 crate::transaction::test_helpers::sample_deployment_transaction(1, Uniform::rand(rng), false, false, rng),
153 crate::transaction::test_helpers::sample_deployment_transaction(2, Uniform::rand(rng), false, true, rng),
154 crate::transaction::test_helpers::sample_deployment_transaction(2, Uniform::rand(rng), false, false, rng),
155 crate::transaction::test_helpers::sample_deployment_transaction(2, Uniform::rand(rng), true, true, rng),
156 crate::transaction::test_helpers::sample_deployment_transaction(2, Uniform::rand(rng), true, false, rng),
157 crate::transaction::test_helpers::sample_execution_transaction_with_fee(true, rng, 0),
158 crate::transaction::test_helpers::sample_execution_transaction_with_fee(false, rng, 0),
159 ]
160 .into_iter()
161 {
162 let expected_bytes = expected.to_bytes_le()?;
164 assert_eq!(expected, Transaction::read_le(&expected_bytes[..])?);
165 }
166 Ok(())
167 }
168}