A Python port of the Invisible Internet Project (I2P)
1"""Trimmer implementations for Kademlia buckets.
2
3Ported from net.i2p.kademlia.{RejectTrimmer, RandomTrimmer, RandomIfOldTrimmer}.
4"""
5
6import random
7import time as _time
8
9from i2p_kademlia.kbucket import KBucket, KBucketTrimmer
10
11
12def _now_ms() -> int:
13 return int(_time.time() * 1000)
14
15
16class RejectTrimmer(KBucketTrimmer):
17 """Always reject new entries when bucket is full. Flood-resistant."""
18
19 def trim(self, bucket: KBucket, to_add: bytes) -> bool:
20 return False
21
22
23class RandomTrimmer(KBucketTrimmer):
24 """Remove a random entry to make room. Not flood-resistant."""
25
26 def __init__(self, max_size: int) -> None:
27 self._max = max_size
28
29 def trim(self, bucket: KBucket, to_add: bytes) -> bool:
30 entries = list(bucket.get_entries())
31 if len(entries) >= self._max and entries:
32 victim = random.choice(entries)
33 bucket.remove(victim)
34 return True
35
36
37class RandomIfOldTrimmer(RandomTrimmer):
38 """Remove random entry only if bucket hasn't been updated recently (5 min)."""
39
40 _STALE_THRESHOLD = 5 * 60 * 1000 # 5 minutes
41
42 def trim(self, bucket: KBucket, to_add: bytes) -> bool:
43 if bucket.last_changed > _now_ms() - self._STALE_THRESHOLD:
44 return False # Bucket is fresh, reject
45 return super().trim(bucket, to_add)