Skip to main content

hopr_transport_path/
traits.rs

1use hopr_types::crypto::types::OffchainPublicKey;
2
3use crate::errors::Result;
4
5/// A candidate path paired with its accumulated traversal cost.
6///
7/// The cost is a multiplicative product of per-edge quality scores in
8/// `(0.0, 1.0]` — higher means better quality.
9#[derive(Debug, Clone)]
10pub struct PathWithCost {
11    /// The path nodes (excluding source): `[intermediates..., dest]`.
12    pub path: Vec<OffchainPublicKey>,
13    /// Accumulated traversal cost.
14    pub cost: f64,
15}
16
17/// Selects multi-hop paths through the network.
18///
19/// Implementors are responsible for determining how paths are found.
20/// The caller (e.g. [`crate::planner::PathPlanner`]) is responsible for caching,
21/// path selection strategy, and validation.
22///
23/// # Cycle-free invariant
24///
25/// Implementations **must** return only cycle-free (simple) paths — no node may
26/// appear more than once in any returned path.  Cycles destroy path entropy and
27/// worsen anonymity.  The built-in [`crate::selector::HoprGraphPathSelector`]
28/// guarantees this by using the `simple_paths` graph algorithm, which by
29/// definition never revisits a node.  Alternative implementations must uphold
30/// the same invariant.
31pub trait PathSelector {
32    /// Return **all** candidate paths from `src` to `dest` using `hops` relays.
33    ///
34    /// Each returned [`PathWithCost`] contains a path `Vec<OffchainPublicKey>`
35    /// of length `hops + 1` (`[intermediates..., dest]`; `src` excluded) paired
36    /// with its accumulated traversal cost.
37    ///
38    /// Every returned path must be cycle-free (see trait-level docs).
39    ///
40    /// Returns `Err` when no paths can be found.
41    fn select_path(&self, src: OffchainPublicKey, dest: OffchainPublicKey, hops: usize) -> Result<Vec<PathWithCost>>;
42}
43
44/// A selector that can run a background path-cache refresh loop.
45///
46/// Implementors pre-warm their internal caches on a periodic schedule,
47/// so that steady-state traffic is always served without a blocking query.
48///
49/// The returned future is `'static` because it is intended to be
50/// spawned as a long-lived background task.
51pub trait BackgroundPathCacheRefreshable: Send + Sync {
52    /// Returns a future that runs the periodic cache-refresh loop.
53    ///
54    /// The future never completes under normal operation.
55    fn run_background_refresh(&self) -> impl std::future::Future<Output = ()> + Send + 'static;
56}