pub struct BwWeightedGenerator { /* private fields */ }Expand description
Bandwidth-weighted node generator.
Implements bandwidth-weighted random selection of relay nodes. Selection probability is proportional to each relay’s bandwidth weight.
§Weight Calculation
The weight for each relay is calculated as:
weight = measured_bandwidth × flag_weight_multiplierWhere flag_weight_multiplier depends on the relay’s flags and position:
| Flags | Middle Position | Guard Position | Exit Position |
|---|---|---|---|
| Neither Guard nor Exit | Wmm | Wgm | Wem |
| Guard only | Wmg | Wgg | Weg |
| Exit only | Wme | Wge | Wee |
| Guard + Exit | Wmd | Wgd | Wed |
§Selection Algorithm
- Filter routers through all restrictions
- Calculate weighted bandwidth for each remaining router
- Build cumulative weight distribution
- Generate random value in [0, total_weight)
- Select router where cumulative weight exceeds random value
§Example
use vanguards_rs::node_selection::{BwWeightedGenerator, FlagsRestriction, NodeRestrictionList, Position};
let restriction = FlagsRestriction::new(
vec!["Fast".to_string(), "Stable".to_string(), "Valid".to_string()],
vec!["Authority".to_string()],
);
let restrictions = NodeRestrictionList::new(vec![Box::new(restriction)]);
let generator = BwWeightedGenerator::new(routers, restrictions, weights, Position::Middle)?;
let selected = generator.generate()?;
println!("Selected relay: {}", selected.fingerprint);§See Also
Position- Circuit position affecting weight calculationNodeRestrictionList- Filtering criteriacrate::error::Error::NoNodesRemain- Error when no nodes pass filters
Implementations§
Source§impl BwWeightedGenerator
impl BwWeightedGenerator
Sourcepub fn new(
sorted_routers: Vec<RouterStatusEntry>,
restrictions: NodeRestrictionList,
bw_weights: HashMap<String, i64>,
position: Position,
) -> Result<Self>
pub fn new( sorted_routers: Vec<RouterStatusEntry>, restrictions: NodeRestrictionList, bw_weights: HashMap<String, i64>, position: Position, ) -> Result<Self>
Creates a new bandwidth-weighted generator.
§Arguments
sorted_routers- Routers sorted by measured bandwidth (descending)restrictions- Restrictions to filter routersbw_weights- Consensus bandwidth weights (Wmm, Wmg, Wme, Wmd, etc.)position- Circuit position for weight calculation
§Errors
Returns Error::NoNodesRemain if all routers are filtered out.
§Example
let generator = BwWeightedGenerator::new(routers, restrictions, weights, Position::Middle)?;Sourcepub fn repair_exits(&mut self)
pub fn repair_exits(&mut self)
Repairs exit node weights for rendezvous point selection.
Exit nodes got their weights set based on middle position, but they can
still be used as rendezvous points in cannibalized circuits. This method
recalculates their weights using exit position weights and tracks a
separate exit_total.
Note: We deliberately don’t re-normalize weight_total since we don’t
want to lower the upper bound of other nodes. But we do want a separate
exit_total for use with Exit nodes.
Sourcepub fn generate(&self) -> Result<&RouterStatusEntry>
pub fn generate(&self) -> Result<&RouterStatusEntry>
Generates a randomly selected router using bandwidth-weighted selection.
Selection probability is proportional to each router’s bandwidth weight.
§Returns
A reference to the selected router.
§Errors
Returns Error::NoNodesRemain if the router list is empty or total weight is zero.
Sourcepub fn weight_total(&self) -> f64
pub fn weight_total(&self) -> f64
Returns the total weight of all routers.
Sourcepub fn exit_total(&self) -> f64
pub fn exit_total(&self) -> f64
Returns the total weight of exit-flagged routers.
Sourcepub fn router_count(&self) -> usize
pub fn router_count(&self) -> usize
Returns the number of routers after restrictions.
Sourcepub fn node_weights(&self) -> &[f64]
pub fn node_weights(&self) -> &[f64]
Returns a reference to the node weights.