node: give anonymous outbound legs a persistent control machine

The anonymous-discovery dial paths drove no control machine: the leg was
born bare in start_handshake and a throwaway machine appeared only at
msg2. Anonymous legs now birth a persistent identity-less machine
alongside the leg (new_outbound widened to Option<PeerIdentity>, backed
by the existing identity-less outbound connection state), and handle_msg2
crystallizes the learned identity onto it before stepping. The msg2
missing-machine arm becomes defensive recovery (debug-assert + insert,
matching the IK line), and the self-connect drop arm disposes the
machine it previously leaked — reachable from identified dials too,
since the handshake completion overwrites the expected identity without
comparing it to the dial-time expectation. The self-connect arm's
index/link/pending-entry leak is pre-existing and stays as-is.

With every leg now born with a machine, the leg-to-machine direction of
the debug coherence check switches on for this line. The add_connection
test seam seeds direction-faithful machines (an outbound-anonymous
seeded connection previously got an inbound-shaped one), and the
hand-rolled dial sites in tests seed dial machines mirroring
production. New tests pin the identity-less birth, the msg2 identity
crystallization through promote, and the self-connect disposal.
This commit is contained in:
Johnathan Corgan
2026-07-17 03:25:28 +00:00
parent d6785f2970
commit ba3c552dce
8 changed files with 330 additions and 72 deletions
+1 -1
View File
@@ -168,7 +168,7 @@ pub(super) async fn initiate_handshake(nodes: &mut [TestNode], i: usize, j: usiz
// crystallizes that same machine in place.
initiator.node.peer_machines.insert(
link_id,
crate::peer::machine::PeerMachine::new_outbound(link_id, peer_identity, 1000),
crate::peer::machine::PeerMachine::new_outbound(link_id, Some(peer_identity), 1000),
);
initiator
.node