mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-27 01:45:20 +00:00
Nostr refactor simplify (#390)
* fix bug * geoDM receive works, send doesnt, and incoming message doesnt make sender appear in peer list * fix nostr dm * geohash dms work * Geohash DM UI: stop mixing Nostr DM temp chats into mesh offline list; ensure geohash DM senders are added to geohash people list only. Removed nostr_* sidebar append in PeopleSection; kept 64-hex mesh offline favorites. Verified build. * refactor * nice * works * merging nostr -> mesh works * tripple click to delete all * fix sidebar icon * remove hash * dms have correct recipient * works * wip unread badge * geohash dms wip * dms work
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
# Announcement Gossip TLV (Direct Neighbors)
|
||||
|
||||
This document specifies an optional TLV extension to the BitChat `ANNOUNCE` message that allows peers to gossip which other peers they are currently connected to directly over Bluetooth. Implementations can use this to build a mesh topology view (nodes = peers, edges = direct connections).
|
||||
|
||||
Status: optional and backward-compatible.
|
||||
|
||||
## Layering Overview
|
||||
|
||||
- Outer packet: BitChat binary packet with `type = 0x01` (ANNOUNCE). Header is unchanged.
|
||||
- Payload: A sequence of TLVs. Unknown TLVs MUST be ignored for forward compatibility.
|
||||
- Signature: The packet MAY be signed using the Ed25519 public key carried in TLV `0x03`. The gossip TLV (if present) is part of the payload and therefore covered by the signature.
|
||||
|
||||
## TLV Format
|
||||
|
||||
Each TLV uses a compact layout:
|
||||
|
||||
- `type`: 1 byte
|
||||
- `length`: 1 byte (0..255)
|
||||
- `value`: `length` bytes
|
||||
|
||||
Existing TLVs (unchanged):
|
||||
|
||||
- `0x01` NICKNAME: UTF‑8 string (≤ 255 bytes)
|
||||
- `0x02` NOISE_PUBLIC_KEY: Noise static public key bytes (typically 32 bytes for X25519)
|
||||
- `0x03` SIGNING_PUBLIC_KEY: Ed25519 public key bytes (typically 32 bytes)
|
||||
|
||||
New TLV (optional):
|
||||
|
||||
- `0x04` DIRECT_NEIGHBORS: Concatenation of up to 10 peer IDs, each encoded as exactly 8 bytes. There is no inner count; the number of neighbors is `length / 8`. If `length` is not a multiple of 8, trailing partial bytes MUST be ignored.
|
||||
|
||||
### Peer ID Binary Encoding (8 bytes)
|
||||
|
||||
Peer IDs are represented as 8 raw bytes (16 hex chars) in “network order” (left‑to‑right):
|
||||
|
||||
- Take the peer ID hex string, lowercase/truncate to at most 16 hex chars.
|
||||
- Convert each 2 hex chars to 1 byte from left to right.
|
||||
- If fewer than 16 hex chars are available, pad the remaining bytes with `0x00` at the end to reach 8 bytes.
|
||||
|
||||
This matches the on‑wire 8‑byte `senderID`/`recipientID` encoding used in the BitChat packet header.
|
||||
|
||||
## Sender Behavior
|
||||
|
||||
- Build the base announcement payload by emitting TLVs `0x01`..`0x03` as usual.
|
||||
- Optionally append TLV `0x04` with up to 10 unique, directly connected peer IDs.
|
||||
- Remove duplicates before encoding.
|
||||
- Order is arbitrary and not semantically significant.
|
||||
- Sign the ANNOUNCE packet so the gossip TLV is covered (recommended):
|
||||
- Signature algorithm: Ed25519 using the key in TLV `0x03`.
|
||||
- Signature input: the binary packet encoding with the signature field omitted and the TTL normalized to `0`. This allows TTL to change during relays without invalidating the signature.
|
||||
- The payload may be compressed per the base protocol; the gossip TLV is encoded prior to optional compression.
|
||||
|
||||
## Receiver Behavior
|
||||
|
||||
- Decompress payload if the packet’s compression flag is set, then parse TLVs in order.
|
||||
- Parse TLVs `0x01`..`0x03` as usual; ignore any unknown TLVs.
|
||||
- If a `0x04` TLV is present:
|
||||
- Interpret the value as `N = length / 8` peer IDs (ignore trailing non‑aligned bytes).
|
||||
- Each 8‑byte chunk is decoded back to a 16‑hex‑char peer ID string (lowercase).
|
||||
- De‑duplicate neighbors.
|
||||
- Topology maintenance guidance (optional, but recommended for consistent behavior):
|
||||
- Maintain, for each announcing peer A, the last announcement timestamp and the neighbor list from TLV `0x04`.
|
||||
- When a newer announcement from A arrives (use the 8‑byte unsigned `timestamp` in the BitChat packet header), replace A’s previously recorded neighbor list with the new one. If older or equal, ignore the neighbor update.
|
||||
- Treat the neighbor list as a set of undirected edges `{A, B}` in your topology visualization; i.e., if A reports direct peers `[B, C]`, add edges A–B and A–C.
|
||||
|
||||
## Limits and Compatibility
|
||||
|
||||
- Max neighbors per TLV: 10. Senders MAY send fewer; receivers MUST accept any number `N ≥ 0` implied by `length / 8` up to the received `length`.
|
||||
- Omission: If the TLV `0x04` is omitted, the announce remains valid. Peers can still chat and interoperate normally; the topology graph will just not include edges reported by that peer (other peers that include A in their neighbor lists can still introduce edges to A).
|
||||
- Unknown TLVs MUST be ignored. This makes the extension safe for older implementations.
|
||||
|
||||
## Minimal Example (conceptual)
|
||||
|
||||
ANNOUNCE payload TLVs (concatenated):
|
||||
|
||||
- `01 [len=N] [UTF‑8 nickname]`
|
||||
- `02 [len=32] [32 bytes X25519 pubkey]`
|
||||
- `03 [len=32] [32 bytes Ed25519 pubkey]`
|
||||
- `04 [len=8*M] [peerID1(8) || peerID2(8) || ... || peerIDM(8)]` (optional)
|
||||
|
||||
Where each `peerIDk(8)` is the 8‑byte binary form of the peer ID as specified above.
|
||||
|
||||
That’s the entire change; the outer packet header, message type, and relay/TTL behavior are unchanged.
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
# Source-Based Routing for BitChat Packets
|
||||
|
||||
This document specifies an optional source-based routing extension to the BitChat packet format. A sender may attach a hop-by-hop route (list of peer IDs) to instruct relays on the intended path. Relays that support this feature will try to forward to the next hop directly; otherwise, they fall back to regular broadcast relaying.
|
||||
|
||||
Status: optional and backward-compatible.
|
||||
|
||||
## Layering Overview
|
||||
|
||||
- Outer packet: BitChat binary packet with unchanged fixed header (version/type/ttl/timestamp/flags/payloadLength).
|
||||
- Flags: adds a new bit `HAS_ROUTE (0x08)`.
|
||||
- Variable sections (when present, in order):
|
||||
1) `SenderID` (8 bytes)
|
||||
2) `RecipientID` (8 bytes) if `HAS_RECIPIENT`
|
||||
3) `Route` (if `HAS_ROUTE`): `count` (1 byte) + `count * 8` bytes hop IDs
|
||||
4) `Payload` (with optional compression preamble)
|
||||
5) `Signature` (64 bytes) if `HAS_SIGNATURE`
|
||||
|
||||
Unknown flags are ignored by older implementations (they will simply not see a route and continue broadcasting as before).
|
||||
|
||||
## Route Field Encoding
|
||||
|
||||
- Presence: Signaled by the `HAS_ROUTE (0x08)` bit in `flags`.
|
||||
- Layout (immediately after optional `RecipientID`):
|
||||
- `count`: 1 byte (0..255)
|
||||
- `hops`: concatenation of `count` peer IDs, each encoded as exactly 8 bytes
|
||||
- Peer ID encoding (8 bytes): same as used elsewhere in BitChat (16 hex chars → 8 bytes; left-to-right conversion; pad with `0x00` if shorter). This matches the on‑wire `senderID`/`recipientID` encoding.
|
||||
- Size impact: `1 + 8*N` bytes, where `N = count`.
|
||||
- Empty route: `HAS_ROUTE` with `count = 0` is treated as no route (relays ignore it).
|
||||
|
||||
## Sender Behavior
|
||||
|
||||
- Applicability: Intended for addressed packets (i.e., where `recipientID` is set and is not the broadcast ID). For broadcast packets, omit the route.
|
||||
- Path computation: Use Dijkstra’s shortest path (unit weights) on your internal mesh topology to find a route from `src` (your peerID) to `dst` (recipient peerID). The hop list SHOULD include the full path `[src, ..., dst]`.
|
||||
- Encoding: Set `HAS_ROUTE`, write `count = path.length`, then the 8‑byte hop IDs in order. Keep `count <= 255`.
|
||||
- Signing: The route is covered by the Ed25519 signature (recommended):
|
||||
- Signature input is the canonical encoding with `signature` omitted and `ttl = 0` (TTL excluded to allow relay decrement) — same rule as base protocol.
|
||||
|
||||
## Relay Behavior
|
||||
|
||||
When receiving a packet that is not addressed to you:
|
||||
|
||||
1) If `HAS_ROUTE` is not set, or the route is empty, relay using your normal broadcast logic (subject to TTL/probability policies).
|
||||
2) If `HAS_ROUTE` is set and your peer ID appears at index `i` in the hop list:
|
||||
- If there is a next hop at `i+1`, attempt a targeted unicast to that next hop if you have a direct connection to it.
|
||||
- If successful, do NOT broadcast this packet further.
|
||||
- If not directly connected (or the send fails), fall back to broadcast relaying.
|
||||
- If you are the last hop (no `i+1`), proceed with standard handling (e.g., if not addressed to you, do not relay further).
|
||||
|
||||
TTL handling remains unchanged: relays decrement TTL by 1 before forwarding (whether targeted or broadcast). If TTL reaches 0, do not relay.
|
||||
|
||||
## Receiver Behavior (Destination)
|
||||
|
||||
- This extension does not change how addressed packets are handled by the final recipient. If the packet is addressed to you (`recipientID == myPeerID`), process it normally (e.g., decrypt Noise payload, verify signatures, etc.).
|
||||
- Signature verification MUST include the route field when present; route tampering will invalidate the signature.
|
||||
|
||||
## Compatibility
|
||||
|
||||
- Omission: If `HAS_ROUTE` is omitted, legacy behavior applies. Relays that don’t implement this feature will ignore the route entirely, because they won’t set or check `HAS_ROUTE`.
|
||||
- Partial support: If any relay on the path cannot directly reach the next hop, it will fall back to broadcast relaying; delivery is still probabilistic like the base protocol.
|
||||
|
||||
## Minimal Example (conceptual)
|
||||
|
||||
- Header (fixed 13 bytes): unchanged.
|
||||
- Variable sections (ordered):
|
||||
- `SenderID(8)`
|
||||
- `RecipientID(8)` (if present)
|
||||
- `HAS_ROUTE` set → `count=3`, `hops = [H0 H1 H2]` where each `Hk` is 8 bytes
|
||||
- Payload (optionally compressed)
|
||||
- Signature (64)
|
||||
|
||||
Where `H0` is the sender’s peer ID, `H2` is the recipient’s peer ID, and `H1` is an intermediate relay. The receiver verifies the signature over the packet encoding (with `ttl = 0` and `signature` omitted), which includes the `hops` when `HAS_ROUTE` is set.
|
||||
|
||||
## Operational Notes
|
||||
|
||||
- Routing optimality depends on the freshness and completeness of the topology your implementation has learned (e.g., via gossip of direct neighbors). Recompute routes as needed.
|
||||
- Route length should be kept small to reduce overhead and the probability of missing a direct link at some hop.
|
||||
- Implementations may introduce policy controls (e.g., disable source routing, cap max route length).
|
||||
|
||||
Reference in New Issue
Block a user