feat(bootstrap): dial always-on bootstrap peers so a fresh node has a dialable peer - #245
Draft
MichaelTaylor3d wants to merge 3 commits into
Draft
feat(bootstrap): dial always-on bootstrap peers so a fresh node has a dialable peer#245MichaelTaylor3d wants to merge 3 commits into
MichaelTaylor3d wants to merge 3 commits into
Conversation
… dialable peer A freshly-installed node knows no peers. Peer exchange spreads only the peers a link's far end knows, the DHT routes queries through peers already in the table, and a relay reservation makes the node reachable without ever populating an address book. So a node on a machine that has never run one has nothing to dial and reports connected_peers = 0 for as long as it runs. Adds the bootstrap seam: resolve the anchor set, then dial each over the full NAT traversal ladder and adopt the verified connection into the pool. Dials are spawned so bring-up never blocks on an anchor that may be unreachable. An anchor is dialed only when its peer_id is known. The node<->node interface pins the peer's certificate SPKI against an expected identity, so an entry with no identity is skipped rather than dialed unpinned -- an unpinned dial would accept whatever identity answered at the address. The compiled-in set is empty for now and DIG_BOOTSTRAP_PEERS names the anchors: the canonical set lives in dig-constants 0.11.0, which this workspace cannot adopt until the chia 0.36 migration, per the dig-constants pin's own rationale. Refs: DIG-Network/dig_ecosystem#923 Co-Authored-By: Claude <noreply@anthropic.com>
Without a hook the built .debs sit on the GitHub release while the apt repository keeps serving the previous version until someone runs its deploy by hand. repository_dispatch deliberately, not `on: release:` in apt.dig.net: a release run sets github.ref to the TAG, so every job guarded on refs/heads/main skips while the run still reports completed -- nothing red, nothing ran. The job is INERT until apt.dig.net adds the matching listener; the dispatches API returns 204 whether or not anything is listening, so this is documented in place rather than left to look like a working hook. Refs: DIG-Network/dig_ecosystem#425 Co-Authored-By: Claude <noreply@anthropic.com>
Reverting validated_peer_id to Some(_) left the skip test green: its only unidentified fixture had no `@`, so it never reached identity validation and was blind to that validation being deleted outright. Adds the `@`-present-but-empty case, which fails on the revert as it should. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
DO NOT MERGE — gate round not yet run.
Closes nothing on its own; refs https://github.com/DIG-Network/dig_ecosystem/issues/923.
What changed
Adds the bootstrap seam (
crates/dig-node-core/src/seams/dig_peer/bootstrap.rs) and wires it intopeer-network bring-up: resolve the anchor set, dial each over the full NAT traversal ladder, adopt
each verified connection into the connected-peer pool.
A freshly-installed node knows no peers. Peer exchange spreads only the peers a link's far end
knows, the DHT routes queries through peers already in the table, and a relay reservation makes the
node reachable without ever populating an address book. So a node on a machine that has never run
one has nothing to dial and reports
connected_peers = 0indefinitely.Two findings that shaped the design
GossipHandle::connect_via_natpins the peer's certificateSPKI against an EXPECTED
peer_id, and dig-node's existing PEX dial loop (pex.rs:613) alreadycontinues on any candidate lacking one. So a bootstrap entry needs an identity, not just anauthority. An entry without one is SKIPPED rather than dialed unpinned — an unpinned dial would
accept whatever identity answered at that address.
(feat(bootstrap): canonical DIG_BOOTSTRAP_PEERS so a fresh node has a dialable peer dig-constants#13), but this workspace pins dig-constants to
0.9: 0.10 moved tochia-protocol 0.36 while everything here builds against 0.26, and linking both stops
Bytes32unifying across the workspace. That is the pin's own documented rationale
(
crates/dig-node-core/Cargo.toml:227), and I verified it empirically — bumping to 0.11 producesE0308 ... multiple different versions of crate chia_protocol. Socompiled_in_targets()isexplicitly empty and documented as such, and
DIG_BOOTSTRAP_PEERSis the supported way to namean anchor until the chia 0.36 migration lands.
Neither of these is a shortcut: the anchor's own
peer_idis not known yet either (see the report),so the canonical entry would be skipped as unpinned regardless. The dial mechanism is complete and
exercised end-to-end through the env path.
Blast radius
impactwas unavailable for this worktree (see report); radius established by grep + direct readand stated honestly.
bootstrap.rsis a new module with no existing callers.run_peer_network(peer.rs), plus apub modand a re-export line. No existing function signature, type, or test was modified.run_peer_networkis the peer-network bring-up entry point, so it is high-traffic — which is whythe added call is a spawn that cannot fail bring-up and returns early when the target set is
empty (the current default). With no anchors configured the behaviour is byte-identical to before
apart from one INFO log.
How verified (locally — dig-node's
Test + coveragecheck is known false-green, #2513)cargo test -p dig-node-core --lib— 854 passed, 0 failed.cargo clippy -p dig-node-core --all-targets -- -D warnings— clean, exit 0.cargo fmt --check— clean.Test design notes
Fixtures were built to distinguish the property from the nearest wrong implementation, not merely to
assert an outcome:
env_list_parses_every_entryuses two entries — one cannot tell "parses the list" from"parses the first element".
a_malformed_entry_is_dropped_without_discarding_the_listpairs each bad entry with a goodneighbour — a list of only-bad entries yields empty either way and cannot tell "drops the entry"
from "rejects the list".
a_blank_value_falls_back_rather_than_disablingcarries a populated control through the sameargument position, so it cannot pass merely because both arms are empty today.
compiled_targets_are_absent_for_now_and_pinned_whenever_presentasserts the current empty stateAND the pinning invariant, so it begins checking pinning rather than going vacuous the day the
canonical set is adopted.
authority_resolution_prefers_ipv6guards its assertion on the host actually offering bothfamilies, so it cannot pass vacuously on a single-family host.
Version
Workspace 0.126.0 → 0.127.0;
dig-node-core0.47.0 → 0.48.0 (minor: additive capability).Not in this PR
dig_ecosystem#1871 (
adopt_relayed_inboundnever called) is not fixed here — it is blocked on adig-gossip API gap, detailed in the lane report. Shipping the naive call would count the peer while
stopping its peer-RPC from being served, which is a regression, not a fix.