diff options
| author | tv <tv@krebsco.de> | 2026-10-30 16:10:34 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-30 16:10:34 +0100 |
| commit | 0ee0cd19b7ceabf5d75e1b8fdd074a6e758bc6db (patch) | |
| tree | 741690960d20823792f3eac0b5fe1d12835755fc /src/transport/sim.rs | |
| parent | dfac9af1d96702f451b9d48ec7127455c3a1c560 (diff) | |
decouple simulation test from mycelium
Diffstat (limited to 'src/transport/sim.rs')
| -rw-r--r-- | src/transport/sim.rs | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/src/transport/sim.rs b/src/transport/sim.rs index 2410bba..a558e9f 100644 --- a/src/transport/sim.rs +++ b/src/transport/sim.rs @@ -1,9 +1,9 @@ //! A simulated network for tests: many nodes in one process, each with a //! [`SimTransport`] on a shared [`SimNet`]. //! -//! Messages go through the Mycelium wire encoding (`mycelium::encode_message`), so the -//! codec is exercised as in production; without the mycelium feature, through the wire -//! encoding alone, as libp2p and Tor send it. The net delays, loses and duplicates them per +//! Messages go through the wire encoding (`WIRE`, as libp2p and Tor send it), so the +//! codec is exercised as in production; a net can use a transport's envelope instead +//! (`SimNet::with_codec`; Mycelium's tests run a swarm on its envelope). The net delays, loses and duplicates them per //! link, from a seeded generator; nodes can be taken down (everything to and from them //! is lost) and brought up again; and a test can inject a message as if a node had sent //! it, e.g. one that arrives late. @@ -25,8 +25,6 @@ use bytes::Bytes; use tokio::sync::{mpsc, oneshot}; use tracing::{debug, warn}; -#[cfg(feature = "mycelium")] -pub(crate) use super::mycelium::{decode_message, encode_message}; use super::{EncodedMessage, MessageHandler, MessageKind, ParsedMessage, Transport}; use crate::locks::MutexExt; use crate::testrand::Rng; @@ -88,11 +86,19 @@ struct NetInner { #[derive(Clone)] pub(crate) struct SimNet { inner: Arc<Mutex<NetInner>>, + codec: Codec, } impl SimNet { + /// Messages in the wire encoding alone (`WIRE`). pub(crate) fn new(seed: u64) -> Self { + Self::with_codec(seed, WIRE) + } + + /// Messages put into bytes by `codec`. + pub(crate) fn with_codec(seed: u64, codec: Codec) -> Self { Self { + codec, inner: Arc::new(Mutex::new(NetInner { rng: Rng::new(seed), default_link: LinkParams::default(), @@ -217,7 +223,7 @@ impl SimNet { /// net. For messages a real node wouldn't send at that moment, e.g. one sent long /// ago and delivered late. pub(crate) async fn inject(&self, from: &str, to: &str, message: &ParsedMessage) -> Result<()> { - let encoded = encode_message(to, message)?; + let encoded = (self.codec.encode)(to, message)?; let (handled_tx, handled_rx) = oneshot::channel(); let delivery = Delivery { from: from.to_owned(), @@ -251,9 +257,22 @@ pub(crate) struct SimTransport { inbox: tokio::sync::Mutex<Option<mpsc::UnboundedReceiver<Delivery>>>, } -/// Without Mycelium: a message in the wire encoding alone, as libp2p and Tor send it. -#[cfg(not(feature = "mycelium"))] -pub(crate) fn encode_message(peer: &str, message: &ParsedMessage) -> Result<EncodedMessage> { +/// How a simulated net puts messages into bytes and back (`SimNet::with_codec`): the +/// wire encoding alone (`WIRE`, as libp2p and Tor send it), or a transport's envelope +/// around it (Mycelium's: `mycelium::CODEC`), so a whole swarm runs on that envelope. +#[derive(Clone, Copy)] +pub(crate) struct Codec { + pub(crate) encode: fn(&str, &ParsedMessage) -> Result<EncodedMessage>, + pub(crate) decode: fn(&[u8]) -> Result<ParsedMessage>, +} + +/// The wire encoding alone (`transport::wire`). +pub(crate) const WIRE: Codec = Codec { + encode: wire_encode, + decode: wire_decode, +}; + +fn wire_encode(peer: &str, message: &ParsedMessage) -> Result<EncodedMessage> { let body = super::wire::encode(message)?; Ok(EncodedMessage { peer: peer.to_owned(), @@ -265,9 +284,7 @@ pub(crate) fn encode_message(peer: &str, message: &ParsedMessage) -> Result<Enco }) } -/// The message in a body made by [`encode_message`]. -#[cfg(not(feature = "mycelium"))] -pub(crate) fn decode_message(body: &[u8]) -> Result<ParsedMessage> { +fn wire_decode(body: &[u8]) -> Result<ParsedMessage> { Ok(super::wire::decode(body)?) } @@ -296,7 +313,7 @@ impl Transport for SimTransport { } fn encode(&self, peer: &str, message: &ParsedMessage) -> Result<EncodedMessage> { - encode_message(peer, message) + (self.net.codec.encode)(peer, message) } /// Always accepted: the net loses messages silently, like Mycelium once it has @@ -312,7 +329,7 @@ impl Transport for SimTransport { bail!("consumer of {} already started", self.id); }; while let Some(delivery) = inbox.recv().await { - match decode_message(&delivery.body) { + match (self.net.codec.decode)(&delivery.body) { Ok(message) => { debug!(node = %self.id, from = %delivery.from, message = ?message, "Simulated delivery"); if let Err(error) = handler(delivery.from, message, delivery.payload_len).await |
