Merge branch 'refactor-node' into refactor-node-next

Fold the handshake timer lifecycle (msg1 retransmit + timeout/stale
reap) through the per-peer machine, re-expressed onto the XX handshake
surface.

- Route peer-machine removal through remove_peer_machine so each link's
  timer store is dropped together with its machine (choke-point).
- Home the msg1-retransmit decision on the machine-armed retransmit
  timer; advance the resend counter only on send success and relocate
  the operator-visible resend count onto the machine.
- Reap outbound handshake timeouts via a presence-scan over the machine
  HandshakeTimeout timer, reading the threshold from config each tick so
  the reap stays neutral for any handshake_timeout_secs.

Cancel both dial-armed handshake timers on outbound promote so a
promoted machine carries no stale timer entry. Preserve the guard that
suppresses a msg1 resend at a peer already promoted via the inbound
cross-connection path.

The XX inbound HandshakeTimeout presence-scan is neutral only because
the inbound establish path sends msg2 inline and never dispatches the
inbound machine event, so no inbound leg ever populates a
HandshakeTimeout timer. A future change that drives inbound establish
through the machine must re-verify the reap equivalence for inbound
legs.
This commit is contained in:
Johnathan Corgan
2026-07-15 21:38:52 +00:00
11 changed files with 492 additions and 105 deletions
+4 -4
View File
@@ -607,7 +607,7 @@ impl Node {
self.links.remove(&link_id);
self.addr_to_link
.remove(&(transport_id, remote_addr.clone()));
self.peer_machines.remove(&link_id);
self.remove_peer_machine(link_id);
return Err(NodeError::IndexAllocationFailed(e.to_string()));
}
};
@@ -623,7 +623,7 @@ impl Node {
self.links.remove(&link_id);
self.addr_to_link
.remove(&(transport_id, remote_addr.clone()));
self.peer_machines.remove(&link_id);
self.remove_peer_machine(link_id);
return Err(NodeError::HandshakeFailed(e.to_string()));
}
};
@@ -1393,7 +1393,7 @@ impl Node {
);
// Clean up link and dial-time machine on handshake failure
self.remove_link(&pending.link_id);
self.peer_machines.remove(&pending.link_id);
self.remove_peer_machine(pending.link_id);
} else {
// Drive the dial-persisted machine: `Connecting` →
// `on_transport_connected` → `start_outbound_handshake`,
@@ -1460,7 +1460,7 @@ impl Node {
self.remove_link(&pending.link_id);
self.links.remove(&pending.link_id);
if let Some(id) = &pending.peer_identity {
self.peer_machines.remove(&pending.link_id);
self.remove_peer_machine(pending.link_id);
self.note_handshake_timeout(*id.node_addr(), Self::now_ms());
}
}