use crate::types::ProtocolMessage;
use bincode::Options;
use serde::{Serialize, de::DeserializeOwned};
pub const MAX_MESSAGE_SIZE: usize = 16 * 1024 * 1024;
fn wire_options() -> impl Options {
bincode::options().with_limit(MAX_MESSAGE_SIZE as u64)
}
pub fn serialize<T: Serialize + ?Sized>(value: &T) -> Result<Vec<u8>, bincode::Error> {
wire_options().serialize(value)
}
pub fn deserialize<T: DeserializeOwned>(bytes: &[u8]) -> Result<T, bincode::Error> {
wire_options().deserialize(bytes)
}
pub fn encode_protocol_message(msg: &ProtocolMessage) -> Result<Vec<u8>, bincode::Error> {
serialize(msg)
}
pub fn decode_protocol_message(bytes: &[u8]) -> Result<ProtocolMessage, bincode::Error> {
deserialize(bytes)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::types::MessageRouting;
use libp2p::PeerId;
fn message(recipient: Option<PeerId>) -> ProtocolMessage {
ProtocolMessage {
protocol: "/test-protocol/1.0.0".to_string(),
routing: MessageRouting {
message_id: 42,
round_id: 7,
sender: PeerId::random(),
recipient,
},
payload: b"protocol payload bytes".to_vec(),
}
}
fn assert_round_trip(msg: &ProtocolMessage) {
let bytes = encode_protocol_message(msg).expect("encode failed");
let decoded = decode_protocol_message(&bytes).expect("decode failed");
assert_eq!(decoded.protocol, msg.protocol);
assert_eq!(decoded.payload, msg.payload);
assert_eq!(decoded.routing.message_id, msg.routing.message_id);
assert_eq!(decoded.routing.round_id, msg.routing.round_id);
assert_eq!(decoded.routing.sender, msg.routing.sender);
assert_eq!(decoded.routing.recipient, msg.routing.recipient);
}
#[test]
fn round_trip_broadcast_routing() {
assert_round_trip(&message(None));
}
#[test]
fn round_trip_direct_routing() {
assert_round_trip(&message(Some(PeerId::random())));
}
#[test]
fn send_path_bytes_decode_via_receive_path_options() {
let msg = message(Some(PeerId::random()));
let bytes = encode_protocol_message(&msg).expect("encode failed");
let decoded = bincode::options()
.with_limit(MAX_MESSAGE_SIZE as u64)
.deserialize::<ProtocolMessage>(&bytes)
.expect("receive-path options must decode send-path bytes");
assert_eq!(decoded.payload, msg.payload);
assert_eq!(decoded.routing.message_id, msg.routing.message_id);
}
#[test]
fn oversized_message_fails_on_encode() {
let mut msg = message(None);
msg.payload = vec![0u8; MAX_MESSAGE_SIZE + 1];
assert!(
encode_protocol_message(&msg).is_err(),
"encoding must fail fast when the payload exceeds MAX_MESSAGE_SIZE"
);
}
}