Skip to main content

ChokingAlgorithm

Struct ChokingAlgorithm 

Source
pub struct ChokingAlgorithm { /* private fields */ }
Expand description

BitTorrent choking algorithm implementation (tit-for-tat strategy)

This implements the standard BT choking algorithm:

  • Top K peers by score get unchoked (reciprocity-based)
  • One additional slot for optimistic unchoke (random selection)
  • Snubbed peers are penalized heavily

The algorithm minimizes churn by only changing state when necessary.

Implementations§

Source§

impl ChokingAlgorithm

Source

pub fn new(config: ChokingConfig) -> Self

Create a new choking algorithm with the given configuration

Source

pub fn add_peer(&mut self, stats: PeerStats)

Add a peer to be managed by the algorithm

Source

pub fn remove_peer(&mut self, idx: usize)

Remove a peer at the given index

Source

pub fn len(&self) -> usize

Returns the number of peers being managed

Source

pub fn is_empty(&self) -> bool

Returns true if there are no peers

Source

pub fn rotate_choke(&mut self) -> Vec<ChokeAction>

Core algorithm: called every ~10 seconds (config.choke_rotation_interval_secs)

This performs the tit-for-tat choke rotation:

  1. Check and mark snubbed peers (timeout-based)
  2. Calculate score for each peer
  3. Sort by score descending
  4. Top K get Unchoke, rest get Choke BUT: keep currently unchoked peers unchoked if they’re still in top K (avoid churn - only change what’s necessary)
  5. Return only the actions that changed state
Source

pub fn optimistically_unchoke(&mut self) -> Option<usize>

Called every ~30 seconds (config.optimistic_unchoke_interval_secs)

Selects ONE choked+interested peer for optimistic unchoke. This gives new/unknown peers a chance to prove themselves.

Uses round-robin rotation among eligible non-snubbed peers to ensure fair distribution of the optimistic unchoke slot.

Returns Some(index) if found, None if no eligible peer

Source

pub fn rotate_optimistic_unchoked(&mut self, eligible_peers: &[usize]) -> usize

Rotate which peer gets the optimistic unchoke slot using round-robin.

Picks a different peer than the current one when possible, cycling through eligible peers in order.

§Arguments
  • eligible_peers - Indices of peers that are eligible for optimistic unchoke
§Returns

The index of the selected peer from the eligible set

Source

pub fn on_data_received(&mut self, peer_idx: usize, bytes: u64)

Called whenever we receive data from a peer. Automatically unsnubs the peer if it was in the explicit snubbed set.

Source

pub fn mark_peer_snubbed(&mut self, peer_id: usize)

Explicitly mark a peer as snubbed (algorithm-level).

This adds the peer to the snubbed_peers set, which causes calculate_peer_score to return -1000 for this peer, ensuring they always get choked on the next rotation.

Source

pub fn unsnub_peer(&mut self, peer_id: usize) -> bool

Remove a peer from the explicit snubbed set (they sent data again).

Returns true if the peer was actually in the snubbed set (newly un-snubbed), false if they were not snubbed.

Source

pub fn is_explicitly_snubbed(&self, peer_id: usize) -> bool

Check if a peer is in the explicit snubbed set.

Source

pub fn snubbed_count(&self) -> usize

Get the number of explicitly snubbed peers.

Source

pub fn check_snubbed_peers(&mut self) -> Vec<usize>

Check all peers for snubbed status Returns indices of newly snubbed peers

Source

pub fn get_peer_mut(&mut self, idx: usize) -> Option<&mut PeerStats>

Get mutable reference to peer stats

Source

pub fn get_peer(&self, idx: usize) -> Option<&PeerStats>

Get reference to peer stats

Source

pub fn peers(&self) -> &[PeerStats]

Get all peers as a slice

Source

pub fn config(&self) -> &ChokingConfig

Get reference to configuration

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more