Skip to content

Commit 3d1fa47

Browse files
committed
Dandelion updates
- expiration now uses poisson distribution just like in the bitcoin version
1 parent 6269e45 commit 3d1fa47

1 file changed

Lines changed: 18 additions & 7 deletions

File tree

src/network/dandelion.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from collections import namedtuple
2-
from random import choice, sample
2+
from random import choice, sample, expovariate
33
from threading import RLock
44
from time import time
55

@@ -12,8 +12,11 @@
1212

1313
# randomise routes after 600 seconds
1414
REASSIGN_INTERVAL = 600
15-
# trigger fluff due to expiration in 2 minutes
16-
FLUFF_TRIGGER_TIMEOUT = 120
15+
16+
# trigger fluff due to expiration
17+
FLUFF_TRIGGER_FIXED_DELAY = 10
18+
FLUFF_TRIGGER_MEAN_DELAY = 30
19+
1720
MAX_STEMS = 2
1821

1922
Stem = namedtuple('Stem', ['child', 'stream', 'timeout'])
@@ -31,22 +34,30 @@ def __init__(self):
3134
self.refresh = time() + REASSIGN_INTERVAL
3235
self.lock = RLock()
3336

37+
@staticmethod
38+
def poissonTimeout(start=None, average=0):
39+
if start is None:
40+
start = time()
41+
if average == 0:
42+
average = FLUFF_TRIGGER_MEAN_DELAY
43+
return start + expovariate(1.0/average) + FLUFF_TRIGGER_FIXED_DELAY
44+
3445
def addHash(self, hashId, source=None, stream=1):
3546
if not state.dandelion:
3647
return
3748
with self.lock:
3849
self.hashMap[hashId] = Stem(
3950
self.getNodeStem(source),
4051
stream,
41-
time() + FLUFF_TRIGGER_TIMEOUT)
52+
Dandelion.poissonTimeout())
4253

4354
def setHashStream(self, hashId, stream=1):
4455
with self.lock:
4556
if hashId in self.hashMap:
4657
self.hashMap[hashId] = Stem(
4758
self.hashMap[hashId].child,
4859
stream,
49-
time() + FLUFF_TRIGGER_TIMEOUT)
60+
Dandelion.poissonTimeout())
5061

5162
def removeHash(self, hashId, reason="no reason specified"):
5263
logging.debug("%s entering fluff mode due to %s.", ''.join('%02x'%ord(i) for i in hashId), reason)
@@ -70,7 +81,7 @@ def maybeAddStem(self, connection):
7081
for k in (k for k, v in self.nodeMap.iteritems() if v is None):
7182
self.nodeMap[k] = connection
7283
for k, v in {k: v for k, v in self.hashMap.iteritems() if v.child is None}.iteritems():
73-
self.hashMap[k] = Stem(connection, v.stream, time() + FLUFF_TRIGGER_TIMEOUT)
84+
self.hashMap[k] = Stem(connection, v.stream, Dandelion.poissionTimeout())
7485
invQueue.put((v.stream, k, v.child))
7586

7687

@@ -83,7 +94,7 @@ def maybeRemoveStem(self, connection):
8394
for k in (k for k, v in self.nodeMap.iteritems() if v == connection):
8495
self.nodeMap[k] = None
8596
for k, v in {k: v for k, v in self.hashMap.iteritems() if v.child == connection}.iteritems():
86-
self.hashMap[k] = Stem(None, v.stream, time() + FLUFF_TRIGGER_TIMEOUT)
97+
self.hashMap[k] = Stem(None, v.stream, Dandelion.poissonTimeout())
8798

8899
def pickStem(self, parent=None):
89100
try:

0 commit comments

Comments
 (0)