DhtStorage

class DhtStorage(val maxPeersPerTorrent: Int = DEFAULT_MAX_PEERS, val maxItems: Int = DEFAULT_MAX_ITEMS, val maxTorrents: Int = DEFAULT_MAX_TORRENTS)

In-memory DHT data store. This is a pure-Kotlin port of libtorrent's dht_default_storage (src/kademlia/dht_storage.cpp). It holds the three things a DHT node serves:

  • announced peers per info-hash (BEP-5 announce_peer / get_peers), bucketed by address family and aged out after PEER_LIFETIME_SECONDS,

  • immutable items keyed by SHA-1(value) (BEP-44), and

  • mutable items keyed by SHA-1(public key ‖ salt) (BEP-44), where a higher sequence number supersedes a lower one.

Time. libtorrent calls aux::time_now() internally; per this module's contract that ambient clock is replaced by an explicit now parameter (epoch seconds as a Long) threaded through announcePeer, getPeers, putImmutableItem, putMutableItem and tick. This keeps the structure pure and deterministically testable.

Scope. This is the data structure only. The transport-side machinery in node::incoming_request lives in the node layer and is not duplicated here. That covers write-token generation and verification, BEP-42 id checks, the infohashes_sample for BEP-51, the popularity-based eviction (pick_least_important_item) and the dht_max_* capacity caps. maxPeersPerTorrent and maxItems provide the same drop-when-full behaviour the settings drive upstream.

Constructors

Link copied to clipboard
constructor(maxPeersPerTorrent: Int = DEFAULT_MAX_PEERS, maxItems: Int = DEFAULT_MAX_ITEMS, maxTorrents: Int = DEFAULT_MAX_TORRENTS)

Types

Link copied to clipboard
object Companion
Link copied to clipboard
class PeerEntry(val endpoint: DhtEndpoint, var added: Long, var seed: Boolean)

One announced peer: the port of the anonymous peer_entry in dht_storage.cpp.

Link copied to clipboard
class PeersResult(val peers: List<DhtEndpoint>, val name: String?)

Result of getPeers: the selected peer endpoints plus the torrent name (if any).

Properties

Link copied to clipboard

Number of stored immutable items.

Link copied to clipboard

Cap on stored immutable + mutable items, each table (dht_max_dht_items, default 700).

Link copied to clipboard

Cap on stored peers per torrent (dht_max_peers, default 2000).

Link copied to clipboard

Cap on the number of distinct torrents tracked (dht_max_torrents, default 2000).

Link copied to clipboard

Number of stored mutable items.

Link copied to clipboard

Total announced peers across all torrents.

Link copied to clipboard

Number of distinct torrents currently tracked.

Functions

Link copied to clipboard
fun announcePeer(infoHash: Sha1Hash, endpoint: DhtEndpoint, now: Long, seed: Boolean = false, name: String? = null)

Record an announce_peer, the port of dht_default_storage::announce_peer. The peer is keyed by address family; re-announcing the same endpoint refreshes its timestamp/seed flag in place. A new torrent is created unless maxTorrents is reached, and a new peer is added unless maxPeersPerTorrent is reached.

Link copied to clipboard

Fetch a stored immutable item by target, the port of get_immutable_item. Returns null if absent.

Link copied to clipboard

Fetch a stored mutable item by target, the port of get_mutable_item. Returns null if absent.

Link copied to clipboard

The stored sequence number for target, or null if absent. This is the port of get_mutable_item_seq. The node layer uses this for the BEP-44 cas / old-sequence checks before a put.

Link copied to clipboard
fun getPeers(infoHash: Sha1Hash, wantV4: Boolean, now: Long, noseed: Boolean = false, maxReply: Int = DEFAULT_MAX_PEERS_REPLY): DhtStorage.PeersResult?

Fetch the announced peers for infoHash in the requester's address family. This is the data half of dht_default_storage::get_peers. noseed excludes seeds (for a seeding requester); wantV4 picks peers4 vs peers6. At most maxReply peers are returned, taken in stored order rather than sampled, because sampling is a transport concern. The optional torrent name is returned alongside.

Link copied to clipboard

Store an immutable item, the port of put_immutable_item. The key is DhtItem.target (= SHA-1 of the bencoded value). Re-putting the same target just refreshes its last-seen stamp. When the table is full a put of a new target is dropped (libtorrent instead evicts the least-important item; that popularity heuristic is a node-layer concern, so here a full table simply refuses new targets).

Link copied to clipboard

Store or update a mutable item, the port of put_mutable_item. The key is MutableItem.target (= SHA-1(public key ‖ salt)). If a slot already exists, the new item replaces it only when its sequence number is strictly greater (if (item.seq < seq)), so older writes can never clobber newer ones; either way the last-seen stamp is refreshed. A new slot is dropped when the table is full (see putImmutableItem on eviction).

Link copied to clipboard
fun tick(now: Long, itemLifetimeSeconds: Long = DEFAULT_ITEM_LIFETIME_SECONDS)

Remove expired peers and items, the port of dht_default_storage::tick. Peers older than PEER_LIFETIME_SECONDS are purged and torrents left with no peers are removed; immutable/mutable items not heard about within itemLifetimeSeconds are dropped.