dusk_node_data/ledger/
block.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 super::*;
8
9pub type Hash = [u8; 32];
10pub type Bloom = [u8; 256];
11
12#[derive(Default, Debug, Clone)]
13pub struct Block {
14    header: Header,
15    txs: Vec<Transaction>,
16    faults: Vec<Fault>,
17}
18
19impl PartialEq<Self> for Block {
20    fn eq(&self, other: &Self) -> bool {
21        self.header.hash == other.header.hash
22    }
23}
24
25impl Eq for Block {}
26
27impl Block {
28    /// Creates a new block and calculates block hash, if missing.
29    pub fn new(
30        header: Header,
31        txs: Vec<Transaction>,
32        faults: Vec<Fault>,
33    ) -> io::Result<Self> {
34        let mut b = Block {
35            header,
36            txs,
37            faults,
38        };
39        b.calculate_hash()?;
40        Ok(b)
41    }
42
43    fn calculate_hash(&mut self) -> io::Result<()> {
44        // Call hasher only if header.hash is empty
45        if self.header.hash != Hash::default() {
46            return Ok(());
47        }
48
49        let mut hasher = sha3::Sha3_256::new();
50        self.header.marshal_hashable(&mut hasher)?;
51
52        self.header.hash = hasher.finalize().into();
53        Ok(())
54    }
55
56    pub fn header(&self) -> &Header {
57        &self.header
58    }
59    pub fn txs(&self) -> &Vec<Transaction> {
60        &self.txs
61    }
62    pub fn faults(&self) -> &Vec<Fault> {
63        &self.faults
64    }
65
66    pub fn set_attestation(&mut self, att: Attestation) {
67        self.header.att = att;
68    }
69
70    pub fn size(&self) -> io::Result<usize> {
71        let mut buf = vec![];
72        self.write(&mut buf)?;
73        Ok(buf.len())
74    }
75
76    pub fn set_signature(&mut self, signature: Signature) {
77        self.header.signature = signature;
78    }
79}
80
81#[derive(Debug, Clone, Copy, PartialEq)]
82pub enum Label {
83    Accepted(u64),
84    Attested(u64),
85    Confirmed(u64),
86    Final(u64),
87}
88
89/// Immutable view of a labelled block that is/(should be) persisted
90#[derive(Debug, Clone)]
91pub struct BlockWithLabel {
92    blk: Block,
93    label: Label,
94}
95
96impl BlockWithLabel {
97    pub fn new_with_label(blk: Block, label: Label) -> Self {
98        Self { blk, label }
99    }
100    pub fn inner(&self) -> &Block {
101        &self.blk
102    }
103    pub fn label(&self) -> Label {
104        self.label
105    }
106    pub fn is_final(&self) -> bool {
107        matches!(self.label(), Label::Final(_)) || self.blk.header().height == 0
108    }
109}
110
111#[cfg(any(feature = "faker", test))]
112pub mod faker {
113    use rand::Rng;
114    use transaction::faker::gen_dummy_tx;
115
116    use super::*;
117
118    impl<T> Dummy<T> for Block {
119        /// Creates a block with 3 transactions and a random header.
120        fn dummy_with_rng<R: Rng + ?Sized>(_config: &T, rng: &mut R) -> Self {
121            let txs = vec![
122                gen_dummy_tx(rng.gen()),
123                gen_dummy_tx(rng.gen()),
124                gen_dummy_tx(rng.gen()),
125            ];
126            let header: Header = Faker.fake();
127            let faults = vec![Faker.fake(), Faker.fake(), Faker.fake()];
128
129            Block::new(header, txs, faults).expect("valid hash")
130        }
131    }
132}