node/peering: add the sans-IO peering reconciler core (unwired)

Introduce PeeringReconciler, the synchronous decision core for peer
desired-state, with its input/action vocabulary (Gate, Budget, Observed,
Candidate, DiscoveryPools, Policy, PeeringAction) and the Peering owner
struct. reconcile() computes connect/retry intents across four layers:
the auto-connect mandatory floor, the ceiling-only overlay enqueue, the
opportunistic transport-neighbor growth, and the node.limits ceiling
enforced inline. It mirrors the supervisor sans-IO shape: no I/O, no
clock reads (time enters as a parameter), no runtime handles.

The core owns its own cross-attempt retry schedule so escalating backoff
survives the fresh connection created per re-dial. Gate-guarded reflexes
(on_handshake_timeout / on_link_dead) reproduce the current backoff math
and no-op while draining. Overlay is strictly ceiling-only (no peer-count
set-point). Disconnect is defined but never emitted (no shedding).

Unwired here: the driver still runs the imperative peering methods and
Node holds the live retry map. 11 unit tests drive the pure core with
synthetic inputs. No behavior change.
This commit is contained in:
Johnathan Corgan
2026-07-13 04:10:36 +00:00
parent b676c9d83a
commit 5d08d27d3c
2 changed files with 1293 additions and 0 deletions
+3
View File
@@ -10,3 +10,6 @@
//! persist in the reconciler, not per-connection. //! persist in the reconciler, not per-connection.
pub(in crate::node) mod retry; pub(in crate::node) mod retry;
#[allow(dead_code)] // Wired by the driver cutover in the following commits; unused until then.
pub(in crate::node) mod reconcile;
File diff suppressed because it is too large Load Diff