Browse Source

Implement relay churn

Ian Goldberg 4 years ago
parent
commit
53552a3e36
1 changed files with 39 additions and 1 deletions
  1. 39 1
      simulator.py

+ 39 - 1
simulator.py

@@ -171,7 +171,45 @@ class Simulator:
         for r in self.relays: r.perfstats.reset()
         for c in self.clients: c.perfstats.reset()
 
-        # TODO: churn relays and clients
+        # Churn relays
+
+        # Churn is controlled by three parameters:
+        # newmean: the mean number of new arrivals per epoch
+        # newstddev: the stddev number of new arrivals per epoch
+        # oldprob: the probability any given existing one leaves per epoch
+
+        # If target is the desired steady state number, then it should
+        # be the case that target * oldprob = newmean.  That way, if the
+        # current number is below target, on average you add more than
+        # you remove, and if the current number is above target, on
+        # average you add fewer than you remove.
+
+        # For relays, looking at all the consensuses for Nov and Dec
+        # 2019, newmean is about 1.0% of the network size, and newstddev
+        # is about 0.3% of the network size.
+        relay_newmean = 0.010 * self.relaytarget
+        relay_newstddev = 0.003 * self.relaytarget
+        relay_oldprob = 0.010
+
+        # Stop some of the (non-fallback) relays
+        relays_terminating = []
+        for r in self.relays:
+            if not r.is_fallbackrelay and random.random() < relay_oldprob:
+                relays_terminating.append(r)
+
+        for r in relays_terminating:
+            r.terminate()
+            self.relays.remove(r)
+
+        # Start some new relays
+        relays_new = int(random.normalvariate(relay_newmean, relay_newstddev))
+        if relays_new > 0:
+            for i in range(relays_new):
+                x = random.randint(1,2500)
+                bw = int(200000-(200000-25000)/3*math.log10(x))
+                self.relays.append(relay.Relay(self.dirauthaddrs, bw, 0))
+
+        # TODO: churn clients
 
         # Tick the epoch
         network.thenetwork.nextepoch()