cardano_serialization_lib/serialization/
transaction_body.rs1use crate::*;
2
3impl cbor_event::se::Serialize for TransactionBody {
4 fn serialize<'se, W: Write>(
5 &self,
6 serializer: &'se mut Serializer<W>,
7 ) -> cbor_event::Result<&'se mut Serializer<W>> {
8 serializer.write_map(cbor_event::Len::Len(
9 3 + opt64(&self.ttl)
10 + opt64_non_empty(&self.certs)
11 + opt64_non_empty(&self.withdrawals)
12 + opt64(&self.update)
13 + opt64(&self.auxiliary_data_hash)
14 + opt64(&self.validity_start_interval)
15 + opt64_non_empty(&self.mint)
16 + opt64(&self.script_data_hash)
17 + opt64_non_empty(&self.collateral)
18 + opt64_non_empty(&self.required_signers)
19 + opt64(&self.network_id)
20 + opt64(&self.collateral_return)
21 + opt64(&self.total_collateral)
22 + opt64_non_empty(&self.reference_inputs)
23 + opt64_non_empty(&self.voting_procedures)
24 + opt64_non_empty(&self.voting_proposals)
25 + opt64(&self.donation)
26 + opt64(&self.current_treasury_value),
27 ))?;
28 serializer.write_unsigned_integer(0)?;
29 self.inputs.serialize(serializer)?;
30 serializer.write_unsigned_integer(1)?;
31 self.outputs.serialize(serializer)?;
32 serializer.write_unsigned_integer(2)?;
33 self.fee.serialize(serializer)?;
34 if let Some(field) = &self.ttl {
35 serializer.write_unsigned_integer(3)?;
36 field.serialize(serializer)?;
37 }
38 if let Some(field) = &self.certs {
39 if !field.is_none_or_empty() {
40 serializer.write_unsigned_integer(4)?;
41 field.serialize(serializer)?;
42 }
43 }
44 if let Some(field) = &self.withdrawals {
45 if !field.is_none_or_empty() {
46 serializer.write_unsigned_integer(5)?;
47 field.serialize(serializer)?;
48 }
49 }
50 if let Some(field) = &self.update {
51 serializer.write_unsigned_integer(6)?;
52 field.serialize(serializer)?;
53 }
54 if let Some(field) = &self.auxiliary_data_hash {
55 serializer.write_unsigned_integer(7)?;
56 field.serialize(serializer)?;
57 }
58 if let Some(field) = &self.validity_start_interval {
59 serializer.write_unsigned_integer(8)?;
60 field.serialize(serializer)?;
61 }
62 if let Some(field) = &self.mint {
63 if !field.is_none_or_empty() {
64 serializer.write_unsigned_integer(9)?;
65 field.serialize(serializer)?;
66 }
67 }
68 if let Some(field) = &self.script_data_hash {
69 serializer.write_unsigned_integer(11)?;
70 field.serialize(serializer)?;
71 }
72 if let Some(field) = &self.collateral {
73 if !field.is_none_or_empty() {
74 serializer.write_unsigned_integer(13)?;
75 field.serialize(serializer)?;
76 }
77 }
78 if let Some(field) = &self.required_signers {
79 if !field.is_none_or_empty() {
80 serializer.write_unsigned_integer(14)?;
81 field.serialize(serializer)?;
82 }
83 }
84 if let Some(field) = &self.network_id {
85 serializer.write_unsigned_integer(15)?;
86 field.serialize(serializer)?;
87 }
88 if let Some(field) = &self.collateral_return {
89 serializer.write_unsigned_integer(16)?;
90 field.serialize(serializer)?;
91 }
92 if let Some(field) = &self.total_collateral {
93 serializer.write_unsigned_integer(17)?;
94 field.serialize(serializer)?;
95 }
96 if let Some(field) = &self.reference_inputs {
97 if !field.is_none_or_empty() {
98 serializer.write_unsigned_integer(18)?;
99 field.serialize(serializer)?;
100 }
101 }
102 if let Some(field) = &self.voting_procedures {
103 if !field.is_none_or_empty() {
104 serializer.write_unsigned_integer(19)?;
105 field.serialize(serializer)?;
106 }
107 }
108 if let Some(field) = &self.voting_proposals {
109 if !field.is_none_or_empty() {
110 serializer.write_unsigned_integer(20)?;
111 field.serialize(serializer)?;
112 }
113 }
114 if let Some(field) = &self.current_treasury_value {
115 serializer.write_unsigned_integer(21)?;
116 field.serialize(serializer)?;
117 }
118 if let Some(field) = &self.donation {
119 serializer.write_unsigned_integer(22)?;
120 field.serialize(serializer)?;
121 }
122 Ok(serializer)
123 }
124}
125
126impl Deserialize for TransactionBody {
127 fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
128 (|| -> Result<_, DeserializeError> {
129 let len = raw.map()?;
130 let mut read_len = CBORReadLen::new(len);
131 read_len.read_elems(3)?;
132 let mut inputs = None;
133 let mut outputs = None;
134 let mut fee = None;
135 let mut ttl = None;
136 let mut certs = None;
137 let mut withdrawals = None;
138 let mut update = None;
139 let mut auxiliary_data_hash = None;
140 let mut validity_start_interval = None;
141 let mut mint = None;
142 let mut script_data_hash = None;
143 let mut collateral = None;
144 let mut required_signers = None;
145 let mut network_id = None;
146 let mut collateral_return = None;
147 let mut total_collateral = None;
148 let mut reference_inputs = None;
149 let mut voting_procedures = None;
150 let mut voting_proposals = None;
151 let mut current_treasury_value = None;
152 let mut donation = None;
153 let mut read = 0;
154 while match len {
155 cbor_event::Len::Len(n) => read < n as usize,
156 cbor_event::Len::Indefinite => true,
157 } {
158 match raw.cbor_type()? {
159 CBORType::UnsignedInteger => match raw.unsigned_integer()? {
160 0 => {
161 if inputs.is_some() {
162 return Err(DeserializeFailure::DuplicateKey(Key::Uint(0)).into());
163 }
164 inputs = Some(
165 (|| -> Result<_, DeserializeError> {
166 Ok(TransactionInputs::deserialize(raw)?)
167 })()
168 .map_err(|e| e.annotate("inputs"))?,
169 );
170 }
171 1 => {
172 if outputs.is_some() {
173 return Err(DeserializeFailure::DuplicateKey(Key::Uint(1)).into());
174 }
175 outputs = Some(
176 (|| -> Result<_, DeserializeError> {
177 Ok(TransactionOutputs::deserialize(raw)?)
178 })()
179 .map_err(|e| e.annotate("outputs"))?,
180 );
181 }
182 2 => {
183 if fee.is_some() {
184 return Err(DeserializeFailure::DuplicateKey(Key::Uint(2)).into());
185 }
186 fee =
187 Some(
188 (|| -> Result<_, DeserializeError> {
189 Ok(Coin::deserialize(raw)?)
190 })()
191 .map_err(|e| e.annotate("fee"))?,
192 );
193 }
194 3 => {
195 if ttl.is_some() {
196 return Err(DeserializeFailure::DuplicateKey(Key::Uint(3)).into());
197 }
198 ttl = Some(
199 (|| -> Result<_, DeserializeError> {
200 read_len.read_elems(1)?;
201 Ok(SlotBigNum::deserialize(raw)?)
202 })()
203 .map_err(|e| e.annotate("ttl"))?,
204 );
205 }
206 4 => {
207 if certs.is_some() {
208 return Err(DeserializeFailure::DuplicateKey(Key::Uint(4)).into());
209 }
210 certs = Some(
211 (|| -> Result<_, DeserializeError> {
212 read_len.read_elems(1)?;
213 Ok(Certificates::deserialize(raw)?)
214 })()
215 .map_err(|e| e.annotate("certs"))?,
216 );
217 }
218 5 => {
219 if withdrawals.is_some() {
220 return Err(DeserializeFailure::DuplicateKey(Key::Uint(5)).into());
221 }
222 withdrawals = Some(
223 (|| -> Result<_, DeserializeError> {
224 read_len.read_elems(1)?;
225 Ok(Withdrawals::deserialize(raw)?)
226 })()
227 .map_err(|e| e.annotate("withdrawals"))?,
228 );
229 }
230 6 => {
231 if update.is_some() {
232 return Err(DeserializeFailure::DuplicateKey(Key::Uint(6)).into());
233 }
234 update = Some(
235 (|| -> Result<_, DeserializeError> {
236 read_len.read_elems(1)?;
237 Ok(Update::deserialize(raw)?)
238 })()
239 .map_err(|e| e.annotate("update"))?,
240 );
241 }
242 7 => {
243 if auxiliary_data_hash.is_some() {
244 return Err(DeserializeFailure::DuplicateKey(Key::Uint(7)).into());
245 }
246 auxiliary_data_hash = Some(
247 (|| -> Result<_, DeserializeError> {
248 read_len.read_elems(1)?;
249 Ok(AuxiliaryDataHash::deserialize(raw)?)
250 })()
251 .map_err(|e| e.annotate("auxiliary_data_hash"))?,
252 );
253 }
254 8 => {
255 if validity_start_interval.is_some() {
256 return Err(DeserializeFailure::DuplicateKey(Key::Uint(8)).into());
257 }
258 validity_start_interval = Some(
259 (|| -> Result<_, DeserializeError> {
260 read_len.read_elems(1)?;
261 Ok(SlotBigNum::deserialize(raw)?)
262 })()
263 .map_err(|e| e.annotate("validity_start_interval"))?,
264 );
265 }
266 9 => {
267 if mint.is_some() {
268 return Err(DeserializeFailure::DuplicateKey(Key::Uint(9)).into());
269 }
270 mint = Some(
271 (|| -> Result<_, DeserializeError> {
272 read_len.read_elems(1)?;
273 Ok(Mint::deserialize(raw)?)
274 })()
275 .map_err(|e| e.annotate("mint"))?,
276 );
277 }
278 11 => {
279 if script_data_hash.is_some() {
280 return Err(DeserializeFailure::DuplicateKey(Key::Uint(11)).into());
281 }
282 script_data_hash = Some(
283 (|| -> Result<_, DeserializeError> {
284 read_len.read_elems(1)?;
285 Ok(ScriptDataHash::deserialize(raw)?)
286 })()
287 .map_err(|e| e.annotate("script_data_hash"))?,
288 );
289 }
290 13 => {
291 if collateral.is_some() {
292 return Err(DeserializeFailure::DuplicateKey(Key::Uint(13)).into());
293 }
294 collateral = Some(
295 (|| -> Result<_, DeserializeError> {
296 read_len.read_elems(1)?;
297 Ok(TransactionInputs::deserialize(raw)?)
298 })()
299 .map_err(|e| e.annotate("collateral"))?,
300 );
301 }
302 14 => {
303 if required_signers.is_some() {
304 return Err(DeserializeFailure::DuplicateKey(Key::Uint(14)).into());
305 }
306 required_signers = Some(
307 (|| -> Result<_, DeserializeError> {
308 read_len.read_elems(1)?;
309 Ok(Ed25519KeyHashes::deserialize(raw)?)
310 })()
311 .map_err(|e| e.annotate("required_signers"))?,
312 );
313 }
314 15 => {
315 if network_id.is_some() {
316 return Err(DeserializeFailure::DuplicateKey(Key::Uint(15)).into());
317 }
318 network_id = Some(
319 (|| -> Result<_, DeserializeError> {
320 read_len.read_elems(1)?;
321 Ok(NetworkId::deserialize(raw)?)
322 })()
323 .map_err(|e| e.annotate("network_id"))?,
324 );
325 }
326 16 => {
327 if collateral_return.is_some() {
328 return Err(DeserializeFailure::DuplicateKey(Key::Uint(16)).into());
329 }
330 collateral_return = Some(
331 (|| -> Result<_, DeserializeError> {
332 read_len.read_elems(1)?;
333 Ok(TransactionOutput::deserialize(raw)?)
334 })()
335 .map_err(|e| e.annotate("collateral_return"))?,
336 );
337 }
338 17 => {
339 if total_collateral.is_some() {
340 return Err(DeserializeFailure::DuplicateKey(Key::Uint(17)).into());
341 }
342 total_collateral = Some(
343 (|| -> Result<_, DeserializeError> {
344 read_len.read_elems(1)?;
345 Ok(Coin::deserialize(raw)?)
346 })()
347 .map_err(|e| e.annotate("total_collateral"))?,
348 );
349 }
350 18 => {
351 if reference_inputs.is_some() {
352 return Err(DeserializeFailure::DuplicateKey(Key::Uint(18)).into());
353 }
354 reference_inputs = Some(
355 (|| -> Result<_, DeserializeError> {
356 read_len.read_elems(1)?;
357 Ok(TransactionInputs::deserialize(raw)?)
358 })()
359 .map_err(|e| e.annotate("reference_inputs"))?,
360 );
361 }
362 19 => {
363 if voting_procedures.is_some() {
364 return Err(DeserializeFailure::DuplicateKey(Key::Uint(19)).into());
365 }
366 voting_procedures = Some(
367 (|| -> Result<_, DeserializeError> {
368 read_len.read_elems(1)?;
369 Ok(VotingProcedures::deserialize(raw)?)
370 })()
371 .map_err(|e| e.annotate("voting_procedures"))?,
372 );
373 }
374 20 => {
375 if voting_proposals.is_some() {
376 return Err(DeserializeFailure::DuplicateKey(Key::Uint(20)).into());
377 }
378 voting_proposals = Some(
379 (|| -> Result<_, DeserializeError> {
380 read_len.read_elems(1)?;
381 Ok(VotingProposals::deserialize(raw)?)
382 })()
383 .map_err(|e| e.annotate("voting_proposals"))?,
384 );
385 }
386 21 => {
387 if current_treasury_value.is_some() {
388 return Err(DeserializeFailure::DuplicateKey(Key::Uint(21)).into());
389 }
390 current_treasury_value = Some(
391 (|| -> Result<_, DeserializeError> {
392 read_len.read_elems(1)?;
393 Ok(Coin::deserialize(raw)?)
394 })()
395 .map_err(|e| e.annotate("current_treasury_value"))?,
396 );
397 }
398 22 => {
399 if donation.is_some() {
400 return Err(DeserializeFailure::DuplicateKey(Key::Uint(22)).into());
401 }
402 donation = Some(
403 (|| -> Result<_, DeserializeError> {
404 read_len.read_elems(1)?;
405 Ok(Coin::deserialize(raw)?)
406 })()
407 .map_err(|e| e.annotate("donation"))?,
408 );
409 }
410 unknown_key => {
411 return Err(
412 DeserializeFailure::UnknownKey(Key::Uint(unknown_key)).into()
413 )
414 }
415 },
416 CBORType::Text => match raw.text()?.as_str() {
417 unknown_key => {
418 return Err(DeserializeFailure::UnknownKey(Key::Str(
419 unknown_key.to_owned(),
420 ))
421 .into())
422 }
423 },
424 CBORType::Special => match len {
425 cbor_event::Len::Len(_) => {
426 return Err(DeserializeFailure::BreakInDefiniteLen.into())
427 }
428 cbor_event::Len::Indefinite => match raw.special()? {
429 CBORSpecial::Break => break,
430 _ => return Err(DeserializeFailure::EndingBreakMissing.into()),
431 },
432 },
433 other_type => {
434 return Err(DeserializeFailure::UnexpectedKeyType(other_type).into())
435 }
436 }
437 read += 1;
438 }
439 let inputs = match inputs {
440 Some(x) => x,
441 None => return Err(DeserializeFailure::MandatoryFieldMissing(Key::Uint(0)).into()),
442 };
443 let outputs = match outputs {
444 Some(x) => x,
445 None => return Err(DeserializeFailure::MandatoryFieldMissing(Key::Uint(1)).into()),
446 };
447 let fee = match fee {
448 Some(x) => x,
449 None => return Err(DeserializeFailure::MandatoryFieldMissing(Key::Uint(2)).into()),
450 };
451 read_len.finish()?;
452 Ok(Self {
453 inputs,
454 outputs,
455 fee,
456 ttl,
457 certs,
458 withdrawals,
459 update,
460 auxiliary_data_hash,
461 validity_start_interval,
462 mint,
463 script_data_hash,
464 collateral,
465 required_signers,
466 network_id,
467 collateral_return,
468 total_collateral,
469 reference_inputs,
470 voting_procedures,
471 voting_proposals,
472 donation,
473 current_treasury_value,
474 })
475 })()
476 .map_err(|e| e.annotate("TransactionBody"))
477 }
478}