This commit is contained in:
PacoX
2026-05-13 10:43:57 +02:00
parent 8296f44a4e
commit 94ed729985
2 changed files with 30 additions and 10 deletions
+5 -4
View File
@@ -15,7 +15,6 @@ The device capability determines the hash width (number of bytes per hop):
| 1 byte | 256 | Single-byte node IDs | | 1 byte | 256 | Single-byte node IDs |
| 2 bytes | 65,536 | Medium meshes | | 2 bytes | 65,536 | Medium meshes |
| 3 bytes | 16.7M | Large networks | | 3 bytes | 16.7M | Large networks |
| 4 bytes | 4.3B | Gigantic deployments |
### Device Capability Detection ### Device Capability Detection
@@ -24,12 +23,14 @@ On device connection, the app reads the firmware capability to set `pathHashByte
```dart ```dart
// Read from device info response (offset 81) // Read from device info response (offset 81)
final modeRaw = firmwareBytes.length >= 82 final modeRaw = firmwareBytes.length >= 82
? (firmwareBytes[81] & 0x3F) ? (firmwareBytes[81] & 0xFF)
: 0; : 0;
final mode = modeRaw.clamp(0, 3); final mode = modeRaw.clamp(0, 2);
_pathHashByteWidth = mode + 1; // 1, 2, 3, or 4 bytes per hop _pathHashByteWidth = mode + 1; // 1, 2, or 3 bytes per hop
``` ```
The current implementation intentionally clamps to modes `0..2`, so the supported hop width is `1..3` bytes. Do not document 4-byte hops unless the connector implementation is widened first.
### Path Data Structure ### Path Data Structure
Paths in messages and storage consist of: Paths in messages and storage consist of:
+24 -5
View File
@@ -51,6 +51,12 @@ class PathTraceData {
String _hopKey(Uint8List hopBytes) => PathHelper.formatHopHex(hopBytes); String _hopKey(Uint8List hopBytes) => PathHelper.formatHopHex(hopBytes);
Uint8List _lastHopChunk(Uint8List path, int hopWidth) {
if (path.isEmpty) return Uint8List(0);
final width = hopWidth.clamp(1, path.length);
return Uint8List.fromList(path.sublist(path.length - width));
}
class PathTraceMapScreen extends StatefulWidget { class PathTraceMapScreen extends StatefulWidget {
final String title; final String title;
final Uint8List path; final Uint8List path;
@@ -208,8 +214,9 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
} }
final mirroredHops = <Uint8List>[...pathHops]; final mirroredHops = <Uint8List>[...pathHops];
if (widget.targetContact?.type == advTypeRepeater || final isRepeaterOrRoom = widget.targetContact?.type == advTypeRepeater ||
widget.targetContact?.type == advTypeRoom) { widget.targetContact?.type == advTypeRoom;
if (isRepeaterOrRoom) {
final pk = widget.targetContact?.publicKey; final pk = widget.targetContact?.publicKey;
if (pk != null && pk.length >= hopWidth) { if (pk != null && pk.length >= hopWidth) {
mirroredHops.add(Uint8List.fromList(pk.sublist(0, hopWidth))); mirroredHops.add(Uint8List.fromList(pk.sublist(0, hopWidth)));
@@ -220,8 +227,16 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
), ),
); );
} }
// For repeaters/rooms, include full reversed path
mirroredHops.addAll(pathHops.reversed);
} else {
// For non-repeater/room targets, reverse without duplicating the pivot hop
if (pathHops.length > 1) {
mirroredHops.addAll(
pathHops.sublist(0, pathHops.length - 1).reversed,
);
}
} }
mirroredHops.addAll(pathHops.reversed);
final traceBytes = <int>[]; final traceBytes = <int>[];
for (final hop in mirroredHops) { for (final hop in mirroredHops) {
@@ -396,7 +411,8 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
(c) => (c) =>
c.hasLocation && c.hasLocation &&
c.path.isNotEmpty && c.path.isNotEmpty &&
_hopKey(Uint8List.fromList([c.path.last])) == hopKey, _hopKey(_lastHopChunk(c.path, widget.pathHashByteWidth)) ==
hopKey,
) )
.toList(); .toList();
if (peers.isNotEmpty) { if (peers.isNotEmpty) {
@@ -442,7 +458,10 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
(c) => (c) =>
c.hasLocation && c.hasLocation &&
c.path.isNotEmpty && c.path.isNotEmpty &&
_hopKey(Uint8List.fromList([c.path.last])) == lastHopKey, _hopKey(
_lastHopChunk(c.path, widget.pathHashByteWidth),
) ==
lastHopKey,
) )
.toList(); .toList();
if (peers.isNotEmpty) { if (peers.isNotEmpty) {