chia_protocol/
reward_chain_block.rs

1use chia_streamable_macro::streamable;
2
3use crate::Bytes32;
4use crate::ProofOfSpace;
5use crate::VDFInfo;
6use chia_bls::G2Element;
7use chia_sha2::Sha256;
8use chia_traits::{Result, Streamable};
9use std::io::Cursor;
10
11use crate::utils::{parse, stream, update_digest};
12
13#[cfg(feature = "py-bindings")]
14use pyo3::prelude::*;
15
16#[streamable]
17pub struct RewardChainBlockUnfinished {
18    total_iters: u128,
19    signage_point_index: u8,
20    pos_ss_cc_challenge_hash: Bytes32,
21    proof_of_space: ProofOfSpace,
22    challenge_chain_sp_vdf: Option<VDFInfo>, // Not present for first sp in slot
23    challenge_chain_sp_signature: G2Element,
24    reward_chain_sp_vdf: Option<VDFInfo>, // Not present for first sp in slot
25    reward_chain_sp_signature: G2Element,
26}
27
28#[streamable(no_streamable)]
29pub struct RewardChainBlock {
30    weight: u128,
31    height: u32,
32    total_iters: u128,
33    signage_point_index: u8,
34    pos_ss_cc_challenge_hash: Bytes32,
35    proof_of_space: ProofOfSpace,
36    challenge_chain_sp_vdf: Option<VDFInfo>, // Not present for first sp in slot
37    challenge_chain_sp_signature: G2Element,
38    challenge_chain_ip_vdf: VDFInfo,
39    reward_chain_sp_vdf: Option<VDFInfo>, // Not present for first sp in slot
40    reward_chain_sp_signature: G2Element,
41    reward_chain_ip_vdf: VDFInfo,
42    infused_challenge_chain_ip_vdf: Option<VDFInfo>, // Iff deficit < 16
43    header_mmr_root: Option<Bytes32>,
44    is_transaction_block: bool,
45}
46
47impl Streamable for RewardChainBlock {
48    fn update_digest(&self, digest: &mut Sha256) {
49        self.weight.update_digest(digest);
50        self.height.update_digest(digest);
51        self.total_iters.update_digest(digest);
52        self.signage_point_index.update_digest(digest);
53        self.pos_ss_cc_challenge_hash.update_digest(digest);
54        self.proof_of_space.update_digest(digest);
55        self.challenge_chain_sp_vdf.update_digest(digest);
56        self.challenge_chain_sp_signature.update_digest(digest);
57        self.challenge_chain_ip_vdf.update_digest(digest);
58        self.reward_chain_sp_vdf.update_digest(digest);
59        self.reward_chain_sp_signature.update_digest(digest);
60        self.reward_chain_ip_vdf.update_digest(digest);
61        update_digest(
62            self.infused_challenge_chain_ip_vdf.as_ref(),
63            self.header_mmr_root.as_ref(),
64            digest,
65        );
66        self.is_transaction_block.update_digest(digest);
67    }
68
69    fn stream(&self, out: &mut Vec<u8>) -> Result<()> {
70        self.weight.stream(out)?;
71        self.height.stream(out)?;
72        self.total_iters.stream(out)?;
73        self.signage_point_index.stream(out)?;
74        self.pos_ss_cc_challenge_hash.stream(out)?;
75        self.proof_of_space.stream(out)?;
76        self.challenge_chain_sp_vdf.stream(out)?;
77        self.challenge_chain_sp_signature.stream(out)?;
78        self.challenge_chain_ip_vdf.stream(out)?;
79        self.reward_chain_sp_vdf.stream(out)?;
80        self.reward_chain_sp_signature.stream(out)?;
81        self.reward_chain_ip_vdf.stream(out)?;
82        stream(
83            self.infused_challenge_chain_ip_vdf.as_ref(),
84            self.header_mmr_root.as_ref(),
85            out,
86        )?;
87        self.is_transaction_block.stream(out)?;
88        Ok(())
89    }
90
91    fn parse<const TRUSTED: bool>(input: &mut Cursor<&[u8]>) -> Result<Self> {
92        let weight = <u128 as Streamable>::parse::<TRUSTED>(input)?;
93        let height = <u32 as Streamable>::parse::<TRUSTED>(input)?;
94        let total_iters = <u128 as Streamable>::parse::<TRUSTED>(input)?;
95        let signage_point_index = <u8 as Streamable>::parse::<TRUSTED>(input)?;
96        let pos_ss_cc_challenge_hash = <Bytes32 as Streamable>::parse::<TRUSTED>(input)?;
97        let proof_of_space = <ProofOfSpace as Streamable>::parse::<TRUSTED>(input)?;
98        let challenge_chain_sp_vdf = <Option<VDFInfo> as Streamable>::parse::<TRUSTED>(input)?;
99        let challenge_chain_sp_signature = <G2Element as Streamable>::parse::<TRUSTED>(input)?;
100        let challenge_chain_ip_vdf = <VDFInfo as Streamable>::parse::<TRUSTED>(input)?;
101        let reward_chain_sp_vdf = <Option<VDFInfo> as Streamable>::parse::<TRUSTED>(input)?;
102        let reward_chain_sp_signature = <G2Element as Streamable>::parse::<TRUSTED>(input)?;
103        let reward_chain_ip_vdf = <VDFInfo as Streamable>::parse::<TRUSTED>(input)?;
104        let (infused_challenge_chain_ip_vdf, header_mmr_root) =
105            parse::<TRUSTED, VDFInfo, Bytes32>(input)?;
106        let is_transaction_block = <bool as Streamable>::parse::<TRUSTED>(input)?;
107
108        Ok(Self {
109            weight,
110            height,
111            total_iters,
112            signage_point_index,
113            pos_ss_cc_challenge_hash,
114            proof_of_space,
115            challenge_chain_sp_vdf,
116            challenge_chain_sp_signature,
117            challenge_chain_ip_vdf,
118            reward_chain_sp_vdf,
119            reward_chain_sp_signature,
120            reward_chain_ip_vdf,
121            infused_challenge_chain_ip_vdf,
122            header_mmr_root,
123            is_transaction_block,
124        })
125    }
126}
127
128#[cfg_attr(feature = "py-bindings", pymethods)]
129impl RewardChainBlock {
130    pub fn get_unfinished(&self) -> RewardChainBlockUnfinished {
131        RewardChainBlockUnfinished {
132            total_iters: self.total_iters,
133            signage_point_index: self.signage_point_index,
134            pos_ss_cc_challenge_hash: self.pos_ss_cc_challenge_hash,
135            proof_of_space: self.proof_of_space.clone(),
136            challenge_chain_sp_vdf: self.challenge_chain_sp_vdf.clone(),
137            challenge_chain_sp_signature: self.challenge_chain_sp_signature.clone(),
138            reward_chain_sp_vdf: self.reward_chain_sp_vdf.clone(),
139            reward_chain_sp_signature: self.reward_chain_sp_signature.clone(),
140        }
141    }
142}