diff options
| -rw-r--r-- | src/node.rs | 2 | ||||
| -rw-r--r-- | src/remake/mod.rs | 4 | ||||
| -rw-r--r-- | src/state/peer.rs | 2 | ||||
| -rw-r--r-- | src/state/session.rs | 13 | ||||
| -rw-r--r-- | src/swarm/auth.rs | 9 | ||||
| -rw-r--r-- | src/swarm/blob.rs | 16 | ||||
| -rw-r--r-- | src/swarm/peer/handshake.rs | 2 | ||||
| -rw-r--r-- | src/swarm/peer/inbound.rs | 4 | ||||
| -rw-r--r-- | src/swarm/peer/keepalive.rs | 2 | ||||
| -rw-r--r-- | src/swarm/relay.rs | 2 | ||||
| -rw-r--r-- | src/swarm/source.rs | 22 | ||||
| -rw-r--r-- | src/swarm/sync.rs | 10 | ||||
| -rw-r--r-- | src/swarm/throughput.rs | 2 | ||||
| -rw-r--r-- | src/transport/mod.rs | 8 | ||||
| -rw-r--r-- | src/transport/traffic.rs | 10 |
15 files changed, 57 insertions, 51 deletions
diff --git a/src/node.rs b/src/node.rs index 9330bb6..57ee302 100644 --- a/src/node.rs +++ b/src/node.rs @@ -1,5 +1,5 @@ //! Building a node and starting its workers: what `main` does once it has read the -//! configuration and connected to Mycelium, and what the simulator (`transport::sim`) +//! configuration and connected its transport, and what the simulator (`transport::sim`) //! does for every simulated node. Everything here is independent of where the //! transport and the settings come from. diff --git a/src/remake/mod.rs b/src/remake/mod.rs index 79e0a1b..ca7f5a0 100644 --- a/src/remake/mod.rs +++ b/src/remake/mod.rs @@ -224,8 +224,8 @@ impl PeerSummary { /// Admin routes. Merged into the authenticated part of the node's router. /// Largest remake request (bytes). The proposal carries the new document to every -/// node in one sync message, which Mycelium must deliver within its deadline, so -/// documents near this size are already a stretch. +/// node in one sync message, which the transport must deliver within its delivery +/// limit, so documents near this size are already a stretch. const REMAKE_REQUEST_LIMIT: usize = 64 * 1024 * 1024; pub(crate) fn router<H: Host>() -> Router<H> { diff --git a/src/state/peer.rs b/src/state/peer.rs index 92329b2..8086f63 100644 --- a/src/state/peer.rs +++ b/src/state/peer.rs @@ -191,7 +191,7 @@ impl PeerState { } /// Start Automerge sync with this peer from scratch. A message still being handed to - /// Mycelium was generated against the old state; its outcome is then ignored. + /// the transport was generated against the old state; its outcome is then ignored. pub(crate) fn reset_sync(&mut self) { // The same waits for answers, from the start. let mut reply_backoff = self.sync.reply_backoff; diff --git a/src/state/session.rs b/src/state/session.rs index 6efe538..cd1ab30 100644 --- a/src/state/session.rs +++ b/src/state/session.rs @@ -17,7 +17,8 @@ use tracing::debug; use crate::backoff::Backoff; use crate::swarm::throughput::SyncBytes; -/// A sync message on its way to our Mycelium (the HTTP request is in progress). +/// A sync message being handed to our transport (for Mycelium: the HTTP request is in +/// progress). #[derive(Clone)] pub(crate) struct Sending { /// Changes it carries for the first time; taken back if the send fails. @@ -30,7 +31,7 @@ pub(crate) struct Sending { /// Session IDs, unique within the process. static NEXT_SESSION: AtomicU64 = AtomicU64::new(1); -/// First wait before generating again after our Mycelium refused a message; doubles +/// First wait before generating again after our transport refused a message; doubles /// while it keeps refusing. const SEND_RETRY: Duration = Duration::from_millis(500); const SEND_RETRY_MAX: Duration = Duration::from_secs(30); @@ -43,10 +44,10 @@ pub(crate) struct SyncSession { id: u64, state: sync::State, - /// A message being handed to our Mycelium. + /// A message being handed to our transport. pub(crate) sending: Option<Sending>, - /// After our Mycelium refused a message: no new one before this. The refused one is + /// After our transport refused a message: no new one before this. The refused one is /// not kept; the next one is generated afresh and carries everything pending. pub(crate) retry_at: Option<Instant>, /// The wait after the next refusal. @@ -233,7 +234,7 @@ impl SyncSession { self.id } - /// Our Mycelium took the message generated from session `session`. Returns whether + /// Our transport took the message generated from session `session`. Returns whether /// to generate again: a pass was requested while it was handed over, or a reset /// replaced the session meanwhile (any pass requested then was lost with the old /// session, and the new one hasn't necessarily opened yet). @@ -248,7 +249,7 @@ impl SyncSession { .is_some_and(|sending| sending.regenerate) } - /// Our Mycelium refused the message: as far as the peer is concerned, it was never + /// Our transport refused the message: as far as the peer is concerned, it was never /// sent. Takes back its changes (they go out with the next message), clears /// `in_flight`, and returns how long to wait before generating again. None if a reset /// already discarded what was being sent (the message came from another `session`). diff --git a/src/swarm/auth.rs b/src/swarm/auth.rs index 46efd77..3bfbd4d 100644 --- a/src/swarm/auth.rs +++ b/src/swarm/auth.rs @@ -1,9 +1,10 @@ //! Swarm membership by pre-shared key. //! -//! Mycelium authenticates the sender of every message (`src_pk` can't be forged), so we -//! always know *who* talks to us. With a swarm key configured, only nodes that also know -//! the key may take part: HELLO and HELLO_REPLY carry a tag proving it, and until a peer -//! has sent a valid one, everything else it sends is ignored. +//! The transport authenticates the sender of every message (for Mycelium, `src_pk` +//! can't be forged), so we always know *who* talks to us. With a swarm key configured, +//! only nodes that also know the key may take part: HELLO and HELLO_REPLY carry a tag +//! proving it, and until a peer has sent a valid one, everything else it sends is +//! ignored. //! //! The tag is `HMAC-SHA256(key, label ‖ swarm_id ‖ from_pk ‖ to_pk)`. It needs no //! challenge: it is bound to both keys, and only `from_pk` can send as `from_pk`, so a diff --git a/src/swarm/blob.rs b/src/swarm/blob.rs index c13bcd9..ec99c93 100644 --- a/src/swarm/blob.rs +++ b/src/swarm/blob.rs @@ -1,12 +1,12 @@ //! Blobs: content-addressed bytes fetched in chunks from several peers at once. //! -//! Large transfers can't go in one Mycelium message (it must arrive within Mycelium's -//! five-minute deadline), and a blob every node holds identically can come from many -//! of them. A blob is an Automerge change by its hash (e.g. an epoch's snapshot change, -//! which every node on that epoch holds byte for byte), or content by its BLAKE3 hash -//! (e.g. the new document of a `replace` or `import` remake), or the changes between two -//! sets of heads (a delta: what a peer lacks, when one sync message would be too large; -//! `swarm::sync`). +//! Large transfers can't go in one message (it must arrive within the transport's +//! delivery limit, five minutes for Mycelium), and a blob every node holds identically +//! can come from many of them. A blob is an Automerge change by its hash (e.g. an +//! epoch's snapshot change, which every node on that epoch holds byte for byte), or +//! content by its BLAKE3 hash (e.g. the new document of a `replace` or `import` +//! remake), or the changes between two sets of heads (a delta: what a peer lacks, when +//! one sync message would be too large; `swarm::sync`). //! //! * Serving: a request without chunks gets the manifest (size, chunk size, a BLAKE3 //! hash per chunk); one with chunks gets each chunk as a message of its own. A node @@ -85,7 +85,7 @@ pub(crate) struct Blobs { /// A sync message larger than this many chunks is sent as a delta blob instead /// (`swarm::sync`): below it, a blob costs more round trips than it saves; above it, a /// lost message costs too much to send again whole, and a slow link may not deliver it -/// within Mycelium's deadline. +/// within the transport's delivery limit. const DELTA_THRESHOLD_CHUNKS: usize = 16; /// The largest sync message accepted: the threshold of a sender with the largest chunks diff --git a/src/swarm/peer/handshake.rs b/src/swarm/peer/handshake.rs index 109a42f..4c657ad 100644 --- a/src/swarm/peer/handshake.rs +++ b/src/swarm/peer/handshake.rs @@ -109,7 +109,7 @@ pub(super) async fn retry_hello_if_due(state: &AppState, peer: &str) -> Result<( } /// Sends a HELLO without holding any lock, then schedules the next retry. -/// Success and failure both end in AwaitingReply: Mycelium accepting the message +/// Success and failure both end in AwaitingReply: the transport accepting the message /// says nothing about whether the peer received it. async fn transmit_hello(state: &AppState, peer: &str) -> Result<()> { let swarm_id = state.swarm_id().await; diff --git a/src/swarm/peer/inbound.rs b/src/swarm/peer/inbound.rs index 745e646..a1f6646 100644 --- a/src/swarm/peer/inbound.rs +++ b/src/swarm/peer/inbound.rs @@ -31,8 +31,8 @@ pub(crate) async fn handle_message( return Ok(()); } - // A reply to a HELLO from an earlier run of ours (late, or queued in Mycelium while - // we were down) says nothing about now; the peer answers our current HELLO. + // A reply to a HELLO from an earlier run of ours (late, or queued by the transport + // while we were down) says nothing about now; the peer answers our current HELLO. if let transport::ParsedMessage::HelloReply(reply) = &message && reply.run_id != state.run_id { diff --git a/src/swarm/peer/keepalive.rs b/src/swarm/peer/keepalive.rs index b22d954..ce2951b 100644 --- a/src/swarm/peer/keepalive.rs +++ b/src/swarm/peer/keepalive.rs @@ -29,7 +29,7 @@ const FAREWELL_TIMEOUT: Duration = Duration::from_secs(2); /// At shutdown: one last PING to each neighbour, saying we aren't ready. A neighbour /// catching up from us picks another source now, instead of once we go dormant. Bounded -/// in time: our Mycelium may be gone already. +/// in time: our transport may be gone already. pub(crate) async fn farewell(state: &AppState) { state.stopping.store(true, Ordering::Release); let mut pings = tokio::task::JoinSet::new(); diff --git a/src/swarm/relay.rs b/src/swarm/relay.rs index b1cc0a7..202ae40 100644 --- a/src/swarm/relay.rs +++ b/src/swarm/relay.rs @@ -36,7 +36,7 @@ use crate::transport::{self, HeadsSummary}; const PULL_TIMEOUT: Duration = Duration::from_secs(15); /// How long an announcement waits for further changes to ride along. Added once per -/// hop to propagation; well below a round trip over Mycelium. +/// hop to propagation; well below a round trip over the transport. const ANNOUNCE_DELAY: Duration = Duration::from_millis(200); /// After changes from `from` were applied and our heads changed: tell our other diff --git a/src/swarm/source.rs b/src/swarm/source.rs index e7f06fb..699b03b 100644 --- a/src/swarm/source.rs +++ b/src/swarm/source.rs @@ -5,9 +5,9 @@ //! document gets the whole document from each of its peers, and a node that is merely //! behind gets the missing changes from each. Automerge can't deduplicate across peers. //! So one suitable peer becomes the source, preferably the closest by round-trip time -//! (a clearly closer one gets a 1 s head start to claim it, else the first to ask); -//! the others wait until the initial sync is done, and then only exchange heads. Messages from waiting -//! peers are still applied; we just don't answer them yet. +//! (a clearly closer one gets a 1 s head start to claim it, else the first to ask); the +//! others wait until the initial sync is done, and then only exchange heads. Messages +//! from waiting peers are still applied; we just don't answer them yet. //! //! A source must be ready and willing to sync with us, as far as we know (its sync //! messages and keepalives say so). It counts as alive while any message from it @@ -20,14 +20,14 @@ //! big answer lost on the way, a stuck sync state) would keep us catching up forever. //! So it is also given up after three of our sync messages in a row went unanswered, //! once nothing from it can still be on the way: no sync message from it for -//! `Timing::delivery_limit`, after which Mycelium has delivered or dropped anything it -//! sent before. It isn't chosen again for another `delivery_limit`, so another peer -//! takes over rather than the same one stalling again; if it is the only candidate, -//! catching up waits that long before trying it again. It also gets a fresh HELLO: a -//! joining node learns of other peers only from HELLO_REPLYs, and the one it got from -//! this peer may have listed none (a peer lists only its neighbours, which a new member -//! isn't until its registration has spread). Meanwhile, every minute without a sync message from it is logged as a -//! warning. +//! `Timing::delivery_limit`, after which the transport has delivered or dropped +//! anything it sent before. It isn't chosen again for another `delivery_limit`, so +//! another peer takes over rather than the same one stalling again; if it is the only +//! candidate, catching up waits that long before trying it again. It also gets a fresh +//! HELLO: a joining node learns of other peers only from HELLO_REPLYs, and the one it +//! got from this peer may have listed none (a peer lists only its neighbours, which a +//! new member isn't until its registration has spread). Meanwhile, every minute without +//! a sync message from it is logged as a warning. use std::sync::atomic::Ordering; use std::time::Duration; diff --git a/src/swarm/sync.rs b/src/swarm/sync.rs index 4e382ec..011f049 100644 --- a/src/swarm/sync.rs +++ b/src/swarm/sync.rs @@ -162,7 +162,8 @@ async fn deliver_sync_to_peer(state: &AppState, peer: &str) -> Result<()> { return transport::SyncBody::Message(payload); } // Too large for one message: all or nothing, and on a slow link - // within Mycelium's deadline. The peer fetches it in chunks. + // within the transport's delivery limit. The peer fetches it in + // chunks. let from = peer_state.sync.withdraw_for_delta(); let spec = transport::DeltaSpec::new(from, replica.heads().to_vec()); info!( @@ -213,7 +214,7 @@ async fn deliver_sync_to_peer(state: &AppState, peer: &str) -> Result<()> { (session, encoded) }; - // Off the sync worker: a slow send (a large message, a busy Mycelium) mustn't hold + // Off the sync worker: a slow send (a large message, a busy transport) mustn't hold // up every other peer's. One message per peer is in flight (`sending`), so a peer's // messages still go out in order. let state = state.clone(); @@ -240,7 +241,10 @@ async fn send_generated( Ok(()) => { let regenerate = peer_state_mutex.lock().await.sync.send_succeeded(session); - trace!(regenerate, "Outbound sync message accepted by Mycelium"); + trace!( + regenerate, + "Outbound sync message accepted by the transport" + ); if regenerate { state diff --git a/src/swarm/throughput.rs b/src/swarm/throughput.rs index f1b9b14..85a3fc8 100644 --- a/src/swarm/throughput.rs +++ b/src/swarm/throughput.rs @@ -19,7 +19,7 @@ use tokio::time::Instant; use crate::transport::traffic::Traffic; -/// Smallest exchange that counts: some dozens of Mycelium chunks. +/// Smallest exchange that counts: some dozens of small packets (Mycelium's: 1300 bytes). const MIN_BYTES: u64 = 32 * 1024; const WEIGHT: f64 = 0.25; diff --git a/src/transport/mod.rs b/src/transport/mod.rs index d97c51c..61b1f4b 100644 --- a/src/transport/mod.rs +++ b/src/transport/mod.rs @@ -21,10 +21,10 @@ pub(crate) mod wire; /// Random identifier of one run of a node (from start to exit). pub(crate) type RunId = [u8; 16]; -/// Most heads listed in a keepalive; more are sent as a digest. A head takes 34 bytes on -/// the wire, so 32 of them keep a keepalive within one Mycelium chunk (1300 bytes; see -/// the size test in `mycelium`). There are rarely more heads than nodes that wrote -/// concurrently since the last merging write. +/// Most heads listed in a keepalive; more are sent as a digest. A head takes 34 bytes +/// on the wire, so 32 of them keep a keepalive within one small packet (a Mycelium +/// chunk: 1300 bytes; see the size test in `mycelium`). There are rarely more heads +/// than nodes that wrote concurrently since the last merging write. pub(crate) const MAX_LISTED_HEADS: usize = 32; /// A document's heads, compactly: the heads themselves while there are few, otherwise a diff --git a/src/transport/traffic.rs b/src/transport/traffic.rs index 0d93525..f9b8289 100644 --- a/src/transport/traffic.rs +++ b/src/transport/traffic.rs @@ -1,9 +1,9 @@ //! Messages and bytes exchanged with each peer, by kind: counted where every message //! passes anyway, at the transport. No messages of our own. //! -//! Bytes are payload bytes, what the Mycelium message carries, without its framing, -//! the topic, or the base64 of its HTTP API. Counters only grow (from the start of the -//! process); rates are for whoever reads them. +//! Bytes are payload bytes, what a message carries, without the transport's framing +//! (for Mycelium: the topic, or the base64 of its HTTP API). Counters only grow (from +//! the start of the process); rates are for whoever reads them. //! //! A message dropped by the debug firewall still counts as sent (the firewall plays a //! lossy network) but not as received. @@ -58,10 +58,10 @@ impl ByKind { #[derive(Debug, Default, Clone, Copy, Serialize)] #[serde(rename_all = "camelCase")] pub(crate) struct PeerTraffic { - /// Handed to Mycelium (it accepted them). + /// Handed to the transport (it accepted them). pub(crate) sent: ByKind, pub(crate) received: ByKind, - /// Sends Mycelium refused (e.g. no route to the peer); not counted as sent. + /// Sends the transport refused (e.g. no route to the peer); not counted as sent. pub(crate) refused: ByKind, } |
