Commit Graph

7 Commits

Author SHA1 Message Date
Johnathan Corgan
13c0b70dc3 Add rustfmt formatting policy and reformat codebase
Add rustfmt.toml with stable defaults and apply cargo fmt to all
source files. This establishes a consistent formatting baseline
for CI enforcement.
2026-04-10 08:27:07 +00:00
Johnathan Corgan
71a5c68fa9 Implement comprehensive node and transport statistics
Add 71 new counters (84 values) across three categories:

Node statistics (NodeStats, plain u64 — single handler context):
- Forwarding: 9 counters x (packets + bytes) = 18 values. Covers
  received, decode_error, ttl_exhausted, delivered, forwarded,
  drop_no_route, drop_mtu_exceeded, drop_send_error, originated.
- Discovery: 17 counters (packets only). Request path: received,
  decode_error, duplicate, already_visited, target_is_us, forwarded,
  ttl_exhausted, initiated, deduplicated. Response path: received,
  decode_error, forwarded, identity_miss, proof_failed, accepted,
  timed_out.
- Error signals: 3 counters — coords_required, path_broken,
  mtu_exceeded.
- Spanning tree: 16 counters. Inbound announce handling (received
  through accepted, parent switch, loop detection, ancestry change),
  outbound (sent, rate limited, send failed), cumulative events
  (parent switches/losses, flap dampening).
- Bloom filter: 10 counters. Inbound (received through accepted),
  outbound (sent, debounce suppressed, send failed).

Transport statistics (AtomicU64 + Arc — shared with spawned tasks):
- UDP (6 counters, 8 values): packets/bytes sent/recv, send_errors,
  recv_errors, mtu_exceeded, kernel_drops (stub for SO_MEMINFO).
- TCP (10 counters, 12 values): packets/bytes sent/recv, send_errors,
  recv_errors, mtu_exceeded, plus connection lifecycle counters
  (established, accepted, rejected, timeouts, refused).

Control socket integration:
- show_routing: forwarding, discovery, error signal stats
- show_tree: spanning tree stats + per-peer bloom metrics
  (estimated_count, set_bits, fill_ratio) and coordinate paths
- show_bloom: bloom filter stats + per-peer snapshots
- show_transports: per-transport stats snapshots

Also refactor UDP transport from flat files (udp.rs + udp_stats.rs)
into directory module (udp/mod.rs + udp/stats.rs) matching TCP
structure, and fix pre-existing clippy warnings in tree/tests.rs.
2026-02-28 18:23:04 +00:00
Johnathan Corgan
717be3d960 Restrict bloom filter propagation to tree edges, update design docs
Gate peer_inbound_filters() to only collect from tree peers (parent
and children), so outgoing filter computation merges only tree-sourced
information. All peers still receive FilterAnnounce messages and store
filters locally for routing queries — the restriction is only on what
gets merged into outgoing filters.

This prevents bloom filter saturation where mesh shortcuts cause every
node's filter to converge toward the full network. With tree-only
merge, filters contain subtree (from children) + complement (from
parent) + single-hop mesh views.

Implementation:
- Add is_tree_peer() helper to determine tree parent/child relationship
- Gate peer_inbound_filters() to tree peers only (single control point)
- Trigger bloom filter exchange on tree relationship changes
- Add est_entries, set_bits, fill ratio, and tree_peer fields to
  FilterAnnounce send/receive debug logs
- Add test_bloom_filter_split_horizon test verifying directional
  asymmetry: upward filters contain only the child's subtree, downward
  filters contain only the complement
- Add print_filter_cardinality diagnostic helper for test inspection

Design docs:
- fips-bloom-filters.md: Add directional asymmetry and mesh peer filter
  subsections, update per-peer filter model, saturation mitigation,
  implementation status table
- fips-mesh-operation.md: Update filter propagation description, add
  directional asymmetry, tree relationship change trigger
- fips-intro.md: Rewrite bloom propagation paragraph for tree-only merge
2026-02-23 14:00:00 +00:00
Johnathan Corgan
9605cbafe3 Human-readable peer identifiers in log messages
Replace raw NodeAddr hex strings in log output with human-readable
identifiers using a four-tier lookup: configured alias, active peer
short npub, session endpoint short npub, or truncated hex fallback.

- Add PeerIdentity::short_npub() for compact npub display (npub1xxxx...yyyy)
- Add NodeAddr::short_hex() for compact hex fallback (first 4 bytes + ...)
- Add peer_aliases map populated at startup from peer config
- Add Node::peer_display_name() with four-tier resolution
- Add SessionEntry::remote_pubkey() accessor for session-layer lookups
- Update all 120 log field occurrences across 11 handler/node files
- Pass pre-computed display names to MMP static metric/teardown methods
  to work around borrow checker constraints in iterator loops
2026-02-19 05:04:19 +00:00
Johnathan Corgan
ab7a4bac29 Logging level overhaul: reduce verbosity at info and debug levels
Per-packet happy-path events (UDP send/receive, TUN I/O, MMP report
processing, TreeAnnounce/FilterAnnounce sent, RTT samples) moved from
debug to trace. Periodic maintenance and retry scheduling moved from
info to debug. Session state changes (established, initiated, torn
down) and transport stop promoted from debug to info. MMP report send
failures demoted from warn to debug (normal under churn).
2026-02-19 04:15:08 +00:00
Johnathan Corgan
89bc9cc4b0 Fix bloom filter cascade: gate re-announcements on content change
FilterAnnounce messages never settled in steady state because
handle_filter_announce unconditionally marked all peers for
re-announcement on every inbound filter, creating a perpetual
ping-pong at ~1 message/sec.

Added last_sent_filters tracking to BloomState. mark_changed_peers()
computes outgoing filters and compares against what was last sent,
only marking peers whose filter content actually differs.
2026-02-14 23:36:39 +00:00
Johnathan Corgan
5d7af5b478 Implement FilterAnnounce send/receive, remove TTL/K-hop scoping
Add bloom filter reachability announcement protocol:
- FilterAnnounce encode/decode (wire format 0x20, 1035 bytes)
- node/bloom.rs: send/receive with debounce, split-horizon loop prevention
- Handler wiring: dispatch, tick, peer promotion/removal, cross-connection
- Five integration tests: 10-node, star, chain, ring, 100-node convergence

Remove TTL/K-hop mechanism from code and design docs after discovering
that per-entry TTL scoping is fundamentally incompatible with flat bloom
filter merge + regeneration architecture. Each node re-originates filters
with fresh TTL, making propagation unbounded regardless of TTL value.
Split-horizon remains the primary loop prevention mechanism.

Document spanning tree known limitations (v1) in spanning-tree-dynamics.md.

316 tests pass, clean build, zero warnings.
2026-02-11 03:16:25 +00:00