torrust-tracker icon indicating copy to clipboard operation
torrust-tracker copied to clipboard

Optimization: return peer IP list from swarm (lowest-level layer) to servers (highest-level layer)

Open josecelano opened this issue 7 months ago • 0 comments

Relates to: https://github.com/torrust/torrust-tracker/issues/1366

This is the description of a potencial optimisation not tested.

WARNING: It might not be more efficient or faster.

It's valid for both the HTTP and UDP trackers. TO make the explanation shorter, I will focus only on the UDP tracker (with sample code from the UDP tracker packages).

The function calls to handle the announce request are like this:

torrust_udp_tracker_server::handlers::announce::handle_announce (uses AnnounceData to build the response)
                           ⬇️
bittorrent_udp_tracker_core::services::announce::AnnounceService::handle_announce (returns AnnounceData)                          
                           ⬇️
bittorrent_tracker_core::announce_handler::AnnounceHandler::announce (returns AnnounceData)
                           ⬇️
bittorrent_tracker_core::torrent::repository::in_memory::InMemoryTorrentRepository::get_peers_for (returns Vec<Arc<peer::Peer>>)
                           ⬇️
torrust_tracker_torrent_repository::swarms::Swarms::get_peers_peers_excluding (returns Vec<Arc<peer::Peer>>)
                           ⬇️
torrust_tracker_torrent_repository::swarm::Swarm::peers_excluding (returns Vec<Arc<peer::Peer>>)

The torrent_repository package returns a vector of peers with all the information about the peer (latest announce).

The other intermediary layers use the AnnounceData type:

pub struct AnnounceData {
    /// The list of peers that are downloading the same torrent.
    /// It excludes the peer that made the request.
    pub peers: Vec<Arc<peer::Peer>>,
    /// Swarm statistics
    pub stats: SwarmMetadata,
    pub policy: AnnouncePolicy,
}

That also includes other information used in the announcement response.

Since we only need the IP and the Peer ID, we could refactor the AnnounceData to include only that information and remove the other peer fields.

pub struct AnnounceData {
    pub peers: Vec<Arc<peer::Peer>>,
    pub stats: SwarmMetadata,
    pub policy: AnnouncePolicy,
}

pub struct CompactPeer {
    pub ip: IpAddr,
    pub id: PeerId,
}

In fact, there is already a CompactPeer in the HTTP tracker server, here.

pub struct CompactPeer {
    ip: Ipv4Addr,
    port: u16,
}

WARNING: Splitting the list of peers into IPv4 and IPv6 peers might not be necessary. See https://github.com/torrust/torrust-tracker/issues/1366

Response examples:

http_tracker_client announce 'http://127.0.0.1:7070' 443c7602b4fde83d1154d6d9da48808418b181b6`
{
  "complete": 2,
  "incomplete": 0,
  "interval": 120,
  "min interval": 120,
  "peers": [
    {
      "ip": "0.0.0.0",
      "peer id": [
        45,
        113,
        66,
        48,
        48,
        48,
        48,
        48,
        48,
        48,
        48,
        48,
        48,
        48,
        48,
        48,
        48,
        48,
        48,
        49
      ],
      "port": 42480
    }
  ]
}
udp_tracker_client announce 'udp://127.0.0.1:6969' 443c7602b4fde83d1154d6d9da48808418b181b6`
{
  "AnnounceIpv4": {
    "transaction_id": -888840697,
    "announce_interval": 120,
    "leechers": 0,
    "seeders": 3,
    "peers": [
      "0.0.0.0:17548",
      "0.0.0.0:42480"
    ]
  }
}

cc @da2ce7

josecelano avatar May 07 '25 16:05 josecelano