From 77bca1d0c938f711d1c6783cb3933ce5d72be474 Mon Sep 17 00:00:00 2001 From: Vladimir Lebedev Date: Thu, 26 Sep 2024 17:28:34 +0700 Subject: [PATCH 1/6] Add msg_envelope_v2 --- src/envelope_message.rs | 70 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/src/envelope_message.rs b/src/envelope_message.rs index 7168ebd..233d835 100644 --- a/src/envelope_message.rs +++ b/src/envelope_message.rs @@ -358,18 +358,57 @@ impl Deserializable for IntermediateAddressExt { } } +// msg_metadata#0 depth:uint32 initiator_addr:MsgAddressInt initiator_lt:uint64 = MsgMetadata; +#[cfg(feature = "ton")] +#[derive(Clone, Default, Debug, Eq, PartialEq)] +pub struct MsgMetadata { + pub depth: u32, + pub initiator_addr: crate::MsgAddressInt, + pub initiator_lt: u64, +} + +#[cfg(feature = "ton")] +impl Serializable for MsgMetadata { + fn write_to(&self, cell: &mut BuilderData) -> Result<()> { + self.depth.write_to(cell)?; + self.initiator_addr.write_to(cell)?; + self.initiator_lt.write_to(cell)?; + Ok(()) + } +} + +#[cfg(feature = "ton")] +impl Deserializable for MsgMetadata { + fn read_from(&mut self, cell: &mut SliceData) -> Result<()> { + self.depth.read_from(cell)?; + self.initiator_addr.read_from(cell)?; + self.initiator_lt.read_from(cell)?; + Ok(()) + } +} + // msg_envelope#4 // cur_addr:IntermediateAddress // next_addr:IntermediateAddress // fwd_fee_remaining:Grams // msg:^(Message Any) // = MsgEnvelope; +// +// msg_envelope_v2#5 cur_addr:IntermediateAddress +// next_addr:IntermediateAddress fwd_fee_remaining:Grams +// msg:^(Message Any) +// emitted_lt:(Maybe uint64) +// metadata:(Maybe MsgMetadata) = MsgEnvelope; #[derive(Clone, Default, Debug, Eq, PartialEq)] pub struct MsgEnvelope { cur_addr: IntermediateAddress, next_addr: IntermediateAddress, fwd_fee_remaining: Grams, msg: ChildCell, + #[cfg(feature = "ton")] + emitted_lt: Option, + #[cfg(feature = "ton")] + metadata: Option, } impl MsgEnvelope { @@ -414,6 +453,10 @@ impl MsgEnvelope { next_addr, fwd_fee_remaining, msg: ChildCell::with_cell(msg_cell), + #[cfg(feature = "ton")] + emitted_lt: None, + #[cfg(feature = "ton")] + metadata: None, } } @@ -435,6 +478,10 @@ impl MsgEnvelope { next_addr: route_info.1, fwd_fee_remaining, msg: ChildCell::with_cell(msg_cell), + #[cfg(feature = "ton")] + emitted_lt: None, + #[cfg(feature = "ton")] + metadata: None, }) } @@ -537,14 +584,25 @@ impl MsgEnvelope { } const MSG_ENVELOPE_TAG : usize = 0x4; +#[cfg(feature = "ton")] +const MSG_ENVELOPE_TAG_TON : usize = 0x5; impl Serializable for MsgEnvelope { fn write_to(&self, cell: &mut BuilderData) -> Result<()> { + #[cfg(not(feature = "ton"))] cell.append_bits(MSG_ENVELOPE_TAG, 4)?; + #[cfg(feature = "ton")] + cell.append_bits(MSG_ENVELOPE_TAG_TON, 4)?; self.cur_addr.write_to(cell)?; self.next_addr.write_to(cell)?; self.fwd_fee_remaining.write_to(cell)?; cell.checked_append_reference(self.msg.cell())?; + #[cfg(feature = "ton")] + { + use crate::MaybeSerialize; + self.emitted_lt.write_maybe_to(cell)?; + self.metadata.write_maybe_to(cell)?; + } Ok(()) } } @@ -552,7 +610,11 @@ impl Serializable for MsgEnvelope { impl Deserializable for MsgEnvelope { fn read_from(&mut self, cell: &mut SliceData) -> Result<()>{ let tag = cell.get_next_int(4)? as usize; - if tag != MSG_ENVELOPE_TAG { + #[cfg(not(feature = "ton"))] + let is_tag_valid = tag == MSG_ENVELOPE_TAG; + #[cfg(feature = "ton")] + let is_tag_valid = tag == MSG_ENVELOPE_TAG || tag == MSG_ENVELOPE_TAG_TON; + if !is_tag_valid { fail!( BlockError::InvalidConstructorTag { t: tag as u32, @@ -564,6 +626,12 @@ impl Deserializable for MsgEnvelope { self.next_addr.read_from(cell)?; self.fwd_fee_remaining.read_from(cell)?; self.msg.read_from_reference(cell)?; + #[cfg(feature = "ton")] + { + use crate::MaybeDeserialize; + self.emitted_lt = u64::read_maybe_from(cell)?; + self.metadata = MsgMetadata::read_maybe_from(cell)?; + } Ok(()) } } From c575564453cddec91d8a714c55706d5a017c3a0a Mon Sep 17 00:00:00 2001 From: Vladimir Lebedev Date: Thu, 26 Sep 2024 18:00:42 +0700 Subject: [PATCH 2/6] Add new ton variants for InMsg --- src/inbound_messages.rs | 188 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) diff --git a/src/inbound_messages.rs b/src/inbound_messages.rs index 496c50e..b4eb9dc 100644 --- a/src/inbound_messages.rs +++ b/src/inbound_messages.rs @@ -50,6 +50,14 @@ macro_rules! write_ctor_tag { }} } +#[cfg(feature = "ton")] +macro_rules! write_ctor_extended_tag { + ($builder:expr, $tag:ident) => {{ + $builder.append_bits($tag as usize, 5).unwrap(); + $builder + }} +} + //3.2.7. Augmentation of InMsgDescr #[derive(Default, PartialEq, Eq, Clone, Debug)] pub struct ImportFees { @@ -104,6 +112,10 @@ const MSG_IMPORT_FIN: u8 = 0b00000100; const MSG_IMPORT_TR: u8 = 0b00000101; const MSG_DISCARD_FIN: u8 = 0b00000110; const MSG_DISCARD_TR: u8 = 0b00000111; +#[cfg(feature = "ton")] +const MSG_IMPORT_DEFERRED_FIN: u8 = 0b00100; +#[cfg(feature = "ton")] +const MSG_IMPORT_DEFERRED_TR: u8 = 0b00101; /// /// Inbound message @@ -134,6 +146,12 @@ pub enum InMsg { /// Discarded transit internal messages /// msg_discard_tr$111 in_msg:^MsgEnvelope transaction_id:uint64 fwd_fee:Grams proof_delivered:^Cell = InMsg; DiscardedTransit(InMsgDiscardedTransit), + #[cfg(feature = "ton")] + /// msg_import_deferred_fin$00100 in_msg:^MsgEnvelope transaction:^Transaction fwd_fee:Grams = InMsg; + DeferredFinal(InMsgDeferredFinal), + #[cfg(feature = "ton")] + /// msg_import_deferred_tr$00101 in_msg:^MsgEnvelope out_msg:^MsgEnvelope = InMsg; + DeferredTransit(InMsgDeferredTransit), } impl fmt::Display for InMsg { @@ -155,6 +173,12 @@ impl fmt::Display for InMsg { msg_hash, x.transaction_id, x.fwd_fee), InMsg::DiscardedTransit(x) => write!(f, "InMsg msg_discard_tr$111 msg: {:x} tr: {:x} fee: {} proof: {:x}", msg_hash, x.transaction_id, x.fwd_fee, x.proof_delivered.repr_hash()), + #[cfg(feature = "ton")] + InMsg::DeferredFinal(_x) => write!(f, "InMsg msg_import_deferred_fin$00100 msg: {:x} tr: {:x}", + msg_hash, tr_hash), + #[cfg(feature = "ton")] + InMsg::DeferredTransit(x) => write!(f, "InMsg msg_import_deferred_tr$00101 in_msg: {:x} out_msg: {:x}", + msg_hash, x.out_msg.read_struct().unwrap_or_default().message_hash()), InMsg::None => write!(f, "InMsg msg_unknown") } } @@ -205,6 +229,10 @@ impl InMsg { InMsg::Transit(_) => MSG_IMPORT_TR, InMsg::DiscardedFinal(_) => MSG_DISCARD_FIN, InMsg::DiscardedTransit(_) => MSG_DISCARD_TR, + #[cfg(feature = "ton")] + InMsg::DeferredFinal(_) => MSG_IMPORT_DEFERRED_FIN, + #[cfg(feature = "ton")] + InMsg::DeferredTransit(_) => MSG_IMPORT_DEFERRED_TR, InMsg::None => 8 } } @@ -224,6 +252,10 @@ impl InMsg { InMsg::Transit(ref _x) => None, InMsg::DiscardedFinal(ref _x) => None, InMsg::DiscardedTransit(ref _x) => None, + #[cfg(feature = "ton")] + InMsg::DeferredFinal(ref x) => Some(x.read_transaction()?), + #[cfg(feature = "ton")] + InMsg::DeferredTransit(ref _x) => None, InMsg::None => fail!("wrong message type") } ) @@ -243,6 +275,10 @@ impl InMsg { InMsg::Transit(ref _x) => None, InMsg::DiscardedFinal(ref _x) => None, InMsg::DiscardedTransit(ref _x) => None, + #[cfg(feature = "ton")] + InMsg::DeferredFinal(ref x) => Some(x.transaction_cell()), + #[cfg(feature = "ton")] + InMsg::DeferredTransit(ref _x) => None, InMsg::None => None, } } @@ -259,6 +295,10 @@ impl InMsg { InMsg::Transit(ref x) => x.read_in_message()?.read_message(), InMsg::DiscardedFinal(ref x) => x.read_envelope_message()?.read_message(), InMsg::DiscardedTransit(ref x) => x.read_envelope_message()?.read_message(), + #[cfg(feature = "ton")] + InMsg::DeferredFinal(ref x) => x.read_envelope_message()?.read_message(), + #[cfg(feature = "ton")] + InMsg::DeferredTransit(ref x) => x.read_in_message()?.read_message(), InMsg::None => fail!("wrong msg type") } } @@ -276,6 +316,10 @@ impl InMsg { InMsg::Transit(ref x) => x.read_in_message()?.message_cell(), InMsg::DiscardedFinal(ref x) => x.read_envelope_message()?.message_cell(), InMsg::DiscardedTransit(ref x) => x.read_envelope_message()?.message_cell(), + #[cfg(feature = "ton")] + InMsg::DeferredFinal(ref x) => x.read_envelope_message()?.message_cell(), + #[cfg(feature = "ton")] + InMsg::DeferredTransit(ref x) => x.read_in_message()?.message_cell(), InMsg::None => fail!("wrong message type") } ) @@ -293,6 +337,10 @@ impl InMsg { InMsg::Transit(ref x) => Some(x.in_msg.cell()), InMsg::DiscardedFinal(ref x) => Some(x.envelope_message_cell()), InMsg::DiscardedTransit(ref x) => Some(x.in_msg.cell()), + #[cfg(feature = "ton")] + InMsg::DeferredFinal(ref x) => Some(x.envelope_message_cell()), + #[cfg(feature = "ton")] + InMsg::DeferredTransit(ref x) => Some(x.in_msg.cell()), InMsg::None => None, } } @@ -310,6 +358,10 @@ impl InMsg { InMsg::Transit(ref x) => Some(x.read_in_message()?), InMsg::DiscardedFinal(ref x) => Some(x.read_envelope_message()?), InMsg::DiscardedTransit(ref x) => Some(x.read_envelope_message()?), + #[cfg(feature = "ton")] + InMsg::DeferredFinal(ref x) => Some(x.read_envelope_message()?), + #[cfg(feature = "ton")] + InMsg::DeferredTransit(ref x) => Some(x.read_in_message()?), InMsg::None => fail!("wrong message type"), } ) @@ -327,6 +379,10 @@ impl InMsg { InMsg::Transit(ref x) => Some(x.out_msg.cell()), InMsg::DiscardedFinal(_) => None, InMsg::DiscardedTransit(_) => None, + #[cfg(feature = "ton")] + InMsg::DeferredFinal(_) => None, + #[cfg(feature = "ton")] + InMsg::DeferredTransit(ref x) => Some(x.out_msg.cell()), InMsg::None => None, } } @@ -343,6 +399,10 @@ impl InMsg { InMsg::Transit(ref x) => Some(x.read_out_message()).transpose(), InMsg::DiscardedFinal(_) => Ok(None), InMsg::DiscardedTransit(_) => Ok(None), + #[cfg(feature = "ton")] + InMsg::DeferredFinal(_) => Ok(None), + #[cfg(feature = "ton")] + InMsg::DeferredTransit(ref x) => Some(x.read_out_message()).transpose(), InMsg::None => fail!("wrong message type") } } @@ -410,6 +470,18 @@ impl Augmentation for InMsg { fees.value_imported.grams = header.fwd_fee; } + #[cfg(feature = "ton")] + InMsg::DeferredFinal(_) => { + fees.fees_collected = header.fwd_fee; + + fees.value_imported.grams = header.fwd_fee; + } + #[cfg(feature = "ton")] + InMsg::DeferredTransit(_) => { + fees.fees_collected = header.fwd_fee; + + fees.value_imported.grams = header.fwd_fee; + } InMsg::None => fail!("wrong InMsg type") } Ok(fees) @@ -426,6 +498,10 @@ impl Serializable for InMsg { InMsg::Transit(ref x) => x.write_to(write_ctor_tag!(cell, MSG_IMPORT_TR)), InMsg::DiscardedFinal(ref x) => x.write_to(write_ctor_tag!(cell, MSG_DISCARD_FIN)), InMsg::DiscardedTransit(ref x) => x.write_to(write_ctor_tag!(cell, MSG_DISCARD_TR)), + #[cfg(feature = "ton")] + InMsg::DeferredFinal(ref x) => x.write_to(write_ctor_extended_tag!(cell, MSG_IMPORT_DEFERRED_FIN)), + #[cfg(feature = "ton")] + InMsg::DeferredTransit(ref x) => x.write_to(write_ctor_extended_tag!(cell, MSG_IMPORT_DEFERRED_TR)), InMsg::None => Ok(()), // Due to ChildCell it is need sometimes to serialize default InMsg } } @@ -442,6 +518,15 @@ impl Deserializable for InMsg { MSG_IMPORT_TR => read_msg_descr!(cell, InMsgTransit, Transit), MSG_DISCARD_FIN => read_msg_descr!(cell, InMsgDiscardedFinal, DiscardedFinal), MSG_DISCARD_TR => read_msg_descr!(cell, InMsgDiscardedTransit, DiscardedTransit), + #[cfg(feature = "ton")] + 0b00100000 => { + let subtag = cell.get_next_bit()?; + if subtag { + read_msg_descr!(cell, InMsgDeferredTransit, DeferredTransit) + } else { + read_msg_descr!(cell, InMsgDeferredFinal, DeferredFinal) + } + } tag => fail!( BlockError::InvalidConstructorTag { t: tag as u32, @@ -809,6 +894,109 @@ impl Deserializable for InMsgDiscardedTransit { } } +#[cfg(feature = "ton")] +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct InMsgDeferredFinal { + in_msg: ChildCell, + transaction: ChildCell, + pub fwd_fee: Grams, +} + +#[cfg(feature = "ton")] +impl InMsgDeferredFinal { + pub fn read_envelope_message(&self) -> Result { + self.in_msg.read_struct() + } + + pub fn envelope_message_cell(&self) -> Cell { + self.in_msg.cell() + } + + pub fn envelope_message_hash(&self) -> UInt256 { + self.in_msg.hash() + } + + pub fn message_cell(&self)-> Result { + Ok(self.in_msg.read_struct()?.message_cell()) + } + + pub fn read_transaction(&self) -> Result { + self.transaction.read_struct() + } + + pub fn transaction_cell(&self)-> Cell { + self.transaction.cell() + } +} + +#[cfg(feature = "ton")] +impl Serializable for InMsgDeferredFinal { + fn write_to(&self, cell: &mut BuilderData) -> Result<()> { + cell.checked_append_reference(self.in_msg.cell())?; + cell.checked_append_reference(self.transaction.cell())?; + self.fwd_fee.write_to(cell)?; + Ok(()) + } +} + +#[cfg(feature = "ton")] +impl Deserializable for InMsgDeferredFinal { + fn read_from(&mut self, cell: &mut SliceData) -> Result<()> { + self.in_msg.read_from_reference(cell)?; + self.transaction.read_from_reference(cell)?; + self.fwd_fee.read_from(cell)?; + Ok(()) + } +} + +#[cfg(feature = "ton")] +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct InMsgDeferredTransit { + in_msg: ChildCell, + out_msg: ChildCell, +} + +#[cfg(feature = "ton")] +impl InMsgDeferredTransit { + pub fn read_in_message(&self) -> Result { + self.in_msg.read_struct() + } + + pub fn read_out_message(&self) -> Result { + self.out_msg.read_struct() + } + + pub fn in_envelope_message_cell(&self)-> Cell { + self.in_msg.cell() + } + + pub fn in_envelope_message_hash(&self)-> UInt256 { + self.in_msg.hash() + } + + pub fn out_envelope_message_cell(&self)-> Cell { + self.out_msg.cell() + } +} + +#[cfg(feature = "ton")] +impl Serializable for InMsgDeferredTransit { + fn write_to(&self, cell: &mut BuilderData) -> Result<()> { + cell.checked_append_reference(self.in_msg.cell())?; + cell.checked_append_reference(self.out_msg.cell())?; + Ok(()) + } +} + +#[cfg(feature = "ton")] +impl Deserializable for InMsgDeferredTransit { + fn read_from(&mut self, cell: &mut SliceData) -> Result<()> { + self.in_msg.read_from_reference(cell)?; + self.out_msg.read_from_reference(cell)?; + Ok(()) + } +} + //3.2.8. Structure of InMsgDescr //_ (HashmapAugE 256 InMsg ImportFees) = InMsgDescr define_HashmapAugE!(InMsgDescr, 256, UInt256, InMsg, ImportFees); From 11aea3beab52018c3882f21983a30512eba04e7f Mon Sep 17 00:00:00 2001 From: Vladimir Lebedev Date: Thu, 26 Sep 2024 18:45:09 +0700 Subject: [PATCH 3/6] Add new ton variants for OutMsg --- src/outbound_messages.rs | 159 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) diff --git a/src/outbound_messages.rs b/src/outbound_messages.rs index 4a0311f..e4aed12 100644 --- a/src/outbound_messages.rs +++ b/src/outbound_messages.rs @@ -50,6 +50,10 @@ const OUT_MSG_DEQ_IMM: u8 = 0b100; const OUT_MSG_DEQ: u8 = 0b1100; // is not used due CapShortDequeue const OUT_MSG_DEQ_SHORT: u8 = 0b1101; const OUT_MSG_TRDEQ: u8 = 0b111; // is not used due CapOffHypercube +#[cfg(feature = "ton")] +const OUT_MSG_NEW_DEFER: u8 = 0b10100; +#[cfg(feature = "ton")] +const OUT_MSG_DEFERRED_TR: u8 = 0b10101; /* _ enqueued_lt:uint64 out_msg:^MsgEnvelope = EnqueuedMsg; @@ -457,6 +461,12 @@ pub enum OutMsg { DequeueShort(OutMsgDequeueShort), /// msg_export_tr_req$111 out_msg:^MsgEnvelope imported:^InMsg = OutMsg; TransitRequeued(OutMsgTransitRequeued), + #[cfg(feature = "ton")] + /// msg_export_new_defer$10100 out_msg:^MsgEnvelope transaction:^Transaction = OutMsg; + NewDefer(OutMsgNewDefer), + #[cfg(feature = "ton")] + /// msg_export_deferred_tr$10101 out_msg:^MsgEnvelope imported:^InMsg = OutMsg; + DeferredTransit(OutMsgDeferredTransit), } impl OutMsg { @@ -514,6 +524,10 @@ impl OutMsg { OutMsg::DequeueShort(_) => OUT_MSG_DEQ_SHORT, // 4 bits OutMsg::DequeueImmediate(_) => OUT_MSG_DEQ_IMM, OutMsg::TransitRequeued(_) => OUT_MSG_TRDEQ, + #[cfg(feature = "ton")] + OutMsg::NewDefer(_) => OUT_MSG_NEW_DEFER, + #[cfg(feature = "ton")] + OutMsg::DeferredTransit(_) => OUT_MSG_DEFERRED_TR, OutMsg::None => 16 } } @@ -532,6 +546,10 @@ impl OutMsg { OutMsg::DequeueShort(_) => None, OutMsg::DequeueImmediate(ref x) => Some(x.read_out_message()?), OutMsg::TransitRequeued(ref x) => Some(x.read_out_message()?), + #[cfg(feature = "ton")] + OutMsg::NewDefer(ref x) => Some(x.read_out_message()?), + #[cfg(feature = "ton")] + OutMsg::DeferredTransit(ref x) => Some(x.read_out_message()?), OutMsg::None => fail!("wrong message type") } ) @@ -550,6 +568,10 @@ impl OutMsg { OutMsg::DequeueShort(_) => None, OutMsg::DequeueImmediate(ref x) => Some(x.out_message_cell()), OutMsg::TransitRequeued(ref x) => Some(x.out_message_cell()), + #[cfg(feature = "ton")] + OutMsg::NewDefer(ref x) => Some(x.out_message_cell()), + #[cfg(feature = "ton")] + OutMsg::DeferredTransit(ref x) => Some(x.out_message_cell()), OutMsg::None => None } } @@ -568,6 +590,10 @@ impl OutMsg { OutMsg::DequeueShort(_) => None, OutMsg::DequeueImmediate(ref x) => Some(x.read_out_message()?.read_message()?), OutMsg::TransitRequeued(ref x) => Some(x.read_out_message()?.read_message()?), + #[cfg(feature = "ton")] + OutMsg::NewDefer(ref x) => Some(x.read_out_message()?.read_message()?), + #[cfg(feature = "ton")] + OutMsg::DeferredTransit(ref x) => Some(x.read_out_message()?.read_message()?), OutMsg::None => fail!("wrong message type") } ) @@ -587,6 +613,10 @@ impl OutMsg { OutMsg::DequeueShort(_) => fail!("dequeue short out msg doesn't have message hash"), OutMsg::DequeueImmediate(ref x) => x.read_out_message()?.message_hash(), OutMsg::TransitRequeued(ref x) => x.read_out_message()?.message_hash(), + #[cfg(feature = "ton")] + OutMsg::NewDefer(ref x) => x.read_out_message()?.message_hash(), + #[cfg(feature = "ton")] + OutMsg::DeferredTransit(ref x) => x.read_out_message()?.message_hash(), OutMsg::None => fail!("wrong message type") } ) @@ -606,6 +636,10 @@ impl OutMsg { OutMsg::DequeueShort(_) => None, OutMsg::DequeueImmediate(ref x) => Some(x.read_out_message()?.message_cell()), OutMsg::TransitRequeued(ref x) => Some(x.read_out_message()?.message_cell()), + #[cfg(feature = "ton")] + OutMsg::NewDefer(ref x) => Some(x.read_out_message()?.message_cell()), + #[cfg(feature = "ton")] + OutMsg::DeferredTransit(ref x) => Some(x.read_out_message()?.message_cell()), OutMsg::None => fail!("wrong message type") } ) @@ -624,6 +658,10 @@ impl OutMsg { OutMsg::DequeueShort(ref x) => Some(x.msg_env_hash), OutMsg::DequeueImmediate(ref x) => Some(x.out_message_cell().repr_hash()), OutMsg::TransitRequeued(ref x) => Some(x.out_message_cell().repr_hash()), + #[cfg(feature = "ton")] + OutMsg::NewDefer(ref x) => Some(x.out_message_cell().repr_hash()), + #[cfg(feature = "ton")] + OutMsg::DeferredTransit(ref x) => Some(x.out_message_cell().repr_hash()), OutMsg::None => None } } @@ -638,6 +676,10 @@ impl OutMsg { OutMsg::DequeueShort(ref _x) => None, OutMsg::DequeueImmediate(ref _x) => None, OutMsg::TransitRequeued(ref _x) => None, + #[cfg(feature = "ton")] + OutMsg::NewDefer(ref x) => Some(x.transaction_cell()), + #[cfg(feature = "ton")] + OutMsg::DeferredTransit(ref _x) => None, OutMsg::None => None, } } @@ -655,6 +697,7 @@ impl OutMsg { OutMsg::Transit(ref x) => Some(x.read_imported()).transpose(), OutMsg::DequeueImmediate(ref x) => Some(x.read_reimport_message()).transpose(), OutMsg::TransitRequeued(ref x) => Some(x.read_imported()).transpose(), + OutMsg::DeferredTransit(ref x) => Some(x.read_imported()).transpose(), _ => Ok(None), } } @@ -665,6 +708,7 @@ impl OutMsg { OutMsg::Transit(ref x) => Some(x.imported_cell()), OutMsg::DequeueImmediate(ref x) => Some(x.reimport_message_cell()), OutMsg::TransitRequeued(ref x) => Some(x.imported_cell()), + OutMsg::DeferredTransit(ref x) => Some(x.imported_cell()), _ => None } } @@ -751,6 +795,10 @@ impl Serializable for OutMsg { OutMsg::DequeueShort(ref x) => x.write_to(write_out_ctor_tag!(cell, OUT_MSG_DEQ_SHORT, 4)), OutMsg::DequeueImmediate(ref x) => x.write_to(write_out_ctor_tag!(cell, OUT_MSG_DEQ_IMM, 3)), OutMsg::TransitRequeued(ref x) => x.write_to(write_out_ctor_tag!(cell, OUT_MSG_TRDEQ, 3)), + #[cfg(feature = "ton")] + OutMsg::NewDefer(ref x) => x.write_to(write_out_ctor_tag!(cell, OUT_MSG_NEW_DEFER, 5)), + #[cfg(feature = "ton")] + OutMsg::DeferredTransit(ref x) => x.write_to(write_out_ctor_tag!(cell, OUT_MSG_DEFERRED_TR, 5)), OutMsg::None => fail!( BlockError::InvalidOperation("OutMsg::None can't be serialized".to_string()) ) @@ -775,6 +823,13 @@ impl Deserializable for OutMsg { _ => unreachable!() } }, + tag if cell.remaining_bits() >= 2 && (tag == OUT_MSG_NEW_DEFER >> 2 || tag == OUT_MSG_DEFERRED_TR >> 2) => { + match (tag << 2) | cell.get_next_int(2).unwrap() as u8 { + OUT_MSG_NEW_DEFER => read_out_msg_descr!(cell, OutMsgNewDefer, NewDefer), + OUT_MSG_DEFERRED_TR => read_out_msg_descr!(cell, OutMsgDeferredTransit, DeferredTransit), + _ => unreachable!() + } + }, tag => { fail!( BlockError::InvalidConstructorTag { @@ -1192,3 +1247,107 @@ impl Deserializable for OutMsgTransitRequeued { Ok(()) } } + +/// msg_export_new_defer$10100 out_msg:^MsgEnvelope transaction:^Transaction = OutMsg; +#[cfg(feature = "ton")] +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct OutMsgNewDefer { + out_msg: ChildCell, + transaction: ChildCell, +} + +#[cfg(feature = "ton")] +impl OutMsgNewDefer { + pub fn with_cells(env_cell: Cell, tr_cell: Cell) -> Self { + OutMsgNewDefer { + out_msg: ChildCell::with_cell(env_cell), + transaction: ChildCell::with_cell(tr_cell), + } + } + + pub fn read_out_message(&self) -> Result { + self.out_msg.read_struct() + } + + pub fn out_message_cell(&self)-> Cell { + self.out_msg.cell() + } + + pub fn read_transaction(&self) -> Result { + self.transaction.read_struct() + } + + pub fn transaction_cell(&self)-> Cell { + self.transaction.cell() + } +} + +#[cfg(feature = "ton")] +impl Serializable for OutMsgNewDefer { + fn write_to(&self, cell: &mut BuilderData) -> Result<()> { + cell.checked_append_reference(self.out_msg.cell())?; + cell.checked_append_reference(self.transaction.cell())?; + Ok(()) + } +} + +#[cfg(feature = "ton")] +impl Deserializable for OutMsgNewDefer { + fn read_from(&mut self, cell: &mut SliceData) -> Result<()> { + self.out_msg.read_from_reference(cell)?; + self.transaction.read_from_reference(cell)?; + Ok(()) + } +} + +/// msg_export_deferred_tr$10101 out_msg:^MsgEnvelope imported:^InMsg = OutMsg; +#[cfg(feature = "ton")] +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct OutMsgDeferredTransit { + out_msg: ChildCell, + imported: ChildCell, +} + +#[cfg(feature = "ton")] +impl OutMsgDeferredTransit { + pub fn with_cells(env_cell: Cell, imported_cell: Cell) -> Self { + OutMsgDeferredTransit { + out_msg: ChildCell::with_cell(env_cell), + imported: ChildCell::with_cell(imported_cell), + } + } + + pub fn read_out_message(&self) -> Result { + self.out_msg.read_struct() + } + + pub fn out_message_cell(&self)-> Cell { + self.out_msg.cell() + } + + pub fn read_imported(&self) -> Result { + self.imported.read_struct() + } + + pub fn imported_cell(&self)-> Cell { + self.imported.cell() + } +} + +#[cfg(feature = "ton")] +impl Serializable for OutMsgDeferredTransit { + fn write_to(&self, cell: &mut BuilderData) -> Result<()> { + cell.checked_append_reference(self.out_msg.cell())?; + cell.checked_append_reference(self.imported.cell())?; + Ok(()) + } +} + +#[cfg(feature = "ton")] +impl Deserializable for OutMsgDeferredTransit { + fn read_from(&mut self, cell: &mut SliceData) -> Result<()> { + self.out_msg.read_from_reference(cell)?; + self.imported.read_from_reference(cell)?; + Ok(()) + } +} \ No newline at end of file From 248b2440af763c9b5f8de3cd4068e60664d61bdd Mon Sep 17 00:00:00 2001 From: Vladimir Lebedev Date: Thu, 26 Sep 2024 18:53:19 +0700 Subject: [PATCH 4/6] Fix InMsg new variants parsing --- src/inbound_messages.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/inbound_messages.rs b/src/inbound_messages.rs index b4eb9dc..dd68e93 100644 --- a/src/inbound_messages.rs +++ b/src/inbound_messages.rs @@ -113,9 +113,9 @@ const MSG_IMPORT_TR: u8 = 0b00000101; const MSG_DISCARD_FIN: u8 = 0b00000110; const MSG_DISCARD_TR: u8 = 0b00000111; #[cfg(feature = "ton")] -const MSG_IMPORT_DEFERRED_FIN: u8 = 0b00100; +const MSG_IMPORT_DEFERRED_FIN: u8 = 0b00000100; #[cfg(feature = "ton")] -const MSG_IMPORT_DEFERRED_TR: u8 = 0b00101; +const MSG_IMPORT_DEFERRED_TR: u8 = 0b00000101; /// /// Inbound message @@ -519,7 +519,7 @@ impl Deserializable for InMsg { MSG_DISCARD_FIN => read_msg_descr!(cell, InMsgDiscardedFinal, DiscardedFinal), MSG_DISCARD_TR => read_msg_descr!(cell, InMsgDiscardedTransit, DiscardedTransit), #[cfg(feature = "ton")] - 0b00100000 => { + 0b00000001 => { let subtag = cell.get_next_bit()?; if subtag { read_msg_descr!(cell, InMsgDeferredTransit, DeferredTransit) From c620877f60dd1bc76a1e1d070eb703e7fe169368 Mon Sep 17 00:00:00 2001 From: Vladimir Lebedev Date: Thu, 26 Sep 2024 18:58:23 +0700 Subject: [PATCH 5/6] Fix InMsg new variants parsing --- src/inbound_messages.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/inbound_messages.rs b/src/inbound_messages.rs index dd68e93..ad3efbf 100644 --- a/src/inbound_messages.rs +++ b/src/inbound_messages.rs @@ -520,11 +520,16 @@ impl Deserializable for InMsg { MSG_DISCARD_TR => read_msg_descr!(cell, InMsgDiscardedTransit, DiscardedTransit), #[cfg(feature = "ton")] 0b00000001 => { - let subtag = cell.get_next_bit()?; - if subtag { - read_msg_descr!(cell, InMsgDeferredTransit, DeferredTransit) - } else { - read_msg_descr!(cell, InMsgDeferredFinal, DeferredFinal) + let subtag = cell.get_next_bits(2)?[0]; + match subtag { + 0b00 => read_msg_descr!(cell, InMsgDeferredFinal, DeferredFinal), + 0b01 => read_msg_descr!(cell, InMsgDeferredTransit, DeferredTransit), + _ => fail!( + BlockError::InvalidConstructorTag { + t: ((tag << 2) | subtag) as u32, + s: "InMsg".to_string() + } + ) } } tag => fail!( From 9543f6afb9341fcea2457353f3ae7034f86b821c Mon Sep 17 00:00:00 2001 From: Vladimir Lebedev Date: Thu, 26 Sep 2024 19:01:03 +0700 Subject: [PATCH 6/6] Fix InMsg new variants parsing --- src/inbound_messages.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/inbound_messages.rs b/src/inbound_messages.rs index ad3efbf..28cb6cf 100644 --- a/src/inbound_messages.rs +++ b/src/inbound_messages.rs @@ -520,7 +520,7 @@ impl Deserializable for InMsg { MSG_DISCARD_TR => read_msg_descr!(cell, InMsgDiscardedTransit, DiscardedTransit), #[cfg(feature = "ton")] 0b00000001 => { - let subtag = cell.get_next_bits(2)?[0]; + let subtag = (cell.get_next_bits(2)?[0] & 0b11000000) >> 6; match subtag { 0b00 => read_msg_descr!(cell, InMsgDeferredFinal, DeferredFinal), 0b01 => read_msg_descr!(cell, InMsgDeferredTransit, DeferredTransit),