From e32783bced33abfad03561477260be5cef91c684 Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Fri, 30 Jan 2026 15:39:16 +0000 Subject: [PATCH] Remove serde requirement for MixPacket --- .../src/client/inbound_messages.rs | 10 +++--- .../input_message_listener.rs | 28 ++++++++++++--- common/nymsphinx/forwarding/src/packet.rs | 34 ------------------- 3 files changed, 30 insertions(+), 42 deletions(-) diff --git a/common/client-core/src/client/inbound_messages.rs b/common/client-core/src/client/inbound_messages.rs index f01ba54749..7e81ea6570 100644 --- a/common/client-core/src/client/inbound_messages.rs +++ b/common/client-core/src/client/inbound_messages.rs @@ -5,7 +5,6 @@ use crate::make_bincode_serializer; use bincode::Options; use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag; -use nym_sphinx::forwarding::packet::MixPacket; use nym_sphinx::params::PacketType; use nym_task::connections::TransmissionLane; use serde::{Deserialize, Serialize}; @@ -26,8 +25,11 @@ pub enum InputMessage { /// Fire an already prepared mix packets into the network. /// No guarantees are made about it. For example no retransmssion /// will be attempted if it gets dropped. + /// + /// Packets are stored as pre-serialized bytes, which avoids + /// requiring Serde on MixPacket. Premade { - msgs: Vec, + packet_bytes: Vec>, lane: TransmissionLane, }, @@ -81,11 +83,11 @@ impl InputMessage { } pub fn new_premade( - msgs: Vec, + packet_bytes: Vec>, lane: TransmissionLane, packet_type: PacketType, ) -> Self { - let message = InputMessage::Premade { msgs, lane }; + let message = InputMessage::Premade { packet_bytes, lane }; if packet_type == PacketType::Mix { message } else { diff --git a/common/client-core/src/client/real_messages_control/acknowledgement_control/input_message_listener.rs b/common/client-core/src/client/real_messages_control/acknowledgement_control/input_message_listener.rs index 69ca92709f..90ced22a6d 100644 --- a/common/client-core/src/client/real_messages_control/acknowledgement_control/input_message_listener.rs +++ b/common/client-core/src/client/real_messages_control/acknowledgement_control/input_message_listener.rs @@ -45,7 +45,25 @@ where } } - async fn handle_premade_packets(&mut self, packets: Vec, lane: TransmissionLane) { + async fn handle_premade_packets(&mut self, packet_bytes: Vec>, lane: TransmissionLane) { + // Deserialize packet bytes back to MixPacket + let packets: Vec = packet_bytes + .into_iter() + .filter_map(|bytes| { + MixPacket::try_from_v2_bytes(&bytes) + .map_err(|e| { + warn!("Failed to deserialize premade packet: {}", e); + e + }) + .ok() + }) + .collect(); + + if packets.is_empty() { + warn!("No valid premade packets to send"); + return; + } + self.message_handler .send_premade_mix_packets( packets @@ -156,7 +174,9 @@ where self.handle_reply(recipient_tag, data, lane, max_retransmissions) .await; } - InputMessage::Premade { msgs, lane } => self.handle_premade_packets(msgs, lane).await, + InputMessage::Premade { packet_bytes, lane } => { + self.handle_premade_packets(packet_bytes, lane).await + } InputMessage::MessageWrapper { message, packet_type, @@ -202,8 +222,8 @@ where self.handle_reply(recipient_tag, data, lane, max_retransmissions) .await; } - InputMessage::Premade { msgs, lane } => { - self.handle_premade_packets(msgs, lane).await + InputMessage::Premade { packet_bytes, lane } => { + self.handle_premade_packets(packet_bytes, lane).await } // MessageWrappers can't be nested InputMessage::MessageWrapper { .. } => { diff --git a/common/nymsphinx/forwarding/src/packet.rs b/common/nymsphinx/forwarding/src/packet.rs index 32b8c893ee..907d2c1cde 100644 --- a/common/nymsphinx/forwarding/src/packet.rs +++ b/common/nymsphinx/forwarding/src/packet.rs @@ -4,11 +4,6 @@ use nym_sphinx_addressing::nodes::{NymNodeRoutingAddress, NymNodeRoutingAddressError}; use nym_sphinx_params::{PacketSize, PacketType, SphinxKeyRotation}; use nym_sphinx_types::{NymPacket, NymPacketError}; -use serde::{ - Deserialize, Deserializer, Serialize, Serializer, - de::{self, Visitor}, -}; -use std::fmt; use nym_sphinx_anonymous_replies::reply_surb::AppliedReplySurb; use nym_sphinx_params::key_rotation::InvalidSphinxKeyRotation; @@ -187,32 +182,3 @@ impl MixPacket { .collect()) } } - -// MAX TODO implement for v1 as well for back compat? - this was added in the original asyncread/write work when we only had one v -impl Serialize for MixPacket { - fn serialize(&self, serializer: S) -> Result { - serializer.serialize_bytes(&self.to_v2_bytes().map_err(serde::ser::Error::custom)?) - } -} - -struct MixPacketVisitor; - -impl<'de> Visitor<'de> for MixPacketVisitor { - type Value = MixPacket; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a byte array representing a mix packet") - } - - fn visit_bytes(self, v: &[u8]) -> Result { - MixPacket::try_from_v2_bytes(v).map_err(serde::de::Error::custom) - } -} - -impl<'de> Deserialize<'de> for MixPacket { - fn deserialize>(deserializer: D) -> Result { - deserializer.deserialize_bytes(MixPacketVisitor) - } -} - -// TODO: test for serialization and errors!