Dandelion updates

- expiration now uses poisson distribution just like in the bitcoin
version
This commit is contained in:
Peter Šurda 2018-02-06 22:28:56 +01:00
parent 6269e45a47
commit 3d1fa473fb
Signed by: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87

View File

@ -1,5 +1,5 @@
from collections import namedtuple
from random import choice, sample
from random import choice, sample, expovariate
from threading import RLock
from time import time
@ -12,8 +12,11 @@ import state
# randomise routes after 600 seconds
REASSIGN_INTERVAL = 600
# trigger fluff due to expiration in 2 minutes
FLUFF_TRIGGER_TIMEOUT = 120
# trigger fluff due to expiration
FLUFF_TRIGGER_FIXED_DELAY = 10
FLUFF_TRIGGER_MEAN_DELAY = 30
MAX_STEMS = 2
Stem = namedtuple('Stem', ['child', 'stream', 'timeout'])
@ -31,6 +34,14 @@ class Dandelion():
self.refresh = time() + REASSIGN_INTERVAL
self.lock = RLock()
@staticmethod
def poissonTimeout(start=None, average=0):
if start is None:
start = time()
if average == 0:
average = FLUFF_TRIGGER_MEAN_DELAY
return start + expovariate(1.0/average) + FLUFF_TRIGGER_FIXED_DELAY
def addHash(self, hashId, source=None, stream=1):
if not state.dandelion:
return
@ -38,7 +49,7 @@ class Dandelion():
self.hashMap[hashId] = Stem(
self.getNodeStem(source),
stream,
time() + FLUFF_TRIGGER_TIMEOUT)
Dandelion.poissonTimeout())
def setHashStream(self, hashId, stream=1):
with self.lock:
@ -46,7 +57,7 @@ class Dandelion():
self.hashMap[hashId] = Stem(
self.hashMap[hashId].child,
stream,
time() + FLUFF_TRIGGER_TIMEOUT)
Dandelion.poissonTimeout())
def removeHash(self, hashId, reason="no reason specified"):
logging.debug("%s entering fluff mode due to %s.", ''.join('%02x'%ord(i) for i in hashId), reason)
@ -70,7 +81,7 @@ class Dandelion():
for k in (k for k, v in self.nodeMap.iteritems() if v is None):
self.nodeMap[k] = connection
for k, v in {k: v for k, v in self.hashMap.iteritems() if v.child is None}.iteritems():
self.hashMap[k] = Stem(connection, v.stream, time() + FLUFF_TRIGGER_TIMEOUT)
self.hashMap[k] = Stem(connection, v.stream, Dandelion.poissionTimeout())
invQueue.put((v.stream, k, v.child))
@ -83,7 +94,7 @@ class Dandelion():
for k in (k for k, v in self.nodeMap.iteritems() if v == connection):
self.nodeMap[k] = None
for k, v in {k: v for k, v in self.hashMap.iteritems() if v.child == connection}.iteritems():
self.hashMap[k] = Stem(None, v.stream, time() + FLUFF_TRIGGER_TIMEOUT)
self.hashMap[k] = Stem(None, v.stream, Dandelion.poissonTimeout())
def pickStem(self, parent=None):
try: