• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tari-project / tari / 19424872350

17 Nov 2025 09:33AM UTC coverage: 51.544% (+1.0%) from 50.497%
19424872350

push

github

SWvheerden
chore: new release v5.2.0-pre.4

59181 of 114817 relevant lines covered (51.54%)

8061.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.34
/base_layer/node_components/src/blocks/chain_block.rs
1
//  Copyright 2025, The Tari Project
2
//
3
//  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
4
//  following conditions are met:
5
//
6
//  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
7
//  disclaimer.
8
//
9
//  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
10
//  following disclaimer in the documentation and/or other materials provided with the distribution.
11
//
12
//  3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
13
//  products derived from this software without specific prior written permission.
14
//
15
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
16
//  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
//  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18
//  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19
//  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
20
//  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
21
//  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22

23
use std::{fmt, fmt::Display, sync::Arc};
24

25
use tari_common_types::types::HashOutput;
26
use tari_transaction_components::aggregated_body::AggregateBody;
27

28
use crate::blocks::{Block, BlockHeader, BlockHeaderAccumulatedData};
29

30
/// A block linked to a chain.
31
/// A ChainBlock MUST have the same or stronger guarantees than `ChainHeader`
32
#[derive(Debug, Clone, PartialEq)]
33
pub struct ChainBlock {
34
    accumulated_data: BlockHeaderAccumulatedData,
35
    block: Arc<Block>,
36
}
37

38
impl Display for ChainBlock {
39
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
×
40
        writeln!(f, "{}", self.accumulated_data)?;
×
41
        writeln!(f, "{}", self.block)?;
×
42
        Ok(())
×
43
    }
×
44
}
45

46
impl ChainBlock {
47
    /// Attempts to construct a `ChainBlock` from a `Block` and associate `BlockHeaderAccumulatedData`. Returns None if
48
    /// the Block and the BlockHeaderAccumulatedData do not correspond (i.e have different hashes)
49
    pub fn try_construct(block: Arc<Block>, accumulated_data: BlockHeaderAccumulatedData) -> Option<Self> {
845✔
50
        if accumulated_data.hash != block.hash() {
845✔
51
            return None;
×
52
        }
845✔
53

54
        Some(Self {
845✔
55
            accumulated_data,
845✔
56
            block,
845✔
57
        })
845✔
58
    }
845✔
59

60
    pub fn height(&self) -> u64 {
285✔
61
        self.block.header.height
285✔
62
    }
285✔
63

64
    pub fn hash(&self) -> &HashOutput {
541✔
65
        &self.accumulated_data.hash
541✔
66
    }
541✔
67

68
    /// Returns a reference to the inner block
69
    pub fn block(&self) -> &Block {
919✔
70
        &self.block
919✔
71
    }
919✔
72

73
    /// Returns a reference to the inner block's header
74
    pub fn header(&self) -> &BlockHeader {
2,704✔
75
        &self.block.header
2,704✔
76
    }
2,704✔
77

78
    /// Returns the inner block wrapped in an atomically reference counted (ARC) pointer. This call is cheap and does
79
    /// not copy the block in memory.
80
    pub fn to_arc_block(&self) -> Arc<Block> {
271✔
81
        self.block.clone()
271✔
82
    }
271✔
83

84
    pub fn accumulated_data(&self) -> &BlockHeaderAccumulatedData {
1,080✔
85
        &self.accumulated_data
1,080✔
86
    }
1,080✔
87

88
    pub fn to_chain_header(&self) -> ChainHeader {
478✔
89
        // NOTE: Panic is impossible, a ChainBlock cannot be constructed if inconsistencies between the header and
90
        // accum data exist
91
        ChainHeader::try_construct(self.block.header.clone(), self.accumulated_data.clone()).unwrap()
478✔
92
    }
478✔
93
}
94

95
/// A block linked to a chain.
96
/// A ChainHeader guarantees (i.e cannot be constructed) that the block and accumulated data correspond by hash.
97
#[derive(Debug, Clone, PartialEq)]
98
pub struct ChainHeader {
99
    header: BlockHeader,
100
    accumulated_data: BlockHeaderAccumulatedData,
101
}
102

103
impl Display for ChainHeader {
104
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
×
105
        writeln!(f, "{}", self.header)?;
×
106
        writeln!(f, "{}", self.accumulated_data)?;
×
107
        Ok(())
×
108
    }
×
109
}
110

111
impl ChainHeader {
112
    /// Attempts to construct a `ChainHeader` from a `BlockHeader` and associate `BlockHeaderAccumulatedData`. Returns
113
    /// None if the Block and the BlockHeaderAccumulatedData do not correspond (i.e have different hashes)
114
    pub fn try_construct(header: BlockHeader, accumulated_data: BlockHeaderAccumulatedData) -> Option<Self> {
3,225✔
115
        if accumulated_data.hash != header.hash() {
3,225✔
116
            return None;
×
117
        }
3,225✔
118

119
        Some(Self {
3,225✔
120
            header,
3,225✔
121
            accumulated_data,
3,225✔
122
        })
3,225✔
123
    }
3,225✔
124

125
    pub fn height(&self) -> u64 {
1,494✔
126
        self.header.height
1,494✔
127
    }
1,494✔
128

129
    pub fn timestamp(&self) -> u64 {
571✔
130
        self.header.timestamp.as_u64()
571✔
131
    }
571✔
132

133
    pub fn hash(&self) -> &HashOutput {
995✔
134
        &self.accumulated_data.hash
995✔
135
    }
995✔
136

137
    pub fn header(&self) -> &BlockHeader {
3,110✔
138
        &self.header
3,110✔
139
    }
3,110✔
140

141
    pub fn accumulated_data(&self) -> &BlockHeaderAccumulatedData {
1,232✔
142
        &self.accumulated_data
1,232✔
143
    }
1,232✔
144

145
    pub fn into_parts(self) -> (BlockHeader, BlockHeaderAccumulatedData) {
158✔
146
        (self.header, self.accumulated_data)
158✔
147
    }
158✔
148

149
    pub fn into_header(self) -> BlockHeader {
×
150
        self.header
×
151
    }
×
152

153
    pub fn upgrade_to_chain_block(self, body: AggregateBody) -> ChainBlock {
×
154
        // NOTE: Panic cannot occur because a ChainBlock has the same guarantees as ChainHeader
155
        ChainBlock::try_construct(Arc::new(Block::new(self.header, body)), self.accumulated_data).unwrap()
×
156
    }
×
157
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc