1use std::io::{self, Read, Write};
8
9use dusk_core::transfer::Transaction as ProtocolTransaction;
10
11use crate::Serializable;
12use crate::bls::PublicKeyBytes;
13use crate::ledger::{
14 Attestation, Block, Fault, Header, IterationsInfo, Label, Signature,
15 SpentTransaction, StepVotes, Transaction,
16};
17use crate::message::payload::{
18 QuorumType, Ratification, RatificationResult, ValidationQuorum,
19 ValidationResult, Vote,
20};
21use crate::message::{
22 ConsensusHeader, MESSAGE_MAX_FAILED_ITERATIONS, SignInfo,
23};
24use crate::{
25 MAX_NUMBER_OF_FAULTS, MAX_NUMBER_OF_TRANSACTIONS, MAX_SPENT_TX_ERROR_BYTES,
26};
27
28const MAX_TX_LENGTH_BYTES: usize = 2 * 1024 * 1024;
29
30impl Serializable for Block {
31 fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
32 self.header().write(w)?;
33
34 let txs_len = self.txs().len() as u32;
35 w.write_all(&txs_len.to_le_bytes())?;
36
37 for t in self.txs().iter() {
38 t.write(w)?;
39 }
40
41 let faults_len = self.faults().len() as u32;
42 w.write_all(&faults_len.to_le_bytes())?;
43
44 for f in self.faults().iter() {
45 f.write(w)?;
46 }
47 Ok(())
48 }
49
50 fn read<R: Read>(r: &mut R) -> io::Result<Self>
51 where
52 Self: Sized,
53 {
54 let header = Header::read(r)?;
55
56 let tx_len = Self::read_u32_le(r)?;
58 if tx_len as usize > MAX_NUMBER_OF_TRANSACTIONS {
59 return Err(io::Error::new(
60 io::ErrorKind::InvalidData,
61 format!(
62 "too many block transactions: {tx_len} > {MAX_NUMBER_OF_TRANSACTIONS}"
63 ),
64 ));
65 }
66
67 let txs = (0..tx_len)
68 .map(|_| Transaction::read(r))
69 .collect::<Result<Vec<_>, _>>()?;
70
71 let faults_len = Self::read_u32_le(r)?;
73 if faults_len as usize > MAX_NUMBER_OF_FAULTS {
74 return Err(io::Error::new(
75 io::ErrorKind::InvalidData,
76 format!(
77 "too many block faults: {faults_len} > {MAX_NUMBER_OF_FAULTS}"
78 ),
79 ));
80 }
81
82 let faults = (0..faults_len)
83 .map(|_| Fault::read(r))
84 .collect::<Result<Vec<_>, _>>()?;
85
86 Block::new(header, txs, faults)
87 }
88}
89
90impl Serializable for Transaction {
91 fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
92 w.write_all(&self.version.to_le_bytes())?;
94
95 w.write_all(&self.r#type.to_le_bytes())?;
97
98 let data = self.inner.to_var_bytes();
99
100 Self::write_var_le_bytes32(w, &data)?;
102
103 Ok(())
104 }
105
106 fn read<R: Read>(r: &mut R) -> io::Result<Self>
107 where
108 Self: Sized,
109 {
110 let version = Self::read_u32_le(r)?;
111 let tx_type = Self::read_u32_le(r)?;
112
113 let protocol_tx = Self::read_var_le_bytes32(r, MAX_TX_LENGTH_BYTES)?;
114 let tx_size = protocol_tx.len();
115 let inner = ProtocolTransaction::from_slice(&protocol_tx[..])
116 .map_err(|_| io::Error::from(io::ErrorKind::InvalidData))?;
117
118 Ok(Self {
119 inner,
120 version,
121 r#type: tx_type,
122 size: Some(tx_size),
123 })
124 }
125}
126
127impl Serializable for SpentTransaction {
128 fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
129 self.inner.write(w)?;
130 w.write_all(&self.block_height.to_le_bytes())?;
131 w.write_all(&self.gas_spent.to_le_bytes())?;
132
133 match &self.err {
134 Some(e) => {
135 let b = e.as_bytes();
136 w.write_all(&(b.len() as u32).to_le_bytes())?;
137 w.write_all(b)?;
138 }
139 None => {
140 w.write_all(&0_u32.to_le_bytes())?;
141 }
142 }
143
144 Ok(())
145 }
146
147 fn read<R: Read>(r: &mut R) -> io::Result<Self>
148 where
149 Self: Sized,
150 {
151 let inner = Transaction::read(r)?;
152
153 let block_height = Self::read_u64_le(r)?;
154 let gas_spent = Self::read_u64_le(r)?;
155 let error_len = Self::read_u32_le(r)?;
156 if error_len as usize > MAX_SPENT_TX_ERROR_BYTES {
157 return Err(io::Error::new(
158 io::ErrorKind::InvalidData,
159 format!(
160 "SpentTransaction error string too large: {error_len} > {MAX_SPENT_TX_ERROR_BYTES}"
161 ),
162 ));
163 }
164
165 let err = if error_len > 0 {
166 let mut buf = vec![0u8; error_len as usize];
167 r.read_exact(&mut buf[..])?;
168
169 Some(String::from_utf8(buf).map_err(|_| {
170 io::Error::new(
171 io::ErrorKind::InvalidData,
172 "invalid utf-8 in SpentTransaction error string",
173 )
174 })?)
175 } else {
176 None
177 };
178
179 Ok(Self {
180 inner,
181 block_height,
182 gas_spent,
183 err,
184 })
185 }
186}
187
188impl Serializable for Header {
189 fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
190 self.marshal_hashable(w)?;
191 self.att.write(w)?;
192 w.write_all(&self.hash)?;
193 w.write_all(self.signature.inner())?;
194
195 Ok(())
196 }
197
198 fn read<R: Read>(r: &mut R) -> io::Result<Self>
199 where
200 Self: Sized,
201 {
202 let mut header = Self::unmarshal_hashable(r)?;
203 header.att = Attestation::read(r)?;
204 header.hash = Self::read_bytes(r)?;
205 header.signature = Signature::from(Self::read_bytes(r)?);
206 Ok(header)
207 }
208}
209
210impl Serializable for Attestation {
211 fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
212 self.result.write(w)?;
213 self.validation.write(w)?;
214 self.ratification.write(w)?;
215
216 Ok(())
217 }
218
219 fn read<R: Read>(r: &mut R) -> io::Result<Self>
220 where
221 Self: Sized,
222 {
223 let result = RatificationResult::read(r)?;
224 let validation = StepVotes::read(r)?;
225 let ratification = StepVotes::read(r)?;
226
227 Ok(Attestation {
228 result,
229 validation,
230 ratification,
231 })
232 }
233}
234
235impl Serializable for StepVotes {
236 fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
237 w.write_all(&self.bitset.to_le_bytes())?;
238 w.write_all(self.aggregate_signature.inner())?;
239
240 Ok(())
241 }
242
243 fn read<R: Read>(r: &mut R) -> io::Result<Self>
244 where
245 Self: Sized,
246 {
247 let bitset = Self::read_u64_le(r)?;
248 let aggregate_signature = Self::read_bytes(r)?;
249
250 Ok(StepVotes {
251 bitset,
252 aggregate_signature: aggregate_signature.into(),
253 })
254 }
255}
256
257impl Serializable for RatificationResult {
258 fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
259 match self {
260 RatificationResult::Fail(v) => {
261 w.write_all(&[0])?;
262 v.write(w)?;
263 }
264
265 RatificationResult::Success(v) => {
266 w.write_all(&[1])?;
267 v.write(w)?;
268 }
269 }
270
271 Ok(())
272 }
273
274 fn read<R: Read>(r: &mut R) -> io::Result<Self>
275 where
276 Self: Sized,
277 {
278 let result = match Self::read_u8(r)? {
279 0 => {
280 let vote = Vote::read(r)?;
281 Self::Fail(vote)
282 }
283 1 => {
284 let vote = Vote::read(r)?;
285 Self::Success(vote)
286 }
287 _ => Err(io::Error::new(
288 io::ErrorKind::InvalidData,
289 "Invalid RatificationResult",
290 ))?,
291 };
292 Ok(result)
293 }
294}
295
296impl Serializable for IterationsInfo {
297 fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
298 let count = self.att_list.len() as u8;
299 w.write_all(&count.to_le_bytes())?;
300
301 for iter in &self.att_list {
302 match iter {
303 Some((att, pk)) => {
304 w.write_all(&[1])?;
305 att.write(w)?;
306 w.write_all(pk.inner())?;
307 }
308 None => w.write_all(&[0])?,
309 }
310 }
311
312 Ok(())
313 }
314
315 fn read<R: Read>(r: &mut R) -> io::Result<Self>
316 where
317 Self: Sized,
318 {
319 let mut att_list = vec![];
320
321 let count = Self::read_u8(r)?;
322
323 if count > MESSAGE_MAX_FAILED_ITERATIONS {
325 return Err(io::Error::new(
326 io::ErrorKind::InvalidData,
327 format!("Invalid iterations_info count {count})"),
328 ));
329 }
330
331 for _ in 0..count {
332 let opt = Self::read_u8(r)?;
333
334 let att = match opt {
335 0 => None,
336 1 => {
337 let att = Attestation::read(r)?;
338 let pk = Self::read_bytes(r)?;
339 Some((att, PublicKeyBytes(pk)))
340 }
341 _ => {
342 return Err(io::Error::new(
343 io::ErrorKind::InvalidData,
344 "Invalid option",
345 ));
346 }
347 };
348 att_list.push(att)
349 }
350
351 Ok(IterationsInfo { att_list })
352 }
353}
354
355impl Serializable for Label {
356 fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
357 match self {
358 Label::Accepted(v) => {
359 w.write_all(&0u8.to_le_bytes())?;
360 w.write_all(&v.to_le_bytes())?;
361 }
362 Label::Attested(v) => {
363 w.write_all(&1u8.to_le_bytes())?;
364 w.write_all(&v.to_le_bytes())?;
365 }
366 Label::Confirmed(v) => {
367 w.write_all(&2u8.to_le_bytes())?;
368 w.write_all(&v.to_le_bytes())?;
369 }
370 Label::Final(v) => {
371 w.write_all(&3u8.to_le_bytes())?;
372 w.write_all(&v.to_le_bytes())?;
373 }
374 }
375
376 Ok(())
377 }
378
379 fn read<R: Read>(r: &mut R) -> io::Result<Self>
380 where
381 Self: Sized,
382 {
383 let label = Self::read_u8(r)?;
384 let label = match label {
385 0 => Label::Accepted(Self::read_u64_le(r)?),
386 1 => Label::Attested(Self::read_u64_le(r)?),
387 2 => Label::Confirmed(Self::read_u64_le(r)?),
388 3 => Label::Final(Self::read_u64_le(r)?),
389 _ => Err(io::Error::new(
390 io::ErrorKind::InvalidData,
391 "Invalid label",
392 ))?,
393 };
394
395 Ok(label)
396 }
397}
398
399impl Serializable for Ratification {
400 fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
401 self.header.write(w)?;
402 self.vote.write(w)?;
403 w.write_all(&self.timestamp.to_le_bytes())?;
404 self.validation_result.write(w)?;
405 self.sign_info.write(w)?;
407
408 Ok(())
409 }
410
411 fn read<R: Read>(r: &mut R) -> io::Result<Self>
412 where
413 Self: Sized,
414 {
415 let header = ConsensusHeader::read(r)?;
416 let vote = Vote::read(r)?;
417 let timestamp = Self::read_u64_le(r)?;
418 let validation_result = ValidationResult::read(r)?;
419 let sign_info = SignInfo::read(r)?;
420
421 Ok(Ratification {
422 header,
423 vote,
424 sign_info,
425 timestamp,
426 validation_result,
427 })
428 }
429}
430
431impl Serializable for ValidationResult {
432 fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
433 self.step_votes.write(w)?;
434 self.vote.write(w)?;
435 self.quorum.write(w)?;
436
437 Ok(())
438 }
439
440 fn read<R: Read>(r: &mut R) -> io::Result<Self>
441 where
442 Self: Sized,
443 {
444 let step_votes: StepVotes = StepVotes::read(r)?;
445 let vote = Vote::read(r)?;
446 let quorum = QuorumType::read(r)?;
447
448 Ok(ValidationResult::new(step_votes, vote, quorum))
449 }
450}
451
452impl Serializable for ValidationQuorum {
453 fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
454 self.header.write(w)?;
455 self.result.write(w)?;
456
457 Ok(())
458 }
459
460 fn read<R: Read>(r: &mut R) -> io::Result<Self>
461 where
462 Self: Sized,
463 {
464 let header = ConsensusHeader::read(r)?;
465 let result = ValidationResult::read(r)?;
466
467 Ok(ValidationQuorum { header, result })
468 }
469}
470
471impl Serializable for QuorumType {
472 fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
473 let val: u8 = *self as u8;
474 w.write_all(&val.to_le_bytes())
475 }
476
477 fn read<R: Read>(r: &mut R) -> io::Result<Self>
478 where
479 Self: Sized,
480 {
481 Ok(Self::read_u8(r)?.into())
482 }
483}
484
485#[cfg(test)]
486mod tests {
487 use std::io;
488
489 use fake::{Dummy, Fake, Faker};
490
491 use super::*;
492 use crate::message::payload::{Candidate, Validation};
493
494 fn assert_serializable<S: Dummy<Faker> + Eq + Serializable>() {
496 let obj: S = Faker.fake();
497 let mut buf = vec![];
498 obj.write(&mut buf).expect("should be writable");
499
500 assert!(obj.eq(&S::read(&mut &buf[..]).expect("should be readable")));
501 }
502
503 #[test]
504 fn test_encoding_iterations_info() {
505 assert_serializable::<IterationsInfo>();
506 }
507
508 #[test]
509 fn test_encoding_ratification() {
510 assert_serializable::<Ratification>();
511 }
512
513 #[test]
514 fn test_encoding_validation() {
515 assert_serializable::<Validation>();
516 }
517
518 #[test]
519 fn test_encoding_candidate() {
520 assert_serializable::<Candidate>();
521 }
522
523 #[test]
524 fn test_encoding_att() {
525 assert_serializable::<Attestation>();
526 }
527
528 #[test]
529 fn test_encoding_transaction() {
530 assert_serializable::<Transaction>();
531 }
532
533 #[test]
534 fn test_encoding_spent_transaction() {
535 assert_serializable::<SpentTransaction>();
536 }
537
538 #[test]
539 fn test_spent_transaction_rejects_malformed_error_string() {
540 fn decode_err(
541 tx: &Transaction,
542 error_len: u32,
543 error_bytes: &[u8],
544 ) -> io::Result<SpentTransaction> {
545 let mut bytes = vec![];
546 tx.write(&mut bytes)
547 .expect("transaction encoding should succeed");
548 bytes.extend_from_slice(&123_u64.to_le_bytes()); bytes.extend_from_slice(&456_u64.to_le_bytes()); bytes.extend_from_slice(&error_len.to_le_bytes());
551 bytes.extend_from_slice(error_bytes);
552 SpentTransaction::read(&mut &bytes[..])
553 }
554
555 let tx: Transaction = Faker.fake();
556
557 let err = decode_err(&tx, 2, &[0xFF, 0xFF])
558 .expect_err("invalid utf-8 error bytes must be rejected");
559 assert_eq!(err.kind(), io::ErrorKind::InvalidData);
560
561 let err = decode_err(&tx, (MAX_SPENT_TX_ERROR_BYTES as u32) + 1, &[])
562 .expect_err("oversized error string must be rejected");
563 assert_eq!(err.kind(), io::ErrorKind::InvalidData);
564 }
565
566 #[test]
567 fn test_spent_transaction_none_error_encoding_has_no_trailing_bytes() {
568 let mut spent_tx: SpentTransaction = Faker.fake();
569 spent_tx.err = None;
570
571 let mut bytes = vec![];
572 spent_tx
573 .write(&mut bytes)
574 .expect("spent transaction encoding should succeed");
575
576 let mut slice = &bytes[..];
577 let decoded = SpentTransaction::read(&mut slice)
578 .expect("spent transaction decoding should succeed");
579 assert!(decoded.err.is_none());
580 assert!(slice.is_empty(), "deserializer left trailing bytes");
581 }
582
583 #[test]
584 fn test_encoding_header() {
585 assert_serializable::<ConsensusHeader>();
586 }
587
588 #[test]
589 fn test_encoding_block() {
590 assert_serializable::<Block>();
591 }
592
593 #[test]
594 fn test_encoding_ratification_result() {
595 assert_serializable::<RatificationResult>();
596 }
597
598 #[test]
599 fn test_encoding_fault() {
600 assert_serializable::<Fault>();
601 }
602
603 #[test]
604 fn test_rejects_oversized_lengths() {
605 fn assert_invalid_data<T>(result: io::Result<T>, reason: &str) {
606 match result {
607 Ok(_) => panic!("{reason}"),
608 Err(err) => {
609 assert_eq!(err.kind(), io::ErrorKind::InvalidData);
610 }
611 }
612 }
613
614 let mut tx_bytes = vec![];
615 tx_bytes.extend_from_slice(&1_u32.to_le_bytes()); tx_bytes.extend_from_slice(&1_u32.to_le_bytes()); tx_bytes.extend_from_slice(
618 &((MAX_TX_LENGTH_BYTES as u32) + 1).to_le_bytes(),
619 );
620 assert_invalid_data(
621 Transaction::read(&mut &tx_bytes[..]),
622 "oversized length-prefixed tx payload must be rejected",
623 );
624
625 let mut block_txs_bytes = vec![];
626 Header::default()
627 .write(&mut block_txs_bytes)
628 .expect("header encoding should succeed");
629 block_txs_bytes.extend_from_slice(
630 &((MAX_NUMBER_OF_TRANSACTIONS as u32) + 1).to_le_bytes(),
631 );
632 assert_invalid_data(
633 Block::read(&mut &block_txs_bytes[..]),
634 "block with too many transactions must be rejected",
635 );
636
637 let mut block_faults_bytes = vec![];
638 Header::default()
639 .write(&mut block_faults_bytes)
640 .expect("header encoding should succeed");
641 block_faults_bytes.extend_from_slice(&0_u32.to_le_bytes()); block_faults_bytes.extend_from_slice(
643 &((MAX_NUMBER_OF_FAULTS as u32) + 1).to_le_bytes(),
644 );
645 assert_invalid_data(
646 Block::read(&mut &block_faults_bytes[..]),
647 "block with too many faults must be rejected",
648 );
649 }
650}