chia_protocol/
header_block.rs

1use chia_streamable_macro::streamable;
2
3use crate::unfinished_header_block::UnfinishedHeaderBlock;
4use crate::Bytes;
5use crate::Bytes32;
6use crate::EndOfSubSlotBundle;
7use crate::RewardChainBlock;
8use crate::VDFProof;
9use crate::{Foliage, FoliageTransactionBlock, TransactionsInfo};
10use chia_traits::Streamable;
11
12#[streamable]
13pub struct HeaderBlock {
14    // If first sb
15    finished_sub_slots: Vec<EndOfSubSlotBundle>,
16    // Reward chain trunk data
17    reward_chain_block: RewardChainBlock,
18    // If not first sp in sub-slot
19    challenge_chain_sp_proof: Option<VDFProof>,
20    challenge_chain_ip_proof: VDFProof,
21    // If not first sp in sub-slot
22    reward_chain_sp_proof: Option<VDFProof>,
23    reward_chain_ip_proof: VDFProof,
24    // Iff deficit < 4
25    infused_challenge_chain_ip_proof: Option<VDFProof>,
26    // Reward chain foliage data
27    foliage: Foliage,
28    // Reward chain foliage data (tx block)
29    foliage_transaction_block: Option<FoliageTransactionBlock>,
30    // Filter for block transactions
31    transactions_filter: Bytes,
32    // Reward chain foliage data (tx block additional)
33    transactions_info: Option<TransactionsInfo>,
34}
35
36impl HeaderBlock {
37    pub fn prev_header_hash(&self) -> Bytes32 {
38        self.foliage.prev_block_hash
39    }
40
41    pub fn prev_hash(&self) -> Bytes32 {
42        self.foliage.prev_block_hash
43    }
44
45    pub fn height(&self) -> u32 {
46        self.reward_chain_block.height
47    }
48
49    pub fn weight(&self) -> u128 {
50        self.reward_chain_block.weight
51    }
52
53    pub fn header_hash(&self) -> Bytes32 {
54        self.foliage.hash().into()
55    }
56
57    pub fn total_iters(&self) -> u128 {
58        self.reward_chain_block.total_iters
59    }
60
61    pub fn log_string(&self) -> String {
62        format!(
63            "block {:?} sb_height {} ",
64            self.header_hash(),
65            self.height()
66        )
67    }
68
69    pub fn is_transaction_block(&self) -> bool {
70        self.reward_chain_block.is_transaction_block
71    }
72
73    pub fn first_in_sub_slot(&self) -> bool {
74        !self.finished_sub_slots.is_empty()
75    }
76
77    pub fn into_unfinished_header_block(self) -> UnfinishedHeaderBlock {
78        UnfinishedHeaderBlock {
79            finished_sub_slots: self.finished_sub_slots,
80            reward_chain_block: self.reward_chain_block.get_unfinished(),
81            challenge_chain_sp_proof: self.challenge_chain_sp_proof,
82            reward_chain_sp_proof: self.reward_chain_sp_proof,
83            foliage: self.foliage,
84            foliage_transaction_block: self.foliage_transaction_block,
85            transactions_filter: self.transactions_filter,
86        }
87    }
88}
89
90#[cfg(feature = "py-bindings")]
91use chia_traits::ChiaToPython;
92#[cfg(feature = "py-bindings")]
93use pyo3::prelude::*;
94
95#[cfg(feature = "py-bindings")]
96#[pymethods]
97impl HeaderBlock {
98    #[getter]
99    #[pyo3(name = "prev_header_hash")]
100    fn py_prev_header_hash(&self) -> Bytes32 {
101        self.prev_header_hash()
102    }
103
104    #[getter]
105    #[pyo3(name = "prev_hash")]
106    fn py_prev_hash(&self) -> Bytes32 {
107        self.prev_hash()
108    }
109
110    #[getter]
111    #[pyo3(name = "height")]
112    fn py_height<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyAny>> {
113        ChiaToPython::to_python(&self.height(), py)
114    }
115
116    #[getter]
117    #[pyo3(name = "weight")]
118    fn py_weight<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyAny>> {
119        ChiaToPython::to_python(&self.weight(), py)
120    }
121
122    #[getter]
123    #[pyo3(name = "header_hash")]
124    fn py_header_hash(&self) -> Bytes32 {
125        self.header_hash()
126    }
127
128    #[getter]
129    #[pyo3(name = "total_iters")]
130    fn py_total_iters<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyAny>> {
131        ChiaToPython::to_python(&self.total_iters(), py)
132    }
133
134    #[getter]
135    #[pyo3(name = "log_string")]
136    fn py_log_string(&self) -> String {
137        self.log_string()
138    }
139
140    #[getter]
141    #[pyo3(name = "is_transaction_block")]
142    fn py_is_transaction_block(&self) -> bool {
143        self.is_transaction_block()
144    }
145
146    #[getter]
147    #[pyo3(name = "first_in_sub_slot")]
148    fn py_first_in_sub_slot(&self) -> bool {
149        self.first_in_sub_slot()
150    }
151}