From eb1b6b26a7132fe812131a9e6d65a7b6a9da843a Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Thu, 3 Jul 2025 12:46:30 -0700 Subject: [PATCH] feat!: make serialize function infallible The underlying functions only fail on I/O which doesn't occur when writing to an in memory vector. --- protocol/src/serde.rs | 16 ++++++++-------- protocol/tests/round_trips.rs | 2 +- proxy/src/bin/proxy.rs | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/protocol/src/serde.rs b/protocol/src/serde.rs index 75a64ea..91ebde2 100644 --- a/protocol/src/serde.rs +++ b/protocol/src/serde.rs @@ -17,7 +17,6 @@ pub use bitcoin::p2p::message::{CommandString, NetworkMessage}; #[derive(Debug)] pub enum Error { - Serialize(bitcoin::io::Error), Deserialize(bitcoin::consensus::encode::Error), UnknownShortID(u8), } @@ -25,7 +24,6 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Error::Serialize(e) => write!(f, "Unable to serialize {e}"), Error::Deserialize(e) => write!(f, "Unable to deserialize {e}"), Error::UnknownShortID(b) => write!(f, "Unrecognized short ID when deserializing {b}"), } @@ -35,7 +33,6 @@ impl fmt::Display for Error { impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - Error::Serialize(e) => Some(e), Error::Deserialize(e) => Some(e), Error::UnknownShortID(_) => None, } @@ -43,7 +40,10 @@ impl std::error::Error for Error { } /// Serialize a [`NetworkMessage`] into a buffer. -pub fn serialize(msg: NetworkMessage) -> Result, Error> { +/// +/// This function is infallible because the underlying `consensus_encode()` +/// operations only fail on I/O errors, which cannot occur when writing to an in-memory `Vec`. +pub fn serialize(msg: NetworkMessage) -> Vec { let mut buffer = Vec::new(); match &msg { NetworkMessage::Addr(_) => { @@ -142,7 +142,7 @@ pub fn serialize(msg: NetworkMessage) -> Result, Error> { buffer.push(0u8); msg.command() .consensus_encode(&mut buffer) - .map_err(Error::Serialize)?; + .expect("Encoding to Vec never fails"); } NetworkMessage::Unknown { command, @@ -151,14 +151,14 @@ pub fn serialize(msg: NetworkMessage) -> Result, Error> { buffer.push(0u8); command .consensus_encode(&mut buffer) - .map_err(Error::Serialize)?; + .expect("Encoding to Vec never fails"); } } msg.consensus_encode(&mut buffer) - .map_err(Error::Serialize)?; + .expect("Encoding to Vec never fails"); - Ok(buffer) + buffer } /// Deserialize v2 message into [`NetworkMessage`]. diff --git a/protocol/tests/round_trips.rs b/protocol/tests/round_trips.rs index 0fdd7d0..88b9907 100644 --- a/protocol/tests/round_trips.rs +++ b/protocol/tests/round_trips.rs @@ -271,7 +271,7 @@ fn regtest_handshake() { start_height: 0, relay: false, }; - let message = serialize(NetworkMessage::Version(msg)).unwrap(); + let message = serialize(NetworkMessage::Version(msg)); let packet_len = bip324::OutboundCipher::encryption_buffer_len(message.len()); let mut packet = vec![0u8; packet_len]; encrypter diff --git a/proxy/src/bin/proxy.rs b/proxy/src/bin/proxy.rs index 2e58aaa..62817b9 100644 --- a/proxy/src/bin/proxy.rs +++ b/proxy/src/bin/proxy.rs @@ -114,7 +114,7 @@ async fn v2_proxy( msg.command() ); - let contents = serialize(msg).expect("serialize-able contents into network message"); + let contents = serialize(msg); v2_remote_writer .encrypt_and_write(&contents, &mut remote_writer) .await