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