From 0c7c253d30a34bfbdeafafd0726e05ec95dcab04 Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Wed, 7 Oct 2026 13:37:14 +0000 Subject: [PATCH] Mission item 12 status: the gate (three cases as they must), the unit tests, the verdict line for main Co-Authored-By: Claude Fable 5.1 --- docs/plans/mission-item-12-peer-directory.md | 41 +++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/docs/plans/mission-item-12-peer-directory.md b/docs/plans/mission-item-12-peer-directory.md index ae36b7ae..c4b77c04 100644 --- a/docs/plans/mission-item-12-peer-directory.md +++ b/docs/plans/mission-item-12-peer-directory.md @@ -19,7 +19,7 @@ makes the list useless: this lane reports, it does not decide. | fork `components/addressmanager/src/lib.rs` `add_address`, `iterate_prioritized_random_addresses` (weighted by failure count and prefix bucket) | the store a dialled address lives in | directory addresses enter it like seeder answers; the weight decides which enter, the store's own rule decides the order | | fork `consensus/core/src/config/params.rs` `consensus_digest` (a switch at never is outside the digest; set, it is in) | the activation pattern every 0.3.16 switch follows | `peer_directory_activation_daa`, never on every network | -## 2. Design, as built (prototype; fork branch peer-directory-node on release-0.3.20-node dc141409, commit 0cad5106; repo branch peer-directory on master 819d536b, commit 9a64d18c) +## 2. Design, as built (prototype; fork branch peer-directory-node on release-0.3.20-node dc141409, commits 0cad5106 and db28d331 (tests); repo branch peer-directory on master 819d536b, commits 9a64d18c and 3e0dfa17 (gate), pushed to origin) | Item | Rule | |---|---| @@ -64,6 +64,43 @@ key at 100 blocks), and the attacker holds a MAJORITY of a fresh node's peers in is the number that matters for a relay-level attack rather than a full eclipse; 16 peers takes that to 9 percent and the eclipse to zero in 1,000. +### Unit tests (box 2) + +| Test | Result | +|---|---| +| core `address_announce_round_trips_and_verifies_under_its_key_only` | 1 of 1 | +| node `the_peer_directory_lists_a_blocks_own_key_at_its_newest_address_only_when_switched_on` (known-failed first: the switch at never lists nothing) | 1 of 1 | +| `cargo check -p kaspad -p igneum-miner --features kaspad/igneum-pow` on the branch | ok | + +### The fast-time gate (box 2, `tools/fast-time-remote.sh --box 2`, binary of peer-directory-node 0cad5106, 13:27 to 13:34 UK) + +`infra/fast-time/peer-directory.mjs`: ten listing nodes at one CPU thread each, every miner announcing its node's loopback +p2p address, every node advertising an unroutable external ip (10.255.0.0/16) so ordinary address gossip hands a fresh node +dead addresses only; after 200 s a fresh node starts with `--outpeers=8` and one `--addpeer` to node 0 and is watched 180 s. + +| Case | Must | Got | Numbers | +|---|---|---|---| +| switch off, expect one (the known-failed case) | PASS | PASS | node 0 logged 0 listings; the fresh node held 1 outbound (node 0) for the whole watch, 0 draw lines, synced 448 blocks | +| switch off, expect eight (the harness's own failed shape) | FAIL | FAIL | 1 outbound, 0 from the directory | +| switch on, expect eight (THE GATE LINE) | PASS | PASS | node 0 logged 10 listings; the fresh node reached 8 outbound at 231.7 s (about 30 s after it started), 9 connections from the directory in one draw, synced 414 blocks | + +Three harness faults on the way, each fixed: the log directory missing on the box (every case died at the redirect); the +peer count read `isOutbound` where the fork's `RpcPeerInfo` is `is_outbound`; and the wrapper's first run checking the +worktree root out on the box (fixed on horizon, 10140f9f, carried here). + ## 5. Verdict line for main -(filled at the gate line: listed as useful, or dropped on the NAT fraction; the decision is main's and the project lead's) +The prototype does what invent.md 7.1 asked, on the numbers: a fresh node with one genesis peer and dead gossip reached 8 +outbound from the directory in about 30 s; the eclipse by a 34 percent attacker is 1.4e-4 to 2.2e-4 at 8 peers over 100,000 +starts (under the 0.1 percent line; 0 with 8 or fewer attacker keys, since the draw is without replacement), and the attacker +holds a majority of a fresh node's peers in about 11 percent of starts, which is the number to watch. The NAT reading (2 of 14 +standing nodes reachable, 86 percent behind NAT with no inbound path) makes the list a SEED SUPPLEMENT, not a replacement: +today it would list the two reachable fleet nodes beside the seeds, and a home miner's node (the 12-of-14 class unless the app +maps a port) is a reader of the list, never a listing. Per tier: a home miner's node gains weight-backed peers beside the seeds +at no cost and lists nothing by default; a rig or a pool node with a mapped port opts in with `--announce` and 171 bytes a block; +the phone and Ember verify mode are not wired (not done). Listed as useful or dropped is main's and the project lead's call; this lane's +reading is "keep as a seed supplement behind its switch", which costs 1.7 MB a day per node at 10,000 listing keys (approximate, +from the item size) and nothing while the switch is never. + +Open: an RPC that lists the directory; persistence across restarts; Ember and the phone; the testnet object and every network +file carry no `peer_directory` field (the switch stays never until a cut sets it).