chia_protocol/
fullblock.rs

1use chia_streamable_macro::streamable;
2
3use crate::Bytes32;
4use crate::Coin;
5use crate::EndOfSubSlotBundle;
6use crate::Program;
7use crate::RewardChainBlock;
8use crate::VDFProof;
9use crate::{Foliage, FoliageTransactionBlock, TransactionsInfo};
10use chia_traits::Streamable;
11
12#[streamable]
13pub struct FullBlock {
14    finished_sub_slots: Vec<EndOfSubSlotBundle>,
15    reward_chain_block: RewardChainBlock,
16    challenge_chain_sp_proof: Option<VDFProof>, // # If not first sp in sub-slot
17    challenge_chain_ip_proof: VDFProof,
18    reward_chain_sp_proof: Option<VDFProof>, // # If not first sp in sub-slot
19    reward_chain_ip_proof: VDFProof,
20    infused_challenge_chain_ip_proof: Option<VDFProof>, // # Iff deficit < 4
21    foliage: Foliage,                                   // # Reward chain foliage data
22    foliage_transaction_block: Option<FoliageTransactionBlock>, // # Reward chain foliage data (tx block)
23    transactions_info: Option<TransactionsInfo>, // Reward chain foliage data (tx block additional)
24    transactions_generator: Option<Program>,     // Program that generates transactions
25    transactions_generator_ref_list: Vec<u32>, // List of block heights of previous generators referenced in this block
26}
27
28impl FullBlock {
29    pub fn prev_header_hash(&self) -> Bytes32 {
30        self.foliage.prev_block_hash
31    }
32
33    pub fn header_hash(&self) -> Bytes32 {
34        self.foliage.hash().into()
35    }
36
37    pub fn is_transaction_block(&self) -> bool {
38        self.foliage.foliage_transaction_block_hash.is_some()
39    }
40
41    pub fn total_iters(&self) -> u128 {
42        self.reward_chain_block.total_iters
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 get_included_reward_coins(&self) -> Vec<Coin> {
54        if let Some(ti) = &self.transactions_info {
55            ti.reward_claims_incorporated.clone()
56        } else {
57            vec![]
58        }
59    }
60
61    pub fn is_fully_compactified(&self) -> bool {
62        for sub_slot in &self.finished_sub_slots {
63            if sub_slot.proofs.challenge_chain_slot_proof.witness_type != 0
64                || !sub_slot
65                    .proofs
66                    .challenge_chain_slot_proof
67                    .normalized_to_identity
68            {
69                return false;
70            }
71            if let Some(proof) = &sub_slot.proofs.infused_challenge_chain_slot_proof {
72                if proof.witness_type != 0 || !proof.normalized_to_identity {
73                    return false;
74                }
75            }
76        }
77
78        if let Some(proof) = &self.challenge_chain_sp_proof {
79            if proof.witness_type != 0 || !proof.normalized_to_identity {
80                return false;
81            }
82        }
83        self.challenge_chain_ip_proof.witness_type == 0
84            && self.challenge_chain_ip_proof.normalized_to_identity
85    }
86}
87
88#[cfg(feature = "py-bindings")]
89use chia_traits::ChiaToPython;
90#[cfg(feature = "py-bindings")]
91use pyo3::prelude::*;
92
93#[cfg(feature = "py-bindings")]
94#[pymethods]
95impl FullBlock {
96    #[getter]
97    #[pyo3(name = "prev_header_hash")]
98    fn py_prev_header_hash(&self) -> Bytes32 {
99        self.prev_header_hash()
100    }
101
102    #[getter]
103    #[pyo3(name = "header_hash")]
104    fn py_header_hash(&self) -> Bytes32 {
105        self.header_hash()
106    }
107
108    #[pyo3(name = "is_transaction_block")]
109    fn py_is_transaction_block(&self) -> bool {
110        self.is_transaction_block()
111    }
112
113    #[getter]
114    #[pyo3(name = "total_iters")]
115    fn py_total_iters<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyAny>> {
116        ChiaToPython::to_python(&self.total_iters(), py)
117    }
118
119    #[getter]
120    #[pyo3(name = "height")]
121    fn py_height<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyAny>> {
122        ChiaToPython::to_python(&self.height(), py)
123    }
124
125    #[getter]
126    #[pyo3(name = "weight")]
127    fn py_weight<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyAny>> {
128        ChiaToPython::to_python(&self.weight(), py)
129    }
130
131    #[pyo3(name = "get_included_reward_coins")]
132    fn py_get_included_reward_coins(&self) -> Vec<Coin> {
133        self.get_included_reward_coins()
134    }
135
136    #[pyo3(name = "is_fully_compactified")]
137    fn py_is_fully_compactified(&self) -> bool {
138        self.is_fully_compactified()
139    }
140}