Added: Tier 1 audit Peer-sync flow Deterministic vectors Regenerator Verifier Corrected §5.8 regarding: Directional peering-key identity ordering. Public versus control destination handlers. Permissive announce parser behavior. Autopeer rules. Peer Resource framing and admission. PN_STAMP_THROTTLE = 180 seconds. Two documented LXMF 0.9.7 hazards. Verification: deterministic regeneration passed; full pinned suite passed 20/20; git diff --check passed. No commit created.
94 lines
3.4 KiB
Markdown
94 lines
3.4 KiB
Markdown
# Flow: propagation-node discovery and peer synchronization
|
|
|
|
How two LXMF propagation nodes discover each other, authenticate a sync offer,
|
|
and transfer stored messages. Pinned against **RNS 1.2.4 / LXMF 0.9.7**;
|
|
cross-references [`../SPEC.md`](../SPEC.md) §5.8, §10, and §11.
|
|
|
|
## Sequence
|
|
|
|
### 1. Node announces `lxmf.propagation`
|
|
|
|
The producer emits the seven-element §5.8.5 app_data array containing its
|
|
timebase, enabled state, transfer/sync limits, stamp costs, peering cost, and
|
|
metadata.
|
|
|
|
### 2. Receiving node evaluates autopeering
|
|
|
|
`LXMFPropagationAnnounceHandler` validates app_data. A direct announce creates
|
|
or updates an autopeer only when the node is enabled, autopeering is enabled,
|
|
and the path is within `autopeer_maxdepth` (default 4). Ordinary path responses
|
|
do not create autopeers. An enabled=false direct announce removes an autopeer.
|
|
|
|
### 3. Initiator prepares a directional peering key
|
|
|
|
The offering node computes a proof-of-work key over:
|
|
|
|
```text
|
|
receiving_identity_hash || offering_identity_hash
|
|
```
|
|
|
|
using the receiving node's announced peering cost. The key is cached and can
|
|
be reused until the peer raises its cost.
|
|
|
|
### 4. Initiator selects messages and opens a Link
|
|
|
|
The peer state machine sorts unhandled entries by ascending weight:
|
|
`priority_weight * age_weight * stored_size`. It applies the peer's per-message
|
|
and per-sync limits, opens a Link to `lxmf.propagation`, and identifies with
|
|
its propagation-node identity.
|
|
|
|
LXMF 0.9.7 has a sender-side low-stamp prefilter defect: it uses
|
|
`min(0, required_cost - flexibility)`. Receivers use the correct `max(0, ...)`
|
|
threshold, so low-value messages can be offered and then rejected.
|
|
|
|
### 5. Initiator sends `/offer`
|
|
|
|
The generic §11 request data is:
|
|
|
|
```python
|
|
[peering_key, [transient_id_1, transient_id_2, ...]]
|
|
```
|
|
|
|
Each transient ID is the full 32-byte hash from §5.8. The receiver validates
|
|
the directional key and marks the Link as validated.
|
|
|
|
### 6. Receiver selects wanted IDs
|
|
|
|
The `/offer` response value is:
|
|
|
|
- `False`: receiver already has all offered messages.
|
|
- `True`: receiver wants all offered messages.
|
|
- `[wanted_id, ...]`: receiver wants only that subset.
|
|
|
|
### 7. Initiator transfers requested entries
|
|
|
|
Requested entries are read from the message store with their 32-byte
|
|
propagation stamps and sent as a Resource:
|
|
|
|
```python
|
|
msgpack.packb([time.time(), [stamped_entry_1, stamped_entry_2, ...]])
|
|
```
|
|
|
|
### 8. Receiver admits and stores the Resource
|
|
|
|
Multiple messages are accepted only when the Resource Link was validated by a
|
|
successful `/offer`. An unvalidated Link may submit one message, which supports
|
|
ordinary client submission. The receiver validates each propagation stamp,
|
|
stores valid opaque bodies, and tears down/throttles on invalid stamps.
|
|
|
|
### 9. Initiator marks sync state
|
|
|
|
After a successful Resource transfer, the initiator moves transferred IDs from
|
|
unhandled to handled state, updates counters, tears down the Link, and may
|
|
continue immediately under the persistent strategy.
|
|
|
|
## Source map
|
|
|
|
| Step | File | Function / line |
|
|
|---|---|---|
|
|
| 1 | `LXMF/LXMRouter.py` | `get_propagation_node_app_data`, line 306+ |
|
|
| 2 | `LXMF/Handlers.py` | `LXMFPropagationAnnounceHandler`, line 35+ |
|
|
| 3-5 | `LXMF/LXMPeer.py` | `generate_peering_key` / `sync`, line 242+ |
|
|
| 5-6 | `LXMF/LXMRouter.py` | `offer_request`, line 2145+ |
|
|
| 7, 9 | `LXMF/LXMPeer.py` | `offer_response` / `resource_concluded`, line 395+ |
|
|
| 8 | `LXMF/LXMRouter.py` | `propagation_resource_concluded`, line 2200+ |
|