Skip to content

Commit 08e4646

Browse files
committed
update structs
1 parent c3918b5 commit 08e4646

File tree

4 files changed

+585
-7
lines changed

4 files changed

+585
-7
lines changed

crates/chia-protocol/src/fullblock.rs

Lines changed: 215 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,32 @@ use crate::Coin;
55
use crate::EndOfSubSlotBundle;
66
use crate::Program;
77
use crate::RewardChainBlock;
8+
use crate::RewardChainBlockOld;
89
use crate::VDFProof;
910
use crate::{Foliage, FoliageTransactionBlock, TransactionsInfo};
1011
use chia_traits::Streamable;
1112

13+
#[cfg(feature = "py-bindings")]
14+
use pyo3::prelude::*;
15+
16+
// Pre-fork structure (before HARD_FORK2_HEIGHT)
17+
#[streamable]
18+
pub struct FullBlockOld {
19+
finished_sub_slots: Vec<EndOfSubSlotBundle>,
20+
reward_chain_block: RewardChainBlockOld,
21+
challenge_chain_sp_proof: Option<VDFProof>, // # If not first sp in sub-slot
22+
challenge_chain_ip_proof: VDFProof,
23+
reward_chain_sp_proof: Option<VDFProof>, // # If not first sp in sub-slot
24+
reward_chain_ip_proof: VDFProof,
25+
infused_challenge_chain_ip_proof: Option<VDFProof>, // # Iff deficit < 4
26+
foliage: Foliage, // # Reward chain foliage data
27+
foliage_transaction_block: Option<FoliageTransactionBlock>, // # Reward chain foliage data (tx block)
28+
transactions_info: Option<TransactionsInfo>, // Reward chain foliage data (tx block additional)
29+
transactions_generator: Option<Program>, // Program that generates transactions
30+
transactions_generator_ref_list: Vec<u32>, // List of block heights of previous generators referenced in this block
31+
}
32+
33+
// Post-fork structure (at or after HARD_FORK2_HEIGHT) - this is the default
1234
#[streamable]
1335
pub struct FullBlock {
1436
finished_sub_slots: Vec<EndOfSubSlotBundle>,
@@ -25,6 +47,84 @@ pub struct FullBlock {
2547
transactions_generator_ref_list: Vec<u32>, // List of block heights of previous generators referenced in this block
2648
}
2749

50+
impl FullBlockOld {
51+
pub fn prev_header_hash(&self) -> Bytes32 {
52+
self.foliage.prev_block_hash
53+
}
54+
55+
pub fn header_hash(&self) -> Bytes32 {
56+
self.foliage.hash().into()
57+
}
58+
59+
pub fn is_transaction_block(&self) -> bool {
60+
self.foliage.foliage_transaction_block_hash.is_some()
61+
}
62+
63+
pub fn total_iters(&self) -> u128 {
64+
self.reward_chain_block.total_iters
65+
}
66+
67+
pub fn height(&self) -> u32 {
68+
self.reward_chain_block.height
69+
}
70+
71+
pub fn weight(&self) -> u128 {
72+
self.reward_chain_block.weight
73+
}
74+
75+
pub fn get_included_reward_coins(&self) -> Vec<Coin> {
76+
if let Some(ti) = &self.transactions_info {
77+
ti.reward_claims_incorporated.clone()
78+
} else {
79+
vec![]
80+
}
81+
}
82+
83+
pub fn is_fully_compactified(&self) -> bool {
84+
for sub_slot in &self.finished_sub_slots {
85+
if sub_slot.proofs.challenge_chain_slot_proof.witness_type != 0
86+
|| !sub_slot
87+
.proofs
88+
.challenge_chain_slot_proof
89+
.normalized_to_identity
90+
{
91+
return false;
92+
}
93+
if let Some(proof) = &sub_slot.proofs.infused_challenge_chain_slot_proof {
94+
if proof.witness_type != 0 || !proof.normalized_to_identity {
95+
return false;
96+
}
97+
}
98+
}
99+
100+
if let Some(proof) = &self.challenge_chain_sp_proof {
101+
if proof.witness_type != 0 || !proof.normalized_to_identity {
102+
return false;
103+
}
104+
}
105+
self.challenge_chain_ip_proof.witness_type == 0
106+
&& self.challenge_chain_ip_proof.normalized_to_identity
107+
}
108+
109+
// Always safe: upgrade reward_chain_block to new version
110+
pub fn to_new(&self) -> FullBlock {
111+
FullBlock {
112+
finished_sub_slots: self.finished_sub_slots.clone(),
113+
reward_chain_block: self.reward_chain_block.to_new(),
114+
challenge_chain_sp_proof: self.challenge_chain_sp_proof.clone(),
115+
challenge_chain_ip_proof: self.challenge_chain_ip_proof.clone(),
116+
reward_chain_sp_proof: self.reward_chain_sp_proof.clone(),
117+
reward_chain_ip_proof: self.reward_chain_ip_proof.clone(),
118+
infused_challenge_chain_ip_proof: self.infused_challenge_chain_ip_proof.clone(),
119+
foliage: self.foliage.clone(),
120+
foliage_transaction_block: self.foliage_transaction_block.clone(),
121+
transactions_info: self.transactions_info.clone(),
122+
transactions_generator: self.transactions_generator.clone(),
123+
transactions_generator_ref_list: self.transactions_generator_ref_list.clone(),
124+
}
125+
}
126+
}
127+
28128
impl FullBlock {
29129
pub fn prev_header_hash(&self) -> Bytes32 {
30130
self.foliage.prev_block_hash
@@ -83,12 +183,121 @@ impl FullBlock {
83183
self.challenge_chain_ip_proof.witness_type == 0
84184
&& self.challenge_chain_ip_proof.normalized_to_identity
85185
}
186+
187+
// Validated downgrade: only safe if reward_chain_block can downgrade
188+
#[cfg(feature = "py-bindings")]
189+
pub fn to_old(&self) -> PyResult<FullBlockOld> {
190+
let reward_chain_block_old = self.reward_chain_block.to_old()?;
191+
Ok(FullBlockOld {
192+
finished_sub_slots: self.finished_sub_slots.clone(),
193+
reward_chain_block: reward_chain_block_old,
194+
challenge_chain_sp_proof: self.challenge_chain_sp_proof.clone(),
195+
challenge_chain_ip_proof: self.challenge_chain_ip_proof.clone(),
196+
reward_chain_sp_proof: self.reward_chain_sp_proof.clone(),
197+
reward_chain_ip_proof: self.reward_chain_ip_proof.clone(),
198+
infused_challenge_chain_ip_proof: self.infused_challenge_chain_ip_proof.clone(),
199+
foliage: self.foliage.clone(),
200+
foliage_transaction_block: self.foliage_transaction_block.clone(),
201+
transactions_info: self.transactions_info.clone(),
202+
transactions_generator: self.transactions_generator.clone(),
203+
transactions_generator_ref_list: self.transactions_generator_ref_list.clone(),
204+
})
205+
}
206+
207+
#[cfg(not(feature = "py-bindings"))]
208+
pub fn to_old(&self) -> Result<FullBlockOld, String> {
209+
let reward_chain_block_old = self.reward_chain_block.to_old()?;
210+
Ok(FullBlockOld {
211+
finished_sub_slots: self.finished_sub_slots.clone(),
212+
reward_chain_block: reward_chain_block_old,
213+
challenge_chain_sp_proof: self.challenge_chain_sp_proof.clone(),
214+
challenge_chain_ip_proof: self.challenge_chain_ip_proof.clone(),
215+
reward_chain_sp_proof: self.reward_chain_sp_proof.clone(),
216+
reward_chain_ip_proof: self.reward_chain_ip_proof.clone(),
217+
infused_challenge_chain_ip_proof: self.infused_challenge_chain_ip_proof.clone(),
218+
foliage: self.foliage.clone(),
219+
foliage_transaction_block: self.foliage_transaction_block.clone(),
220+
transactions_info: self.transactions_info.clone(),
221+
transactions_generator: self.transactions_generator.clone(),
222+
transactions_generator_ref_list: self.transactions_generator_ref_list.clone(),
223+
})
224+
}
225+
226+
// Unchecked downgrade: caller guarantees reward_chain_block can downgrade
227+
pub fn to_old_unchecked(&self) -> FullBlockOld {
228+
FullBlockOld {
229+
finished_sub_slots: self.finished_sub_slots.clone(),
230+
reward_chain_block: self.reward_chain_block.to_old_unchecked(),
231+
challenge_chain_sp_proof: self.challenge_chain_sp_proof.clone(),
232+
challenge_chain_ip_proof: self.challenge_chain_ip_proof.clone(),
233+
reward_chain_sp_proof: self.reward_chain_sp_proof.clone(),
234+
reward_chain_ip_proof: self.reward_chain_ip_proof.clone(),
235+
infused_challenge_chain_ip_proof: self.infused_challenge_chain_ip_proof.clone(),
236+
foliage: self.foliage.clone(),
237+
foliage_transaction_block: self.foliage_transaction_block.clone(),
238+
transactions_info: self.transactions_info.clone(),
239+
transactions_generator: self.transactions_generator.clone(),
240+
transactions_generator_ref_list: self.transactions_generator_ref_list.clone(),
241+
}
242+
}
86243
}
87244

88245
#[cfg(feature = "py-bindings")]
89246
use chia_traits::ChiaToPython;
247+
90248
#[cfg(feature = "py-bindings")]
91-
use pyo3::prelude::*;
249+
#[pymethods]
250+
impl FullBlockOld {
251+
#[getter]
252+
#[pyo3(name = "prev_header_hash")]
253+
fn py_prev_header_hash(&self) -> Bytes32 {
254+
self.prev_header_hash()
255+
}
256+
257+
#[getter]
258+
#[pyo3(name = "header_hash")]
259+
fn py_header_hash(&self) -> Bytes32 {
260+
self.header_hash()
261+
}
262+
263+
#[pyo3(name = "is_transaction_block")]
264+
fn py_is_transaction_block(&self) -> bool {
265+
self.is_transaction_block()
266+
}
267+
268+
#[getter]
269+
#[pyo3(name = "total_iters")]
270+
fn py_total_iters<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyAny>> {
271+
ChiaToPython::to_python(&self.total_iters(), py)
272+
}
273+
274+
#[getter]
275+
#[pyo3(name = "height")]
276+
fn py_height<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyAny>> {
277+
ChiaToPython::to_python(&self.height(), py)
278+
}
279+
280+
#[getter]
281+
#[pyo3(name = "weight")]
282+
fn py_weight<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyAny>> {
283+
ChiaToPython::to_python(&self.weight(), py)
284+
}
285+
286+
#[pyo3(name = "get_included_reward_coins")]
287+
fn py_get_included_reward_coins(&self) -> Vec<Coin> {
288+
self.get_included_reward_coins()
289+
}
290+
291+
#[pyo3(name = "is_fully_compactified")]
292+
fn py_is_fully_compactified(&self) -> bool {
293+
self.is_fully_compactified()
294+
}
295+
296+
#[pyo3(name = "to_new")]
297+
fn py_to_new(&self) -> FullBlock {
298+
self.to_new()
299+
}
300+
}
92301

93302
#[cfg(feature = "py-bindings")]
94303
#[pymethods]
@@ -137,4 +346,9 @@ impl FullBlock {
137346
fn py_is_fully_compactified(&self) -> bool {
138347
self.is_fully_compactified()
139348
}
349+
350+
#[pyo3(name = "to_old")]
351+
fn py_to_old(&self) -> PyResult<FullBlockOld> {
352+
self.to_old()
353+
}
140354
}

0 commit comments

Comments
 (0)