diff --git a/src/models/block/mod.rs b/src/models/block/mod.rs index 594f693b..fcd7305c 100755 --- a/src/models/block/mod.rs +++ b/src/models/block/mod.rs @@ -40,12 +40,17 @@ pub struct Block { /// Merkle update for the shard state. pub state_update: Lazy, /// Merkle updates for the outgoing messages queue. + #[cfg(not(feature = "tycho"))] pub out_msg_queue_updates: Option>>, + /// Processed upto and diff hash queue msg update + #[cfg(feature = "tycho")] + pub out_msg_queue_updates: MsgQueueUpdates, /// Block content. pub extra: Lazy, } impl Block { + #[cfg(not(feature = "tycho"))] const TAG_V1: u32 = 0x11ef55aa; const TAG_V2: u32 = 0x11ef55bb; @@ -88,17 +93,21 @@ impl Store for Block { builder: &mut CellBuilder, context: &mut dyn CellContext, ) -> Result<(), Error> { + #[cfg(not(feature = "tycho"))] let tag = if self.out_msg_queue_updates.is_none() { Self::TAG_V1 } else { Self::TAG_V2 }; + #[cfg(feature = "tycho")] + let tag = Self::TAG_V2; ok!(builder.store_u32(tag)); ok!(builder.store_u32(self.global_id as u32)); ok!(builder.store_reference(self.info.cell.clone())); ok!(builder.store_reference(self.value_flow.cell.clone())); + #[cfg(not(feature = "tycho"))] ok!( if let Some(out_msg_queue_updates) = &self.out_msg_queue_updates { let cell = { @@ -112,6 +121,16 @@ impl Store for Block { self.state_update.store_into(builder, context) } ); + #[cfg(feature = "tycho")] + ok!({ + let cell = { + let mut builder = CellBuilder::new(); + ok!(self.state_update.store_into(&mut builder, context)); + ok!(self.out_msg_queue_updates.store_into(&mut builder, context)); + ok!(builder.build_ext(context)) + }; + builder.store_reference(cell) + }); self.extra.store_into(builder, context) } @@ -119,15 +138,23 @@ impl Store for Block { impl<'a> Load<'a> for Block { fn load_from(slice: &mut CellSlice<'a>) -> Result { + #[cfg(not(feature = "tycho"))] let with_out_msg_queue_updates = match ok!(slice.load_u32()) { Self::TAG_V1 => false, Self::TAG_V2 => true, _ => return Err(Error::InvalidTag), }; + #[cfg(feature = "tycho")] + match ok!(slice.load_u32()) { + Self::TAG_V2 => true, + _ => return Err(Error::InvalidTag), + }; let global_id = ok!(slice.load_u32()) as i32; let info = ok!(Lazy::load_from(slice)); let value_flow = ok!(Lazy::load_from(slice)); + + #[cfg(not(feature = "tycho"))] let (state_update, out_msg_queue_updates) = if with_out_msg_queue_updates { let slice = &mut ok!(slice.load_reference_as_slice()); ( @@ -137,6 +164,14 @@ impl<'a> Load<'a> for Block { } else { (ok!(Lazy::load_from(slice)), None) }; + #[cfg(feature = "tycho")] + let (state_update, out_msg_queue_updates) = { + let slice = &mut ok!(slice.load_reference_as_slice()); + ( + ok!(Lazy::load_from(slice)), + ok!(MsgQueueUpdates::load_from(slice)), + ) + }; Ok(Self { global_id, @@ -669,3 +704,12 @@ impl<'a> Load<'a> for ValueFlow { }) } } + +#[cfg(feature = "tycho")] +/// Message queue updates +#[derive(Debug, Clone, Eq, PartialEq, Store, Load)] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +pub struct MsgQueueUpdates { + /// Diff hash + pub diff_hash: HashBytes, +} diff --git a/src/models/block/tests/mc_block_with_tycho_out_msg.boc b/src/models/block/tests/mc_block_with_tycho_out_msg.boc new file mode 100644 index 00000000..1d353b07 Binary files /dev/null and b/src/models/block/tests/mc_block_with_tycho_out_msg.boc differ diff --git a/src/models/block/tests/mod.rs b/src/models/block/tests/mod.rs index cb652af8..9ce3c369 100644 --- a/src/models/block/tests/mod.rs +++ b/src/models/block/tests/mod.rs @@ -1,7 +1,14 @@ use std::collections::HashMap; use super::*; + +#[cfg(not(feature = "tycho"))] use crate::prelude::*; +#[cfg(feature = "tycho")] +use crate::{ + models::{ExtraCurrencyCollection, GlobalCapabilities}, + prelude::*, +}; fn serialize_any(data: T) -> Cell { CellBuilder::build_from(data).unwrap() @@ -351,3 +358,112 @@ fn proof_for_shardchain_block() { assert_eq!(serialize_any(proof).as_ref(), boc.as_ref()); } + +#[test] +#[cfg(feature = "tycho")] +fn block_with_tycho_updates_store_load() { + let block = Block { + global_id: 42, + info: Lazy::new(&BlockInfo { + version: 0, + gen_utime_ms: 123, + after_merge: false, + before_split: false, + after_split: false, + want_split: false, + want_merge: true, + key_block: false, + flags: 1, + seqno: 24721433, + vert_seqno: 0, + shard: ShardIdent::new(-1, 0x8000000000000000).unwrap(), + gen_utime: 1674507085, + start_lt: 34671157000000, + end_lt: 34671157000005, + gen_validator_list_hash_short: 3236125243, + gen_catchain_seqno: 343054, + min_ref_mc_seqno: 24721430, + prev_key_block_seqno: 24715347, + gen_software: GlobalVersion { + version: 34, + capabilities: GlobalCapabilities::new(464814), + }, + master_ref: None, + prev_ref: Cell::empty_cell(), + prev_vert_ref: None, + }) + .unwrap(), + value_flow: Lazy::new(&ValueFlow { + from_prev_block: CurrencyCollection { + tokens: Tokens::new(3610625966274374005), + other: ExtraCurrencyCollection::new(), + }, + to_next_block: CurrencyCollection { + tokens: Tokens::new(3610625969470214036), + other: ExtraCurrencyCollection::new(), + }, + imported: CurrencyCollection { + tokens: Tokens::new(0), + other: ExtraCurrencyCollection::new(), + }, + exported: CurrencyCollection { + tokens: Tokens::new(0), + other: ExtraCurrencyCollection::new(), + }, + fees_collected: CurrencyCollection { + tokens: Tokens::new(3195840031), + other: ExtraCurrencyCollection::new(), + }, + fees_imported: CurrencyCollection { + tokens: Tokens::new(1495840031), + other: ExtraCurrencyCollection::new(), + }, + recovered: CurrencyCollection { + tokens: Tokens::new(3195840031), + other: ExtraCurrencyCollection::new(), + }, + created: CurrencyCollection { + tokens: Tokens::new(1700000000), + other: ExtraCurrencyCollection::new(), + }, + minted: CurrencyCollection { + tokens: Tokens::new(0), + other: ExtraCurrencyCollection::new(), + }, + copyleft_rewards: Dict::new(), + }) + .unwrap(), + state_update: Lazy::new(&MerkleUpdate { + old_hash: HashBytes::ZERO, + new_hash: HashBytes::ZERO, + old_depth: 182, + new_depth: 182, + old: Cell::empty_cell(), + new: Cell::empty_cell(), + }) + .unwrap(), + extra: Lazy::new(&BlockExtra { + in_msg_description: Lazy::new(&AugDict::new()).unwrap(), + out_msg_description: Lazy::new(&AugDict::new()).unwrap(), + account_blocks: Lazy::new(&AugDict::new()).unwrap(), + rand_seed: HashBytes::ZERO, + created_by: HashBytes::ZERO, + custom: None, + }) + .unwrap(), + out_msg_queue_updates: MsgQueueUpdates { + diff_hash: HashBytes::ZERO, + }, + }; + let encoded = BocRepr::encode(&block).unwrap(); + + let cell: Cell = Boc::decode(&*encoded).unwrap(); + assert_eq!( + Block::load_from(&mut cell.as_slice().unwrap()) + .unwrap() + .out_msg_queue_updates, + MsgQueueUpdates { + diff_hash: HashBytes::ZERO, + } + ); +}