Skip to main content

dusk_node_data/
encoding.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4//
5// Copyright (c) DUSK NETWORK. All rights reserved.
6
7use 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        // Read transactions count
57        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        // Read faults count
72        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        // Write version
93        w.write_all(&self.version.to_le_bytes())?;
94
95        // Write TxType
96        w.write_all(&self.r#type.to_le_bytes())?;
97
98        let data = self.inner.to_var_bytes();
99
100        // Write inner transaction
101        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        // Iteration is 0-based
324        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        // sign_info at the end
406        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    /// Asserts if encoding/decoding of a serializable type runs properly.
495    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()); // block_height
549            bytes.extend_from_slice(&456_u64.to_le_bytes()); // gas_spent
550            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()); // version
616        tx_bytes.extend_from_slice(&1_u32.to_le_bytes()); // tx type
617        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()); // tx_len
642        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}