From d131c2b92b799738a4067e426c9f558ea4cbf41f Mon Sep 17 00:00:00 2001 From: behzad nouri Date: Mon, 18 Nov 2024 21:43:21 +0000 Subject: [PATCH] removes serde::Serialize trait bound from Packet::{from_data,populate_packet} (#3636) As part of https://github.com/anza-xyz/agave/pull/3575 we need to implement bincode (de)serialization without deriving serde Serialize/Deserialize traits. Packet::{from_data,populate_packet} methods also only require that the data to be bincode serializable and do not care about serde either. Next version of bincode provides the necessary traits to achieve this functionality: https://docs.rs/bincode/2.0.0-rc.3/bincode/enc/trait.Encode.html but that is not released yet. In order to avoid serde::Serialize trait bound on Packet::{from_data,populate_packet}, the commit adds a new Encode trait which only requires implementing bincode serialization. --- perf/src/packet.rs | 6 +++--- sdk/packet/src/lib.rs | 25 ++++++++++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/perf/src/packet.rs b/perf/src/packet.rs index 81ffeaa7aea392..73c29bc53788a9 100644 --- a/perf/src/packet.rs +++ b/perf/src/packet.rs @@ -1,5 +1,5 @@ //! The `packet` module defines data structures and methods to pull data from the network. -pub use solana_packet::{Meta, Packet, PacketFlags, PACKET_DATA_SIZE}; +pub use solana_packet::{self, Meta, Packet, PacketFlags, PACKET_DATA_SIZE}; use { crate::{cuda_runtime::PinnedVec, recycler::Recycler}, bincode::config::Options, @@ -73,7 +73,7 @@ impl PacketBatch { batch } - pub fn new_unpinned_with_recycler_data_and_dests( + pub fn new_unpinned_with_recycler_data_and_dests( recycler: &PacketBatchRecycler, name: &'static str, dests_and_data: &[(SocketAddr, T)], @@ -85,7 +85,7 @@ impl PacketBatch { for ((addr, data), packet) in dests_and_data.iter().zip(batch.packets.iter_mut()) { if !addr.ip().is_unspecified() && addr.port() != 0 { - if let Err(e) = Packet::populate_packet(packet, Some(addr), &data) { + if let Err(e) = Packet::populate_packet(packet, Some(addr), data) { // TODO: This should never happen. Instead the caller should // break the payload into smaller messages, and here any errors // should be propagated. diff --git a/sdk/packet/src/lib.rs b/sdk/packet/src/lib.rs index 0f29fe7d327011..fe25e4ffa108f4 100644 --- a/sdk/packet/src/lib.rs +++ b/sdk/packet/src/lib.rs @@ -2,10 +2,13 @@ #![cfg_attr(feature = "frozen-abi", feature(min_specialization))] #![cfg_attr(docsrs, feature(doc_auto_cfg))] -#[cfg(feature = "bincode")] -use bincode::{Options, Result}; #[cfg(feature = "frozen-abi")] use solana_frozen_abi_macro::AbiExample; +#[cfg(feature = "bincode")] +use { + bincode::{Options, Result}, + std::io::Write, +}; use { bitflags::bitflags, std::{ @@ -28,6 +31,18 @@ static_assertions::const_assert_eq!(PACKET_DATA_SIZE, 1232); /// 8 bytes is the size of the fragment header pub const PACKET_DATA_SIZE: usize = 1280 - 40 - 8; +#[cfg(feature = "bincode")] +pub trait Encode { + fn encode(&self, writer: W) -> Result<()>; +} + +#[cfg(feature = "bincode")] +impl Encode for T { + fn encode(&self, writer: W) -> Result<()> { + bincode::serialize_into::(writer, self) + } +} + bitflags! { #[repr(C)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] @@ -159,21 +174,21 @@ impl Packet { } #[cfg(feature = "bincode")] - pub fn from_data(dest: Option<&SocketAddr>, data: T) -> Result { + pub fn from_data(dest: Option<&SocketAddr>, data: T) -> Result { let mut packet = Self::default(); Self::populate_packet(&mut packet, dest, &data)?; Ok(packet) } #[cfg(feature = "bincode")] - pub fn populate_packet( + pub fn populate_packet( &mut self, dest: Option<&SocketAddr>, data: &T, ) -> Result<()> { debug_assert!(!self.meta.discard()); let mut wr = std::io::Cursor::new(self.buffer_mut()); - bincode::serialize_into(&mut wr, data)?; + ::encode(data, &mut wr)?; self.meta.size = wr.position() as usize; if let Some(dest) = dest { self.meta.set_socket_addr(dest);