mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-26 16:45:22 +00:00
Add mesh diagnostics: /ping, /trace, and topology map (#1377)
* Add mesh diagnostics: /ping, /trace, and topology map - New protocol types ping=0x26 / pong=0x27 (9-byte payload: 8-byte nonce + origin TTL) with per-peer inbound rate limiting (5 per 10s) - /ping @name reports RTT and hop count, 10s timeout - /trace @name prints the estimated path from gossiped directNeighbors - Topology map sheet (circular Canvas layout) reachable from App Info - Ping/pong ride the deterministic directed-relay path like DMs - Tests: payload round-trip, hop-count math, command output, edge normalization, layout Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Fix CI media-wipe race, per-link ping rate limiting, and /ping output routing Three fixes for PR #1377 review: 1. CI flake (sendImage_privateChatProcessesAndTransfersImage): the panicClearAllData / clearCurrentPublicTimeline detached utility-priority tasks delete the real ~/Library/Application Support/files tree, which the test process shares. The wipe fires at a nondeterministic time and raced the sendImage test's JPEG in files/images/outgoing (write then re-read), so prepareImagePacket threw and the test timed out. Both wipes are now skipped under tests (existing TestEnvironment.isRunningTests pattern); this also stops test runs from deleting the developer's real media. 2. Codex P1: ping packets are unsigned, so keying the pong rate limiter on packet.senderID let one connected peer rotate forged sender IDs to bypass the 5-per-10s budget. The limiter now keys on the ingress link (the directly connected peer that delivered the packet); the pong still goes to the claimed sender. Regression test proves rotating senders over one link exhaust one budget (fails 10 vs 5 pongs on the old code). 3. Codex P2: /ping output arrived up to 10s later and was routed from selectedPrivateChatPeer at callback time, misrouting the result after a chat switch. The origin conversation is now captured when the command is issued (CommandOutputDestination) and deferred output is routed there: a DM result lands in the origin chat's history even if deselected, and a mesh-timeline result pins to #mesh instead of the active channel. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * App Info: move NETWORK section under HOW TO USE and uppercase NETWORK/SYMBOLS headers Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Conform DiagnosticsMockContext to sendPublicMessage CommandContextProvider gained sendPublicMessage (Cashu /pay, #1376) after this branch forked, so the diagnostics test mock no longer conformed once main was merged in. Add the no-op stub. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: jack <jackjackbits@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
jack
Claude Fable 5
parent
d4f0c49787
commit
f9032cf2b9
@@ -25,6 +25,8 @@ enum CommandInfo: String, Identifiable {
|
||||
case who
|
||||
case favorite = "fav"
|
||||
case unfavorite = "unfav"
|
||||
case ping
|
||||
case trace
|
||||
|
||||
var id: String { rawValue }
|
||||
|
||||
@@ -32,7 +34,7 @@ enum CommandInfo: String, Identifiable {
|
||||
|
||||
var placeholder: String? {
|
||||
switch self {
|
||||
case .block, .hug, .message, .slap, .unblock, .favorite, .unfavorite:
|
||||
case .block, .hug, .message, .slap, .unblock, .favorite, .unfavorite, .ping, .trace:
|
||||
return "<" + String(localized: "content.input.nickname_placeholder") + ">"
|
||||
case .pay:
|
||||
return "<" + String(localized: "content.input.token_placeholder") + ">"
|
||||
@@ -54,6 +56,8 @@ enum CommandInfo: String, Identifiable {
|
||||
case .who: String(localized: "content.commands.who")
|
||||
case .favorite: String(localized: "content.commands.favorite")
|
||||
case .unfavorite: String(localized: "content.commands.unfavorite")
|
||||
case .ping: String(localized: "content.commands.ping")
|
||||
case .trace: String(localized: "content.commands.trace")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,11 +70,11 @@ enum CommandInfo: String, Identifiable {
|
||||
if !isGeoPublic {
|
||||
commands.append(.pay)
|
||||
}
|
||||
// The processor rejects favorites in geohash contexts, so only
|
||||
// suggest them where they actually work: mesh.
|
||||
// The processor rejects favorites and mesh diagnostics in geohash
|
||||
// contexts, so only suggest them where they actually work: mesh.
|
||||
if isGeoPublic || isGeoDM {
|
||||
return commands
|
||||
}
|
||||
return commands + [.favorite, .unfavorite]
|
||||
return commands + [.favorite, .unfavorite, .ping, .trace]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user