TorrentPeer
A single known peer of a torrent. The pure-Kotlin port of libtorrent's struct torrent_peer (include/libtorrent/torrent_peer.hpp, src/torrent_peer.cpp).
A torrent_peer is not a connection. It is the long-lived bookkeeping record for an endpoint we have heard about (from a tracker, the DHT, PEX, LSD, resume data, or an incoming connection), whether or not we are connected to it right now. The PeerList owns a sorted collection of these and uses their counters to decide who to (re)connect to.
Address representation
Upstream subclasses torrent_peer into ipv4_peer / ipv6_peer / i2p_peer to store the address compactly in a Boost.Asio type. KiteTorrent v0 carries no socket types in commonMain, so we keep the address as a plain host string plus an integer port. When a behaviour genuinely needs the numeric address (ranking, locality, canonical ordering) we parse it on demand via PeerAddress.parseOrNull and cache the result in address. i2p peers are out of scope for v0 and are not modelled.
Field widths
libtorrent packs many of these into bit-fields (failcount:5, trust_points:4, source:6, plus a wall of bool:1s) purely to shrink the struct. We use ordinary Int/Boolean properties. The semantics are what matter, and we preserve the documented value ranges in the accessors that mutate them (e.g. failcount saturates at 31, mirroring the 5-bit field).
Mutability mirrors upstream: a torrent_peer is a mutable record poked by the owning PeerList; only host is immutable here (the endpoint identity), while counters and flags change over the peer's lifetime. The port can be updated when a peer advertises its real listen port, exactly as peer_list::update_peer_port does.
Properties
We have connected via uTP at least once.
Whether we have a listen port for this peer and may therefore initiate an outgoing connection. Incoming peers that never advertise a port are not connectable. This is a precondition of being a connect candidate.
Whether we currently hold a live connection to this peer. libtorrent stores a peer_connection_interface* here; v0 has no connection layer, so we model only the boolean "is connected" fact that all of the connect-candidate logic actually keys off of. Set through PeerList.setConnected.
Number of failed connection attempts to this peer. Saturates at 31 (a 5-bit field upstream); PeerList.incFailcount never lets it exceed that.
Number of fast reconnects we have allowed this peer. [0, 15] (4-bit).
Session-time (seconds since session start) at which we last connected to (or disconnected from) this peer. 0 means "never". 16-bit in upstream.
Session-time of this peer's last optimistic unchoke. 0 means "never".
A soft hint (from PEX pex_seed, before we have connected) that this peer is upload-only / probably a seed. Cleared the moment we connect, since we then learn the truth. De-prioritised when we are finished.
True while this peer is unchoked because of an optimistic unchoke.
Bytes downloaded from this peer during the last closed connection, in kiB.
Bytes uploaded to this peer during the last closed connection, in kiB.
True if this peer supports BitTorrent protocol v2.
True once we know this peer is a seed because we connected and it told us. Distinct from maybeUploadOnly, which is only a hint.
Bitmap of PeerSource flags: every channel that has told us about this peer, OR-ed together. Drives sourceRank in connect ordering.
We think this peer supports holepunching.
We think this peer supports uTP. Defaults true (assume support), per upstream.
Trust score in [-7, 8] (a signed 4-bit field upstream): incremented for each valid piece this peer helped deliver, decremented for each bad one. If it sinks far enough the peer is treated as bad. Used as a tie-breaker when choosing which peer to evict (comparePeerErase).
Functions
True if this peer's endpoint equals (otherHost, otherPort). Endpoint identity is (address, port). This is the port of the torrent_peer_equal predicate for the IP case. Compares by parsed address when both hosts are literal IPs (so "127.0.0.1" and "127.000.000.001" match), falling back to string equality otherwise.
Total bytes downloaded from this peer (best estimate). With no live connection layer in v0, this is simply prevAmountDownload scaled from kiB to bytes. The port of torrent_peer::total_download's offline branch.
Total bytes uploaded to this peer. See totalDownload.