Files
meshcore-analyzer/cmd
AdamandClaude Opus 5.5 d777f4b7ce fix(ingestor): only flood relay hops refresh nodes.last_seen (#2307) (#2308)
Fixes #2307.

The ingestor refreshed `nodes.last_seen` for every resolved hop in a
path. For DIRECT routes those hops are still to come, and for TRACE
`path_json` is the route the trace was asked to take, so tracing or
messaging a switched-off repeater kept it looking recently heard.

## What changes

**`cmd/ingestor/db.go`**
- New `pathHopsTransmitted(data)`: true only when
`PathBytesAreHops(payloadType)` and the route is FLOOD or
TRANSPORT_FLOOD. It's the same rule as the server's `relayHopHexLen` in
`certain_heard.go`.
- `InsertTransmission` calls `touchRelayNodesLocked` only when that
holds. `observations.resolved_path` is still written for every
observation, so analytics are unchanged.
- The route and payload type come from the observation's own decoded
header (`PacketData`), not the transmission's first frame (see #2266).

## Perf

There's one integer comparison per observation, before the existing
touch. The touch now skips DIRECT and TRACE observations, so it does
fewer `UPDATE nodes` calls, never more.

## Tests

`cmd/ingestor/relay_touch_test.go`:
`TestInsertTransmission_TouchesOnlyFloodRelays` goes through
`InsertTransmission` with a real store and prefix index, using a node
whose 2-byte prefix is unique:

- FLOOD and TRANSPORT_FLOOD TXT_MSG: `last_seen` advances to the rx time
- DIRECT TXT_MSG and DIRECT TRACE: `last_seen` is unchanged

With `db.go` from master, the DIRECT and TRACE cases fail.

How I checked:
- `go vet ./...` and `go test ./...` in `cmd/ingestor` pass, and `gofmt
-l` is clean (`golang:1.27` container, since there's no local Go
toolchain).
- No server, frontend or schema changes, so I didn't run the browser and
E2E steps.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 15:41:48 +01:00
..