mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-11-11 12:37:33 +00:00
Pins the behaviour that has been silently broken since #1283/#1289.
The server's touchRelayLastSeen (cmd/server/store.go) calls
TouchNodeLastSeen, which issues `UPDATE nodes SET last_seen`. The server
opens SQLite with mode=ro (cmd/server/db.go:54), so that UPDATE fails with
"attempt to write a readonly database" on every call. The call site
discards the error:
if err := s.db.TouchNodeLastSeen(pk, ts); err == nil {
s.lastSeenTouched[pk] = now
}
Net effect: nodes.last_seen tracks ADVERT arrivals only. Relay
participation has never refreshed it, so infra nodes on long advert
cadences look stale while actively carrying traffic.
Verified against a production store (live.saarmesh.de, 1388 nodes): 1362
have last_seen within one minute of their own most recent ADVERT.
Five tests, all against the ingestor (the writer-owning process, which
already resolves hop prefixes to full pubkeys for observations.resolved_path
since #1547):
- AdvancesLastSeen — the core regression
- NeverGoesBackwards — monotonic guard for out-of-order ingest
- Debounces — write amplification guard on the hot path
- IgnoresEmptyAndUnknown— unresolved hops must not create rows
- MalformedTimestamp — unparsable rxTime is a no-op
TouchRelayNodes is stubbed as a no-op and Stats.RelayTouches added so the
suite compiles and reds on assertions rather than on a build error
(AGENTS.md § Test-First red-commit bar).
Red output:
--- FAIL: TestTouchRelayNodes_AdvancesLastSeen
last_seen = "2026-07-01T00:00:00Z", want "2026-07-10T12:00:00Z"
RelayTouches = 0, want 1
--- FAIL: TestTouchRelayNodes_Debounces
RelayTouches = 0, want 1 (second touch should be debounced)
Refs #1598, #1611
Co-Authored-By: Claude <noreply@anthropic.com>