Skip to main content

jacquard_batman/
lib.rs

1//! Proactive BATMAN-style next-hop routing engine.
2//!
3//! Ownership:
4//! - router owns canonical route publication, handles, leases, and route truth
5//! - BATMAN owns proactive originator observations, neighbor ranking, and
6//!   best-next-hop state
7//! - route visibility is `NextHopOnly`; the engine does not pretend to expose a
8//!   full explicit path
9//!
10//! This crate implements a proactive next-hop routing model over Jacquard's
11//! shared world observations. It starts from an OGM-equivalent baseline for
12//! route quality and optionally refines ranking with richer shared link
13//! observations when they are present.
14
15#![forbid(unsafe_code)]
16
17mod gossip;
18mod planner;
19mod private_state;
20mod public_state;
21mod runtime;
22mod scoring;
23
24use std::collections::BTreeMap;
25
26use gossip::LearnedAdvertisement;
27use jacquard_core::{
28    Configuration, ConnectivityPosture, NodeId, Observation, RouteId, RoutePartitionClass,
29    RouteProtectionClass, RouteRepairClass, RouteShapeVisibility, RoutingEngineCapabilities,
30    RoutingEngineId,
31};
32use public_state::{
33    ActiveBatmanRoute, BestNextHop, DecayWindow, NeighborRanking, OriginatorObservationTable,
34};
35
36pub const BATMAN_ENGINE_ID: RoutingEngineId =
37    RoutingEngineId::from_contract_bytes(*b"jacquard.batman.");
38
39pub const BATMAN_CAPABILITIES: RoutingEngineCapabilities = RoutingEngineCapabilities {
40    engine: BATMAN_ENGINE_ID,
41    max_protection: RouteProtectionClass::LinkProtected,
42    max_connectivity: ConnectivityPosture {
43        repair: RouteRepairClass::Repairable,
44        partition: RoutePartitionClass::ConnectedOnly,
45    },
46    repair_support: jacquard_core::RepairSupport::Unsupported,
47    hold_support: jacquard_core::HoldSupport::Unsupported,
48    decidable_admission: jacquard_core::DecidableSupport::Supported,
49    quantitative_bounds: jacquard_core::QuantitativeBoundSupport::ProductiveOnly,
50    reconfiguration_support: jacquard_core::ReconfigurationSupport::ReplaceOnly,
51    route_shape_visibility: RouteShapeVisibility::NextHopOnly,
52};
53
54pub struct BatmanEngine<Transport, Effects> {
55    local_node_id: NodeId,
56    transport: Transport,
57    effects: Effects,
58    latest_topology: Option<Observation<Configuration>>,
59    decay_window: DecayWindow,
60    learned_advertisements: BTreeMap<NodeId, LearnedAdvertisement>,
61    originator_observations: OriginatorObservationTable,
62    neighbor_rankings: BTreeMap<NodeId, NeighborRanking>,
63    best_next_hops: BTreeMap<NodeId, BestNextHop>,
64    active_routes: BTreeMap<RouteId, ActiveBatmanRoute>,
65}
66
67impl<Transport, Effects> BatmanEngine<Transport, Effects> {
68    #[must_use]
69    pub fn new(local_node_id: NodeId, transport: Transport, effects: Effects) -> Self {
70        Self::with_decay_window(local_node_id, transport, effects, DecayWindow::default())
71    }
72
73    #[must_use]
74    pub(crate) fn with_decay_window(
75        local_node_id: NodeId,
76        transport: Transport,
77        effects: Effects,
78        decay_window: DecayWindow,
79    ) -> Self {
80        Self {
81            local_node_id,
82            transport,
83            effects,
84            latest_topology: None,
85            decay_window,
86            learned_advertisements: BTreeMap::new(),
87            originator_observations: BTreeMap::new(),
88            neighbor_rankings: BTreeMap::new(),
89            best_next_hops: BTreeMap::new(),
90            active_routes: BTreeMap::new(),
91        }
92    }
93}