Skip to content

Commit 59ee0b9

Browse files
committed
dev: torrent repository cleanups
1 parent 1381304 commit 59ee0b9

26 files changed

+259
-462
lines changed

cSpell.json

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
"ostr",
101101
"Pando",
102102
"peekable",
103+
"peerlist",
103104
"proot",
104105
"proto",
105106
"Quickstart",

packages/configuration/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ use torrust_tracker_primitives::{DatabaseDriver, TrackerMode};
246246
/// The maximum number of returned peers for a torrent.
247247
pub const TORRENT_PEERS_LIMIT: usize = 74;
248248

249-
#[derive(Copy, Clone, Debug, PartialEq, Default, Constructor)]
249+
#[derive(Copy, Clone, Debug, PartialEq, Constructor)]
250250
pub struct TrackerPolicy {
251251
pub remove_peerless_torrents: bool,
252252
pub max_peer_timeout: u32,

packages/primitives/src/announce_event.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
66

77
/// Announce events. Described on the
88
/// [BEP 3. The `BitTorrent` Protocol Specification](https://www.bittorrent.org/beps/bep_0003.html)
9-
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug, Serialize, Deserialize)]
9+
#[derive(Hash, Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
1010
pub enum AnnounceEvent {
1111
/// The peer has started downloading the torrent.
1212
Started,

packages/primitives/src/info_hash.rs

+19
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::hash::{DefaultHasher, Hash, Hasher};
12
use std::panic::Location;
23

34
use thiserror::Error;
@@ -77,6 +78,24 @@ impl std::convert::From<&[u8]> for InfoHash {
7778
}
7879
}
7980

81+
/// for testing
82+
impl std::convert::From<&DefaultHasher> for InfoHash {
83+
fn from(data: &DefaultHasher) -> InfoHash {
84+
let n = data.finish().to_le_bytes();
85+
InfoHash([
86+
n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[0], n[1], n[2],
87+
n[3],
88+
])
89+
}
90+
}
91+
92+
impl std::convert::From<&i32> for InfoHash {
93+
fn from(n: &i32) -> InfoHash {
94+
let n = n.to_le_bytes();
95+
InfoHash([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, n[0], n[1], n[2], n[3]])
96+
}
97+
}
98+
8099
impl std::convert::From<[u8; 20]> for InfoHash {
81100
fn from(val: [u8; 20]) -> Self {
82101
InfoHash(val)

packages/primitives/src/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! which is a `BitTorrent` tracker server. These structures are used not only
55
//! by the tracker server crate, but also by other crates in the Torrust
66
//! ecosystem.
7+
use std::collections::BTreeMap;
78
use std::time::Duration;
89

910
use info_hash::InfoHash;
@@ -38,7 +39,7 @@ pub enum IPVersion {
3839
}
3940

4041
/// Number of bytes downloaded, uploaded or pending to download (left) by the peer.
41-
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug, Serialize, Deserialize)]
42+
#[derive(Hash, Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
4243
pub struct NumberOfBytes(pub i64);
4344

4445
/// The database management system used by the tracker.
@@ -58,7 +59,7 @@ pub enum DatabaseDriver {
5859
MySQL,
5960
}
6061

61-
pub type PersistentTorrents = Vec<(InfoHash, u32)>;
62+
pub type PersistentTorrents = BTreeMap<InfoHash, u32>;
6263

6364
/// The mode the tracker will run in.
6465
///

packages/primitives/src/pagination.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
use derive_more::Constructor;
12
use serde::Deserialize;
23

34
/// A struct to keep information about the page when results are being paginated
4-
#[derive(Deserialize, Copy, Clone, Debug, PartialEq)]
5+
#[derive(Deserialize, Copy, Clone, Debug, PartialEq, Constructor)]
56
pub struct Pagination {
67
/// The page number, starting at 0
78
pub offset: u32,
@@ -10,11 +11,6 @@ pub struct Pagination {
1011
}
1112

1213
impl Pagination {
13-
#[must_use]
14-
pub fn new(offset: u32, limit: u32) -> Self {
15-
Self { offset, limit }
16-
}
17-
1814
#[must_use]
1915
pub fn new_with_options(offset_option: Option<u32>, limit_option: Option<u32>) -> Self {
2016
let offset = match offset_option {

packages/primitives/src/peer.rs

+20-4
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ use crate::{ser_unix_time_value, DurationSinceUnixEpoch, IPVersion, NumberOfByte
5151
/// event: AnnounceEvent::Started,
5252
/// };
5353
/// ```
54-
#[derive(PartialEq, Eq, Debug, Clone, Serialize, Copy)]
54+
#[derive(Debug, Clone, Serialize, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
5555
pub struct Peer {
5656
/// ID used by the downloader peer
5757
pub peer_id: Id,
@@ -173,6 +173,16 @@ impl From<[u8; 20]> for Id {
173173
}
174174
}
175175

176+
impl From<i32> for Id {
177+
fn from(number: i32) -> Self {
178+
let peer_id = number.to_le_bytes();
179+
Id::from([
180+
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, peer_id[0], peer_id[1], peer_id[2],
181+
peer_id[3],
182+
])
183+
}
184+
}
185+
176186
impl TryFrom<Vec<u8>> for Id {
177187
type Error = IdConversionError;
178188

@@ -332,7 +342,7 @@ impl<P: Encoding> FromIterator<Peer> for Vec<P> {
332342
}
333343

334344
pub mod fixture {
335-
use std::net::SocketAddr;
345+
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
336346

337347
use super::{Id, Peer};
338348
use crate::announce_event::AnnounceEvent;
@@ -396,8 +406,8 @@ pub mod fixture {
396406
impl Default for Peer {
397407
fn default() -> Self {
398408
Self {
399-
peer_id: Id(*b"-qB00000000000000000"),
400-
peer_addr: std::net::SocketAddr::new(std::net::IpAddr::V4(std::net::Ipv4Addr::new(126, 0, 0, 1)), 8080),
409+
peer_id: Id::default(),
410+
peer_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080),
401411
updated: DurationSinceUnixEpoch::new(1_669_397_478_934, 0),
402412
uploaded: NumberOfBytes(0),
403413
downloaded: NumberOfBytes(0),
@@ -406,6 +416,12 @@ pub mod fixture {
406416
}
407417
}
408418
}
419+
420+
impl Default for Id {
421+
fn default() -> Self {
422+
Self(*b"-qB00000000000000000")
423+
}
424+
}
409425
}
410426

411427
#[cfg(test)]

packages/primitives/src/torrent_metrics.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@ use std::ops::AddAssign;
66
#[derive(Copy, Clone, Debug, PartialEq, Default)]
77
pub struct TorrentsMetrics {
88
/// Total number of seeders for all torrents
9-
pub seeders: u64,
9+
pub complete: u64,
1010
/// Total number of peers that have ever completed downloading for all torrents.
11-
pub completed: u64,
11+
pub downloaded: u64,
1212
/// Total number of leechers for all torrents.
13-
pub leechers: u64,
13+
pub incomplete: u64,
1414
/// Total number of torrents.
1515
pub torrents: u64,
1616
}
1717

1818
impl AddAssign for TorrentsMetrics {
1919
fn add_assign(&mut self, rhs: Self) {
20-
self.seeders += rhs.seeders;
21-
self.completed += rhs.completed;
22-
self.leechers += rhs.leechers;
20+
self.complete += rhs.complete;
21+
self.downloaded += rhs.downloaded;
22+
self.incomplete += rhs.incomplete;
2323
self.torrents += rhs.torrents;
2424
}
2525
}

packages/torrent-repository/src/entry/mod.rs

+15-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::fmt::Debug;
2+
use std::net::SocketAddr;
23
use std::sync::Arc;
34

45
//use serde::{Deserialize, Serialize};
@@ -17,7 +18,7 @@ pub trait Entry {
1718
fn get_stats(&self) -> SwarmMetadata;
1819

1920
/// Returns True if Still a Valid Entry according to the Tracker Policy
20-
fn is_not_zombie(&self, policy: &TrackerPolicy) -> bool;
21+
fn is_good(&self, policy: &TrackerPolicy) -> bool;
2122

2223
/// Returns True if the Peers is Empty
2324
fn peers_is_empty(&self) -> bool;
@@ -33,7 +34,7 @@ pub trait Entry {
3334
///
3435
/// It filters out the input peer, typically because we want to return this
3536
/// list of peers to that client peer.
36-
fn get_peers_for_peer(&self, client: &peer::Peer, limit: Option<usize>) -> Vec<Arc<peer::Peer>>;
37+
fn get_peers_for_client(&self, client: &SocketAddr, limit: Option<usize>) -> Vec<Arc<peer::Peer>>;
3738

3839
/// It updates a peer and returns true if the number of complete downloads have increased.
3940
///
@@ -51,28 +52,26 @@ pub trait Entry {
5152
#[allow(clippy::module_name_repetitions)]
5253
pub trait EntrySync {
5354
fn get_stats(&self) -> SwarmMetadata;
54-
fn is_not_zombie(&self, policy: &TrackerPolicy) -> bool;
55+
fn is_good(&self, policy: &TrackerPolicy) -> bool;
5556
fn peers_is_empty(&self) -> bool;
5657
fn get_peers_len(&self) -> usize;
5758
fn get_peers(&self, limit: Option<usize>) -> Vec<Arc<peer::Peer>>;
58-
fn get_peers_for_peer(&self, client: &peer::Peer, limit: Option<usize>) -> Vec<Arc<peer::Peer>>;
59+
fn get_peers_for_client(&self, client: &SocketAddr, limit: Option<usize>) -> Vec<Arc<peer::Peer>>;
5960
fn insert_or_update_peer(&self, peer: &peer::Peer) -> bool;
6061
fn insert_or_update_peer_and_get_stats(&self, peer: &peer::Peer) -> (bool, SwarmMetadata);
6162
fn remove_inactive_peers(&self, current_cutoff: DurationSinceUnixEpoch);
6263
}
6364

6465
#[allow(clippy::module_name_repetitions)]
6566
pub trait EntryAsync {
66-
fn get_stats(self) -> impl std::future::Future<Output = SwarmMetadata> + Send;
67-
68-
#[allow(clippy::wrong_self_convention)]
69-
fn is_not_zombie(self, policy: &TrackerPolicy) -> impl std::future::Future<Output = bool> + Send;
70-
fn peers_is_empty(self) -> impl std::future::Future<Output = bool> + Send;
71-
fn get_peers_len(self) -> impl std::future::Future<Output = usize> + Send;
72-
fn get_peers(self, limit: Option<usize>) -> impl std::future::Future<Output = Vec<Arc<peer::Peer>>> + Send;
73-
fn get_peers_for_peer(
74-
self,
75-
client: &peer::Peer,
67+
fn get_stats(&self) -> impl std::future::Future<Output = SwarmMetadata> + Send;
68+
fn check_good(self, policy: &TrackerPolicy) -> impl std::future::Future<Output = bool> + Send;
69+
fn peers_is_empty(&self) -> impl std::future::Future<Output = bool> + Send;
70+
fn get_peers_len(&self) -> impl std::future::Future<Output = usize> + Send;
71+
fn get_peers(&self, limit: Option<usize>) -> impl std::future::Future<Output = Vec<Arc<peer::Peer>>> + Send;
72+
fn get_peers_for_client(
73+
&self,
74+
client: &SocketAddr,
7675
limit: Option<usize>,
7776
) -> impl std::future::Future<Output = Vec<Arc<peer::Peer>>> + Send;
7877
fn insert_or_update_peer(self, peer: &peer::Peer) -> impl std::future::Future<Output = bool> + Send;
@@ -88,11 +87,11 @@ pub trait EntryAsync {
8887
/// This is the tracker entry for a given torrent and contains the swarm data,
8988
/// that's the list of all the peers trying to download the same torrent.
9089
/// The tracker keeps one entry like this for every torrent.
91-
#[derive(Clone, Debug, Default)]
90+
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
9291
pub struct Torrent {
9392
/// The swarm: a network of peers that are all trying to download the torrent associated to this entry
9493
// #[serde(skip)]
9594
pub(crate) peers: std::collections::BTreeMap<peer::Id, Arc<peer::Peer>>,
9695
/// The number of peers that have ever completed downloading the torrent associated to this entry
97-
pub(crate) completed: u32,
96+
pub(crate) downloaded: u32,
9897
}

packages/torrent-repository/src/entry/mutex_std.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1+
use std::net::SocketAddr;
12
use std::sync::Arc;
23

34
use torrust_tracker_configuration::TrackerPolicy;
45
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
56
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch};
67

78
use super::{Entry, EntrySync};
8-
use crate::EntryMutexStd;
9+
use crate::{EntryMutexStd, EntrySingle};
910

1011
impl EntrySync for EntryMutexStd {
1112
fn get_stats(&self) -> SwarmMetadata {
1213
self.lock().expect("it should get a lock").get_stats()
1314
}
1415

15-
fn is_not_zombie(&self, policy: &TrackerPolicy) -> bool {
16-
self.lock().expect("it should get a lock").is_not_zombie(policy)
16+
fn is_good(&self, policy: &TrackerPolicy) -> bool {
17+
self.lock().expect("it should get a lock").is_good(policy)
1718
}
1819

1920
fn peers_is_empty(&self) -> bool {
@@ -28,8 +29,8 @@ impl EntrySync for EntryMutexStd {
2829
self.lock().expect("it should get lock").get_peers(limit)
2930
}
3031

31-
fn get_peers_for_peer(&self, client: &peer::Peer, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
32-
self.lock().expect("it should get lock").get_peers_for_peer(client, limit)
32+
fn get_peers_for_client(&self, client: &SocketAddr, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
33+
self.lock().expect("it should get lock").get_peers_for_client(client, limit)
3334
}
3435

3536
fn insert_or_update_peer(&self, peer: &peer::Peer) -> bool {
@@ -48,3 +49,9 @@ impl EntrySync for EntryMutexStd {
4849
.remove_inactive_peers(current_cutoff);
4950
}
5051
}
52+
53+
impl From<EntrySingle> for EntryMutexStd {
54+
fn from(entry: EntrySingle) -> Self {
55+
Arc::new(std::sync::Mutex::new(entry))
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,36 @@
1+
use std::net::SocketAddr;
12
use std::sync::Arc;
23

34
use torrust_tracker_configuration::TrackerPolicy;
45
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
56
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch};
67

78
use super::{Entry, EntryAsync};
8-
use crate::EntryMutexTokio;
9+
use crate::{EntryMutexTokio, EntrySingle};
910

1011
impl EntryAsync for EntryMutexTokio {
11-
async fn get_stats(self) -> SwarmMetadata {
12+
async fn get_stats(&self) -> SwarmMetadata {
1213
self.lock().await.get_stats()
1314
}
1415

15-
async fn is_not_zombie(self, policy: &TrackerPolicy) -> bool {
16-
self.lock().await.is_not_zombie(policy)
16+
async fn check_good(self, policy: &TrackerPolicy) -> bool {
17+
self.lock().await.is_good(policy)
1718
}
1819

19-
async fn peers_is_empty(self) -> bool {
20+
async fn peers_is_empty(&self) -> bool {
2021
self.lock().await.peers_is_empty()
2122
}
2223

23-
async fn get_peers_len(self) -> usize {
24+
async fn get_peers_len(&self) -> usize {
2425
self.lock().await.get_peers_len()
2526
}
2627

27-
async fn get_peers(self, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
28+
async fn get_peers(&self, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
2829
self.lock().await.get_peers(limit)
2930
}
3031

31-
async fn get_peers_for_peer(self, client: &peer::Peer, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
32-
self.lock().await.get_peers_for_peer(client, limit)
32+
async fn get_peers_for_client(&self, client: &SocketAddr, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
33+
self.lock().await.get_peers_for_client(client, limit)
3334
}
3435

3536
async fn insert_or_update_peer(self, peer: &peer::Peer) -> bool {
@@ -44,3 +45,9 @@ impl EntryAsync for EntryMutexTokio {
4445
self.lock().await.remove_inactive_peers(current_cutoff);
4546
}
4647
}
48+
49+
impl From<EntrySingle> for EntryMutexTokio {
50+
fn from(entry: EntrySingle) -> Self {
51+
Arc::new(tokio::sync::Mutex::new(entry))
52+
}
53+
}

0 commit comments

Comments
 (0)