pub struct PeerStats {Show 22 fields
pub peer_id: [u8; 20],
pub addr: SocketAddr,
pub uploaded_bytes: u64,
pub downloaded_bytes: u64,
pub upload_speed: f64,
pub download_speed: f64,
pub avg_upload_speed: u64,
pub avg_download_speed: u64,
pub am_choking: bool,
pub am_interested: bool,
pub peer_choking: bool,
pub peer_interested: bool,
pub is_snubbed: bool,
pub bad_data_count: u32,
pub snub_count: u32,
pub is_banned: bool,
pub ban_reason: Option<String>,
pub last_message_received_at: Instant,
pub last_data_time: Option<Instant>,
pub last_upload_time: Option<Instant>,
pub last_unchoke_at: Instant,
pub last_optimistic_unchoke_at: Instant,
/* private fields */
}Expand description
Per-peer statistics for BitTorrent choking algorithm decisions.
Tracks cumulative byte counts, real-time speeds via EMA, choke/interested states, timestamps for snubbed detection and unchoke rotation eligibility, and bad data detection for peer banning system.
Fields§
§peer_id: [u8; 20]20-byte peer identifier from the BitTorrent handshake.
addr: SocketAddrNetwork address of this peer.
uploaded_bytes: u64Total bytes uploaded to this peer (cumulative).
downloaded_bytes: u64Total bytes downloaded from this peer (cumulative).
upload_speed: f64Current upload speed estimate in bytes/second.
download_speed: f64Current download speed estimate in bytes/second.
avg_upload_speed: u64Average upload speed over the entire connection (bytes/sec).
avg_download_speed: u64Average download speed over the entire connection (bytes/sec).
am_choking: boolWhether we are choking this peer.
Starts as true (we choke all peers by default).
am_interested: boolWhether we are interested in data from this peer.
peer_choking: boolWhether this peer is choking us.
peer_interested: boolWhether this peer is interested in data from us.
is_snubbed: boolWhether this peer has been marked as snubbed (not sending data).
bad_data_count: u32Number of times this peer sent invalid piece data (hash verification failed).
When this reaches BAD_DATA_THRESHOLD, the peer is permanently banned.
snub_count: u32Number of times this peer has been marked as snubbed.
is_banned: boolWhether this peer has been banned for sending too much invalid data.
Banned peers are disconnected, excluded from selection, and not reconnected for the remainder of the session.
ban_reason: Option<String>Reason why this peer was banned (if is_banned == true).
last_message_received_at: InstantInstant of the most recent message received from this peer.
last_data_time: Option<Instant>Instant of the most recent data received FROM this peer.
last_upload_time: Option<Instant>Instant of the most recent data sent TO this peer.
last_unchoke_at: InstantInstant when we last unchoked this peer (for rotation round-robin).
last_optimistic_unchoke_at: InstantInstant when we last optimistically unchoked this peer.
Implementations§
Source§impl PeerStats
impl PeerStats
Sourcepub fn new(peer_id: [u8; 20], addr: SocketAddr) -> Self
pub fn new(peer_id: [u8; 20], addr: SocketAddr) -> Self
Create a new PeerStats for the given peer.
§Default state
- Byte counters start at 0.
- Speeds start at 0.0.
am_choking = true(we choke by default).- All other boolean flags are
false. - All timestamps are set to
Instant::now(). - Bad data count starts at 0.
§Example
use std::net::SocketAddr;
let addr: SocketAddr = "192.168.1.5:6881".parse().unwrap();
let stats = PeerStats::new([0u8; 20], addr);
assert!(stats.am_choking);
assert_eq!(stats.uploaded_bytes, 0);
assert!(!stats.is_banned);Sourcepub fn on_data_sent(&mut self, bytes: u64)
pub fn on_data_sent(&mut self, bytes: u64)
Record that we sent bytes to this peer.
Increments uploaded_bytes and updates
upload_speed using an Exponential Moving Average:
new_speed = alpha * instant_rate + (1 - alpha) * old_speedwhere alpha = 0.5. On the first call the raw instant rate is used directly.
Also updates last_upload_time.
Sourcepub fn on_data_received(&mut self, bytes: u64)
pub fn on_data_received(&mut self, bytes: u64)
Record that we received bytes from this peer.
Increments downloaded_bytes,
resets is_snubbed to false,
updates last_message_received_at,
updates last_data_time,
and refreshes download_speed via EMA.
Sourcepub fn check_snubbed(&mut self, timeout_secs: u64) -> bool
pub fn check_snubbed(&mut self, timeout_secs: u64) -> bool
Check whether this peer should be marked as snubbed due to inactivity.
Returns true if the peer has just transitioned into the snubbed state
(i.e., no data for at least timeout_secs seconds and was not already snubbed).
Returns false if the peer is still active or was already snubbed.
Also increments snub_count when transitioning to snubbed state.
Sourcepub fn reset_snubbed(&mut self)
pub fn reset_snubbed(&mut self)
Explicitly reset the snubbed flag (e.g. after an unchoke).
Sourcepub fn record_unchoke(&mut self)
pub fn record_unchoke(&mut self)
Record that we have unchoked this peer.
Sets am_choking to false and refreshes
last_unchoke_at.
Sourcepub fn record_choke(&mut self)
pub fn record_choke(&mut self)
Record that we have choked this peer.
Sets am_choking to true.
Sourcepub fn record_optimistic_unchoke(&mut self)
pub fn record_optimistic_unchoke(&mut self)
Record that we performed an optimistic unchoke on this peer.
Sets am_choking to false and refreshes
last_optimistic_unchoke_at.
Sourcepub fn time_since_last_unchoke(&self) -> Duration
pub fn time_since_last_unchoke(&self) -> Duration
Elapsed time since we last unchoked this peer (regular unchoke).
Used by the choking algorithm to determine rotation eligibility (peers that have been unchoked longest are candidates for choking).
Sourcepub fn time_since_last_optimistic_unchoke(&self) -> Duration
pub fn time_since_last_optimistic_unchoke(&self) -> Duration
Elapsed time since we last optimistically unchoked this peer.
Used to avoid re-selecting the same peer for optimistic unchoke too frequently.
Sourcepub fn connection_duration_secs(&self) -> u64
pub fn connection_duration_secs(&self) -> u64
Get the total duration of this peer connection in seconds.
Returns the number of seconds since this peer was first connected.
Sourcepub fn increment_bad_data(&mut self) -> bool
pub fn increment_bad_data(&mut self) -> bool
Increment the bad data counter for this peer.
Called when a piece received from this peer fails hash verification.
§Returns
trueif the peer should now be banned (count >=BAD_DATA_THRESHOLD)falseif the peer is still under the threshold
Sourcepub fn decrement_bad_data(&mut self)
pub fn decrement_bad_data(&mut self)
Decrement the bad data counter for this peer (gradual recovery).
Called when a valid, verified piece is successfully received from this peer. This allows peers who occasionally send bad data to recover their reputation. The count is floored at 0 (never goes negative).
Sourcepub fn is_eligible_for_selection(&self) -> bool
pub fn is_eligible_for_selection(&self) -> bool
Check if this peer is eligible for selection in algorithms.
Returns false if the peer is banned, regardless of other metrics.
This should be called before including a peer in any selection logic.