OverviewFilesCommitsIssuesDocsReleasesPeers

hyperswarm-peer commits / edc04b7

docs: we do not know which nodes hold our record — B's ping needs this first
Investigating B's liveness ping found its prerequisite, and it is a defect on its own. _store_announced_nodes (hyperdht.cpp:890) does not record the nodes that took our announce. It records the closest nodes in OUR OWN routing table and discards the token outright: KademliaNode nodes[20]; int n = _rpc->table().closest(topic, nodes, 20); memset(at.nodes[i].token, 0, 32); // Token not available here. JS records the actual committing node from the reply (announcer.js:265-267, `_serverRelays[2].set(msg.from...)`). Consequences across three open items: the liveness ping cannot be built on this, because pinging routing-table-closest nodes says nothing about whether the HOLDERS are alive; the stored tokens are zeros, so the unannounce path (A2) cannot use them either; and the three-generation cycling has nothing to cycle, since the generations ARE sets of committing nodes. The information is not available where it is needed: the per-node commit callback carries (target, token, node_id) and no address (dht_rpc.cpp:239, called at :1046). So the order is: widen that signature, record the true holder set, then the ping round, then re-announce when fewer than MIN_ACTIVE=3 answer. Not started. Recorded rather than begun — it is a four-part change across two files' public signatures, and half of it landing is worse than none. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
edc04b7e3819e590c22b89cc553a18f44eaa80a9
by plankatron <fleeky@gmail.com> · 2026-09-10T16:38:12.000Z

Changed files (1) +57 -0

docs/PARITY-hyperswarm.md +57 -0
……@@ -929,3 +929,60 @@ measures the NETWORK; letting it gate our build would be a category error.
929929**Why this belongs in a parity audit:** it is the only measurement here that
930930could have said "stop looking". Every other slice found something. This one
931931found that the thing I was about to chase was the DHT behaving normally.
932
933## 15. Slice 11 — ⛔ we do not know which nodes hold our record
934
935Investigating B's liveness ping (§12.1) turned up its prerequisite, and it is a
936defect in its own right.
937
938`_store_announced_nodes` (`hyperdht.cpp:890`) does NOT record the nodes that
939took our announce. It records the closest nodes in OUR OWN ROUTING TABLE, and
940it explicitly discards the token:
941
942 // Store the closest nodes from the routing table for later unannounce.
943 KademliaNode nodes[20];
944 int n = _rpc->table().closest(topic, nodes, 20);
945 ...
946 memset(at.nodes[i].token, 0, 32); // Token not available here.
947
948JS records the ACTUAL committing node, from the reply
949(`announcer.js:265-267`):
950
951 relays.push({ relayAddress: msg.from, peerAddress: msg.to })
952 this._serverRelays[2].set(msg.from.host + ':' + msg.from.port, msg.from)
953
954Three consequences, and they run through several open items:
955
9561. **The liveness ping cannot be built on this.** Pinging routing-table-closest
957 nodes says nothing about whether the nodes HOLDING the record are alive —
958 which is the entire question. JS pings `_serverRelays[2]`, the real holders.
9592. **The stored tokens are zeros**, so anything that needs a per-node token from
960 this table (the unannounce path once A2 is addressed) cannot use it.
9613. **The three-generation cycling (B remainder) has nothing to cycle.** The
962 generations ARE sets of committing nodes.
963
964⛔ **And the information is not currently available where it is needed.** The
965per-node commit callback is
966
967 std::function<std::vector<uint8_t>(const uint8_t *target,
968 const uint8_t *token,
969 const uint8_t *node_id)>
970
971— target, token, node id. **No address.** So recording the true holders means
972widening that signature in `dht_rpc` first (`dht_rpc.cpp:239`, called at
973`:1046`), then recording per announce, and only then can the ping round be
974written.
975
976### Revised plan for the rest of B
977
978 1. widen the commit callback to carry the responding node's ADDRESS
979 2. record the true holder set (address + token) per announced target
980 3. ping round on a 3s schedule with tag->response accounting
981 4. re-announce when answered < min(held, MIN_ACTIVE = 3)
982
983Steps 1-2 are also what A2 needs, and what the generation cycling would cycle.
984Doing them first makes three open items cheaper; doing the ping first is not
985possible.
986
987⚠ NOT STARTED. Recorded rather than begun because it is a four-part change
988across two files' public signatures, and half of it landing is worse than none.