diff --git a/Cargo.lock b/Cargo.lock index 310ecdf6ec..b2786d4974 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7756,7 +7756,6 @@ dependencies = [ name = "nym-sphinx" version = "1.20.1" dependencies = [ - "bincode", "log", "nym-crypto", "nym-metrics", @@ -7778,7 +7777,6 @@ dependencies = [ "serde", "thiserror 2.0.17", "tokio", - "tokio-util", "tracing", ] diff --git a/common/client-core/src/client/inbound_messages.rs b/common/client-core/src/client/inbound_messages.rs index 7e81ea6570..a09a595f91 100644 --- a/common/client-core/src/client/inbound_messages.rs +++ b/common/client-core/src/client/inbound_messages.rs @@ -6,6 +6,7 @@ use bincode::Options; use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag; use nym_sphinx::params::PacketType; +use nym_sphinx::receiver::ReconstructedMessage; use nym_task::connections::TransmissionLane; use serde::{Deserialize, Serialize}; use std::convert::TryInto; @@ -264,6 +265,53 @@ impl Decoder for InputMessageCodec { } } +/// Codec for encoding/decoding `ReconstructedMessage` for the AsyncRead interface. +/// +/// This codec was moved from `nymsphinx::receiver` to keep bincode serialization +/// out of the core sphinx crate. +pub struct ReconstructedMessageCodec; + +impl Encoder for ReconstructedMessageCodec { + type Error = ClientCoreError; + + fn encode( + &mut self, + item: ReconstructedMessage, + buf: &mut BytesMut, + ) -> Result<(), Self::Error> { + let encoded = make_bincode_serializer().serialize(&item)?; + let encoded_len = encoded.len() as u32; + buf.reserve(LENGHT_ENCODING_PREFIX_SIZE + encoded.len()); + buf.extend_from_slice(&encoded_len.to_le_bytes()); + buf.extend_from_slice(&encoded); + Ok(()) + } +} + +impl Decoder for ReconstructedMessageCodec { + type Item = ReconstructedMessage; + type Error = ClientCoreError; + + fn decode(&mut self, buf: &mut BytesMut) -> Result, Self::Error> { + if buf.len() < LENGHT_ENCODING_PREFIX_SIZE { + return Ok(None); + } + + let len = u32::from_le_bytes(buf[0..LENGHT_ENCODING_PREFIX_SIZE].try_into()?) as usize; + + if buf.len() < len + LENGHT_ENCODING_PREFIX_SIZE { + return Ok(None); + } + + let decoded = make_bincode_serializer() + .deserialize(&buf[LENGHT_ENCODING_PREFIX_SIZE..len + LENGHT_ENCODING_PREFIX_SIZE])?; + + buf.advance(len + LENGHT_ENCODING_PREFIX_SIZE); + + Ok(Some(decoded)) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/common/nymsphinx/Cargo.toml b/common/nymsphinx/Cargo.toml index e5cd7941ae..44ef0638cc 100644 --- a/common/nymsphinx/Cargo.toml +++ b/common/nymsphinx/Cargo.toml @@ -14,9 +14,7 @@ rand_distr = { workspace = true } rand_chacha = { workspace = true } thiserror = { workspace = true } serde = { workspace = true, features = ["derive"] } -bincode = { workspace = true } log = { workspace = true } -tokio-util = { workspace = true, features = ["codec"] } nym-sphinx-acknowledgements = { workspace = true } nym-sphinx-addressing = { workspace = true } diff --git a/common/nymsphinx/src/lib.rs b/common/nymsphinx/src/lib.rs index 7d725dfc87..c27867635b 100644 --- a/common/nymsphinx/src/lib.rs +++ b/common/nymsphinx/src/lib.rs @@ -22,10 +22,3 @@ pub use nym_sphinx_framing as framing; // TEMP UNTIL FURTHER REFACTORING pub use preparer::payload::NymPayloadBuilder; - -fn make_bincode_serializer() -> impl bincode::Options { - use bincode::Options; - bincode::DefaultOptions::new() - .with_big_endian() - .with_varint_encoding() -} diff --git a/common/nymsphinx/src/receiver.rs b/common/nymsphinx/src/receiver.rs index da38e7fb09..76a9ed8a0d 100644 --- a/common/nymsphinx/src/receiver.rs +++ b/common/nymsphinx/src/receiver.rs @@ -3,9 +3,7 @@ use std::io; -use crate::make_bincode_serializer; use crate::message::{NymMessage, NymMessageError, PaddedMessage, PlainMessage}; -use bincode::Options; use nym_crypto::aes::cipher::{KeyIvInit, StreamCipher}; use nym_crypto::asymmetric::x25519; use nym_crypto::shared_key::recompute_shared_key; @@ -21,8 +19,6 @@ use nym_sphinx_params::{ }; use serde::{Deserialize, Serialize}; use thiserror::Error; -use tokio_util::bytes::{Buf, BytesMut}; -use tokio_util::codec::{Decoder, Encoder}; // TODO: should this live in this file? #[derive(Debug, Serialize, Deserialize)] @@ -63,50 +59,6 @@ impl From for ReconstructedMessage { } } -pub struct ReconstructedMessageCodec; -const LENGHT_ENCODING_PREFIX_SIZE: usize = 4; - -impl Encoder for ReconstructedMessageCodec { - type Error = MessageRecoveryError; - - fn encode( - &mut self, - item: ReconstructedMessage, - buf: &mut BytesMut, - ) -> Result<(), Self::Error> { - let encoded = make_bincode_serializer().serialize(&item)?; - let encoded_len = encoded.len() as u32; - buf.reserve(LENGHT_ENCODING_PREFIX_SIZE + encoded.len()); - buf.extend_from_slice(&encoded_len.to_le_bytes()); - buf.extend_from_slice(&encoded); - Ok(()) - } -} - -impl Decoder for ReconstructedMessageCodec { - type Item = ReconstructedMessage; - type Error = MessageRecoveryError; - - fn decode(&mut self, buf: &mut BytesMut) -> Result, Self::Error> { - if buf.len() < LENGHT_ENCODING_PREFIX_SIZE { - return Ok(None); - } - - let len = u32::from_le_bytes(buf[0..LENGHT_ENCODING_PREFIX_SIZE].try_into()?) as usize; - - if buf.len() < len + LENGHT_ENCODING_PREFIX_SIZE { - return Ok(None); - } - - let decoded = make_bincode_serializer() - .deserialize(&buf[LENGHT_ENCODING_PREFIX_SIZE..len + LENGHT_ENCODING_PREFIX_SIZE])?; - - buf.advance(len + LENGHT_ENCODING_PREFIX_SIZE); - - Ok(Some(decoded)) - } -} - #[derive(Debug, Error)] pub enum MessageRecoveryError { #[error( @@ -129,12 +81,6 @@ pub enum MessageRecoveryError { #[error("Failed to recover message fragment - {0}")] MessageRecoveryError(#[from] io::Error), - - #[error("Failed to serialize/deserialize message")] - SerializationError(#[from] Box), - - #[error("Invalid length prefix bytes")] - InvalidLengthPrefix(#[from] std::array::TryFromSliceError), } pub trait MessageReceiver { diff --git a/sdk/rust/nym-sdk/src/mixnet/native_client.rs b/sdk/rust/nym-sdk/src/mixnet/native_client.rs index be287ff6db..e30abf3edd 100644 --- a/sdk/rust/nym-sdk/src/mixnet/native_client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/native_client.rs @@ -6,7 +6,7 @@ use bytes::{Buf as _, BytesMut}; use futures::{ready, Future, FutureExt, Sink, SinkExt, Stream, StreamExt}; use log::{debug, error}; use nym_client_core::client::base_client::GatewayConnection; -use nym_client_core::client::inbound_messages::InputMessageCodec; +use nym_client_core::client::inbound_messages::{InputMessageCodec, ReconstructedMessageCodec}; use nym_client_core::client::mix_traffic::ClientRequestSender; use nym_client_core::client::{ base_client::{ClientInput, ClientOutput, ClientState}, @@ -17,7 +17,6 @@ use nym_client_core::config::{ForgetMe, RememberMe}; use nym_crypto::asymmetric::ed25519; use nym_gateway_requests::ClientRequest; use nym_sphinx::addressing::clients::Recipient; -use nym_sphinx::receiver::ReconstructedMessageCodec; use nym_sphinx::{params::PacketType, receiver::ReconstructedMessage}; use nym_statistics_common::clients::{ClientStatsEvents, ClientStatsSender}; use nym_task::connections::{ConnectionCommandSender, LaneQueueLengths};