From d7e3d9f8310aa40903f43272fbb30f37a1f68c2b Mon Sep 17 00:00:00 2001 From: tv Date: Mon, 9 Nov 2026 05:20:44 +0000 Subject: dashboard: the transport each message went by, in the console The console said with whom a message went, not how: the message log was noted above the identity layer (`CountingTransport`), where a message is to or from a node, and the address it went to (the paths layer picks one, `Paths::send_first`) or came from is gone. Only the paths layer's own PINGs and PONGs, logged under their addresses, had one. Now the identity layer notes the node's messages (`MessageLog::set_addressed`), with the address each went to (`IdentityTransport::send_proven` returns it) or came from; `CountingTransport` leaves them to it, and still notes them where there is no identity layer (tests). A console line ends with the transport (the address's scheme, in its colour on the map, the address in the tooltip), and the figures box shows the address. A subscribed node's messages carry theirs too, and the map runs every message along its transport's line, not only the PINGs and PONGs. --- src/transport/identity.rs | 68 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 21 deletions(-) (limited to 'src/transport/identity.rs') diff --git a/src/transport/identity.rs b/src/transport/identity.rs index b61fb0f..5d3e2f5 100644 --- a/src/transport/identity.rs +++ b/src/transport/identity.rs @@ -257,6 +257,28 @@ impl Book { } impl IdentityTransport { + /// To the addresses `peer` proved itself at, best first, the next when a send + /// fails (`Paths::send_first`); refused if it proved itself nowhere yet. The address + /// it went to. + async fn send_proven(&self, message: &EncodedMessage) -> Result { + let proven = self.shared.proven_at(&message.peer, true); + if !proven.is_empty() { + self.shared.ask_other_paths(&message.peer); + } + if proven.is_empty() { + let hints = { + let mut book = self.shared.lock(); + book.counts.refused_unproven += 1; + book.hints.get(&message.peer).cloned().unwrap_or_default() + }; + for address in hints { + self.shared.ask(&address, false); + } + return Err(NotProven(message.peer.clone()).into()); + } + self.shared.paths.send_first(message, &proven).await + } + /// Over `transport`, whose addresses have `config.scheme`, and `config.more`. /// `firewall`: the debug firewall, if any, which paths applies by address; `clock`: /// the node's wall clock; `keepalive`: the node's keepalive interval (`Paths::new`). @@ -299,6 +321,9 @@ impl IdentityTransport { admitted: Mutex::default(), } }); + // The node's messages are noted here, with the address each went to or came + // from (`MessageLog`). + shared.traffic.log.set_addressed(); Self { shared } } } @@ -479,7 +504,16 @@ impl Shared { // proofs fill the book (`Book::bind`). let node = self.lock().heard(&address, Instant::now()); match node { - Some(node) => handler(node, message, payload_len).await, + Some(node) => { + self.traffic.log.note( + "received", + &node, + Some(&address), + &message, + payload_len, + ); + handler(node, message, payload_len).await + } None => { self.lock().counts.dropped_unproven += 1; debug!( @@ -749,29 +783,21 @@ impl Transport for IdentityTransport { Ok(encoded) } - /// To the addresses `peer` proved itself at, best first, the next when a send - /// fails (`Paths::send_first`); refused if it proved itself nowhere yet. + /// As `send_proven` does, noted in the message log with the address + /// (`MessageLog`). async fn send_encoded(&self, message: &EncodedMessage) -> Result<()> { - let proven = self.shared.proven_at(&message.peer, true); - if !proven.is_empty() { - self.shared.ask_other_paths(&message.peer); - } - if proven.is_empty() { - let hints = { - let mut book = self.shared.lock(); - book.counts.refused_unproven += 1; - book.hints.get(&message.peer).cloned().unwrap_or_default() + let sent = self.send_proven(message).await; + if let Some(parsed) = &message.message { + let (way, address) = match &sent { + Ok(address) => ("sent", Some(address.as_str())), + Err(_) => ("refused", None), }; - for address in hints { - self.shared.ask(&address, false); - } - return Err(NotProven(message.peer.clone()).into()); + self.shared + .traffic + .log + .note(way, &message.peer, address, parsed, message.payload_len); } - self.shared - .paths - .send_first(message, &proven) - .await - .map(|_| ()) + sent.map(|_| ()) } /// Every transport's consumer (`Paths::start_consumer`); returns when the first -- cgit v1.3.1