mirror of
https://github.com/logos-messaging/libchat.git
synced 2026-08-12 10:03:13 +00:00
Add readme
This commit is contained in:
parent
4dbd004298
commit
a0e1226f21
15
Cargo.lock
generated
15
Cargo.lock
generated
@ -3706,6 +3706,21 @@ version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||
|
||||
[[package]]
|
||||
name = "meshshark"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"crossbeam-channel",
|
||||
"crossterm 0.29.0",
|
||||
"libc",
|
||||
"logos-delivery",
|
||||
"ratatui",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.9"
|
||||
|
||||
68
bin/meshshark/README.md
Normal file
68
bin/meshshark/README.md
Normal file
@ -0,0 +1,68 @@
|
||||
# meshshark
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
A sniffer for logos-delivery networks. meshshark starts an embedded
|
||||
logos-delivery node, subscribes to the content topics you ask for, and shows
|
||||
arriving-message metadata live in a terminal UI — one pane per subscription, or
|
||||
a single merged stream.
|
||||
|
||||
It reports metadata only: arrival time (as a delta from start), a color-coded
|
||||
content topic, and the payload size. Payload bytes are never inspected, only
|
||||
measured, and an FNV-1a hash of each payload is used as a message id so you can
|
||||
spot duplicate deliveries.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
meshshark --sub <ADDRESS|TOPIC> [--sub …] [--all] [--preset …] [--port …]
|
||||
```
|
||||
|
||||
A value passed to `--sub` that starts with `/` is used verbatim as a content
|
||||
topic; anything else is treated as a delivery address and wrapped as
|
||||
`/logos-chat/1/<address>/proto`.
|
||||
|
||||
```sh
|
||||
# Watch two delivery addresses
|
||||
meshshark --sub saro --sub raya
|
||||
|
||||
# Watch a full content topic, plus a firehose of everything the node receives
|
||||
meshshark --sub /logos-chat/1/saro/proto --all
|
||||
```
|
||||
|
||||
You need at least one `--sub` to join a shard and receive anything, even when
|
||||
using `--all`.
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `-s, --sub <ADDRESS\|TOPIC>` | — | Topic to watch (repeatable). One pane each. |
|
||||
| `--all` | off | Add a firehose pane showing every message on any content topic. |
|
||||
| `--preset <NAME>` | `logos.dev` | logos-delivery network preset. |
|
||||
| `--log-level <LEVEL>` | `ERROR` | Node log level. Kept quiet so it doesn't corrupt the TUI. |
|
||||
| `--port <PORT>` | OS-assigned | TCP/UDP port for the node. A free port is chosen by default so multiple instances can run side by side. |
|
||||
|
||||
## Keys
|
||||
|
||||
| Key | Action |
|
||||
| --- | --- |
|
||||
| `v` / `Tab` | Toggle between grid and unified views. |
|
||||
| `a` | Add a subscription at runtime (type an address or topic, `Enter` to confirm, `Esc` to cancel). |
|
||||
| `q` / `Esc` | Quit. |
|
||||
| `Ctrl-C` | Quit from any mode. |
|
||||
|
||||
## Views
|
||||
|
||||
- **Grid** — one pane per subscription, each keeping the last 500 messages.
|
||||
- **Unified** — a single newest-first merged stream across all subscriptions,
|
||||
keeping the last 1000 messages.
|
||||
|
||||
## Notes
|
||||
|
||||
meshshark links the native logos-delivery node through the `logos-delivery`
|
||||
crate. Because the embedded Nim/libwaku runtime installs `atexit` handlers that
|
||||
block on node teardown, meshshark exits via `_exit` rather than a normal
|
||||
shutdown — the OS reclaims the node at process exit.
|
||||
BIN
bin/meshshark/docs/meshshark_screen.png
Normal file
BIN
bin/meshshark/docs/meshshark_screen.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 621 KiB |
@ -40,7 +40,10 @@ fn fnv1a_64(bytes: &[u8]) -> u64 {
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(name = "meshshark", about = "See what is happening on a logos-delivery network")]
|
||||
#[command(
|
||||
name = "meshshark",
|
||||
about = "See what is happening on a logos-delivery network"
|
||||
)]
|
||||
struct Cli {
|
||||
/// Topic to watch (repeatable). One pane each. A value starting with `/`
|
||||
/// is used as a full content topic; otherwise it is treated as a delivery
|
||||
@ -92,7 +95,7 @@ fn main() {
|
||||
// never needs the bytes themselves.
|
||||
let start_cfg = P2pConfig {
|
||||
preset: cli.preset.clone(),
|
||||
tcp_port: port,
|
||||
port,
|
||||
log_level: cli.log_level.clone(),
|
||||
};
|
||||
let mut delivery = match ThreadedDeliveryWrapper::start(start_cfg, |event: WakuEvent| {
|
||||
|
||||
@ -125,7 +125,11 @@ impl App {
|
||||
/// unified stream. A message on a named topic lands in both its pane and any
|
||||
/// firehose (`ALL`) pane.
|
||||
pub fn record(&mut self, msg: ObservedMessage) {
|
||||
for pane in self.panes.iter_mut().filter(|p| p.matches(&msg.content_topic)) {
|
||||
for pane in self
|
||||
.panes
|
||||
.iter_mut()
|
||||
.filter(|p| p.matches(&msg.content_topic))
|
||||
{
|
||||
pane.record(msg.clone());
|
||||
}
|
||||
if self.unified.len() == UNIFIED_HISTORY {
|
||||
@ -205,7 +209,10 @@ fn draw_header(frame: &mut Frame, app: &App, area: Rect) {
|
||||
.fg(Color::Cyan)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::styled(format!(" · port {}", app.port), Style::default().fg(Color::DarkGray)),
|
||||
Span::styled(
|
||||
format!(" · port {}", app.port),
|
||||
Style::default().fg(Color::DarkGray),
|
||||
),
|
||||
];
|
||||
frame.render_widget(Paragraph::new(Line::from(spans)), area);
|
||||
}
|
||||
@ -272,7 +279,12 @@ fn draw_pane(frame: &mut Frame, pane: &Pane, area: Rect, start: Instant) {
|
||||
} else {
|
||||
pane.content_topic.as_str()
|
||||
};
|
||||
let title = format!(" {} ({} msgs, {}) ", label, pane.count, human_bytes(pane.total_bytes),);
|
||||
let title = format!(
|
||||
" {} ({} msgs, {}) ",
|
||||
label,
|
||||
pane.count,
|
||||
human_bytes(pane.total_bytes),
|
||||
);
|
||||
// Color the border by topic so a pane's color matches its lines in the
|
||||
// unified view. A firehose pane mixes topics, so leave it neutral.
|
||||
let border_color = if pane.match_all {
|
||||
@ -357,7 +369,12 @@ fn draw_status(frame: &mut Frame, app: &App, area: Rect) {
|
||||
ViewMode::Unified => "unified",
|
||||
};
|
||||
let text = if app.status.is_empty() {
|
||||
format!(" {} subs · {} msgs · view {} ", app.panes.len(), total, view)
|
||||
format!(
|
||||
" {} subs · {} msgs · view {} ",
|
||||
app.panes.len(),
|
||||
total,
|
||||
view
|
||||
)
|
||||
} else {
|
||||
format!(" {} ", app.status)
|
||||
};
|
||||
|
||||
@ -29,21 +29,12 @@ pub const DEFAULT_NETWORK_PRESET: &str = "logos.dev";
|
||||
/// Default TCP port for the embedded logos-delivery node.
|
||||
pub const DEFAULT_TCP_PORT: u16 = 60000;
|
||||
|
||||
<<<<<<< HEAD
|
||||
/// The content-topic prefix carrying logos-chat traffic.
|
||||
const CHAT_TOPIC_PREFIX: &str = "/logos-chat/1/";
|
||||
|
||||
pub fn content_topic_for(delivery_address: &str) -> String {
|
||||
format!("{CHAT_TOPIC_PREFIX}{delivery_address}/proto")
|
||||
}
|
||||
=======
|
||||
pub fn content_topic_for(delivery_address: &str) -> String {
|
||||
format!("/logos-chat/1/{delivery_address}/proto")
|
||||
}
|
||||
|
||||
/// The content-topic prefix carrying logos-chat traffic.
|
||||
const CHAT_TOPIC_PREFIX: &str = "/logos-chat/1/";
|
||||
>>>>>>> 08e9b4f (Isolate logos-delivery)
|
||||
|
||||
// ── EmbeddedLogosDelivery ──────────────────────────────────────────────────
|
||||
|
||||
|
||||
@ -49,20 +49,12 @@ type SubscriberList<T> = Arc<Mutex<Vec<Sender<T>>>>;
|
||||
pub const DEFAULT_NETWORK_PRESET: &str = "logos.dev";
|
||||
|
||||
/// Default TCP port for the embedded logos-delivery node.
|
||||
<<<<<<< HEAD
|
||||
pub const DEFAULT_PORT: u16 = 60000;
|
||||
=======
|
||||
pub const DEFAULT_TCP_PORT: u16 = 60000;
|
||||
>>>>>>> 08e9b4f (Isolate logos-delivery)
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct P2pConfig {
|
||||
pub preset: String,
|
||||
<<<<<<< HEAD
|
||||
pub port: u16,
|
||||
=======
|
||||
pub tcp_port: u16,
|
||||
>>>>>>> 08e9b4f (Isolate logos-delivery)
|
||||
pub log_level: String,
|
||||
}
|
||||
|
||||
@ -70,11 +62,7 @@ impl Default for P2pConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
preset: DEFAULT_NETWORK_PRESET.into(),
|
||||
<<<<<<< HEAD
|
||||
port: DEFAULT_PORT,
|
||||
=======
|
||||
tcp_port: DEFAULT_TCP_PORT,
|
||||
>>>>>>> 08e9b4f (Isolate logos-delivery)
|
||||
log_level: "ERROR".into(),
|
||||
}
|
||||
}
|
||||
@ -293,13 +281,8 @@ impl<T> ThreadedDeliveryWrapper<T> {
|
||||
"logLevel": cfg.log_level,
|
||||
"mode": "Core",
|
||||
"preset": cfg.preset,
|
||||
<<<<<<< HEAD
|
||||
"tcpPort": cfg.port,
|
||||
"discv5UdpPort": cfg.port,
|
||||
=======
|
||||
"tcpPort": cfg.tcp_port,
|
||||
"discv5UdpPort": cfg.tcp_port,
|
||||
>>>>>>> 08e9b4f (Isolate logos-delivery)
|
||||
})
|
||||
.to_string();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user