mirror of
https://github.com/jmcorgan/fips.git
synced 2026-08-12 09:33:23 +00:00
Implement cost-based parent selection with periodic re-evaluation
Cost-based parent selection: - Replace depth-only parent selection with effective_depth = depth + link_cost - link_cost computed from locally measured MMP metrics: etx * (1.0 + srtt_ms / 100.0) - Prevents bottleneck subtrees in heterogeneous networks where a LoRa link at depth 1 would otherwise always beat fiber at depth 2 - Configurable hysteresis (default 0.2) prevents marginal parent switches - Configurable hold-down timer (default 30s) suppresses re-evaluation after parent switch - Mandatory switches (parent lost, root change) bypass both safeguards - Link costs passed as HashMap parameter to keep TreeState pure Periodic re-evaluation: - evaluate_parent() was only called on TreeAnnounce receipt or parent loss; after tree stabilization, link degradation went undetected - Added timer-based re-evaluation (reeval_interval_secs, default 60s) that calls evaluate_parent() from the tick handler with current MMP link costs - Respects existing hold-down and hysteresis safeguards - Short-circuits when disabled or <2 peers Design documentation: - Update 7 design docs to reflect cost-based parent selection - Replace depth-only algorithm descriptions with effective_depth model - Replace rejected cumulative path cost spec with local-only design rationale - Rewrite Example 2 (heterogeneous links) for local-only cost model - Update config docs: parent_switch_threshold replaced by parent_hysteresis, hold_down_secs, reeval_interval_secs Chaos simulation enhancements: - fips_overrides with deep merge for per-scenario FIPS config customization - Explicit topology algorithm for deterministic test graphs - Control socket querying via fipsctl for tree/MMP snapshot collection - Edge existence validation in netem manager - Per-link netem policy overrides - 9 new chaos scenarios covering cost avoidance, depth-vs-cost tradeoffs, stability, mixed topologies, periodic re-evaluation, and bottleneck parent 12 new unit tests, 667 total passing, clippy clean.
This commit is contained in:
+10
-2
@@ -337,6 +337,10 @@ pub struct Node {
|
||||
/// are exhausted.
|
||||
retry_pending: HashMap<NodeAddr, retry::RetryState>,
|
||||
|
||||
// === Periodic Parent Re-evaluation ===
|
||||
/// Timestamp of last periodic parent re-evaluation (for pacing).
|
||||
last_parent_reeval: Option<std::time::Instant>,
|
||||
|
||||
// === Display Names ===
|
||||
/// Human-readable names for configured peers (alias or short npub).
|
||||
/// Populated at startup from peer config.
|
||||
@@ -368,7 +372,8 @@ impl Node {
|
||||
|
||||
// Initialize tree state with signed self-declaration
|
||||
let mut tree_state = TreeState::new(node_addr);
|
||||
tree_state.set_parent_switch_threshold(config.node.tree.parent_switch_threshold);
|
||||
tree_state.set_parent_hysteresis(config.node.tree.parent_hysteresis);
|
||||
tree_state.set_hold_down(config.node.tree.hold_down_secs);
|
||||
tree_state
|
||||
.sign_declaration(&identity)
|
||||
.expect("signing own declaration should never fail");
|
||||
@@ -432,6 +437,7 @@ impl Node {
|
||||
std::time::Duration::from_millis(coords_response_interval_ms),
|
||||
),
|
||||
retry_pending: HashMap::new(),
|
||||
last_parent_reeval: None,
|
||||
peer_aliases: HashMap::new(),
|
||||
})
|
||||
}
|
||||
@@ -451,7 +457,8 @@ impl Node {
|
||||
|
||||
// Initialize tree state with signed self-declaration
|
||||
let mut tree_state = TreeState::new(node_addr);
|
||||
tree_state.set_parent_switch_threshold(config.node.tree.parent_switch_threshold);
|
||||
tree_state.set_parent_hysteresis(config.node.tree.parent_hysteresis);
|
||||
tree_state.set_hold_down(config.node.tree.hold_down_secs);
|
||||
tree_state
|
||||
.sign_declaration(&identity)
|
||||
.expect("signing own declaration should never fail");
|
||||
@@ -518,6 +525,7 @@ impl Node {
|
||||
std::time::Duration::from_millis(coords_response_interval_ms),
|
||||
),
|
||||
retry_pending: HashMap::new(),
|
||||
last_parent_reeval: None,
|
||||
peer_aliases: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user