Dandelion updates
- expiration now uses poisson distribution just like in the bitcoin version
This commit is contained in:
parent
6269e45a47
commit
3d1fa473fb
|
@ -1,5 +1,5 @@
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from random import choice, sample
|
from random import choice, sample, expovariate
|
||||||
from threading import RLock
|
from threading import RLock
|
||||||
from time import time
|
from time import time
|
||||||
|
|
||||||
|
@ -12,8 +12,11 @@ import state
|
||||||
|
|
||||||
# randomise routes after 600 seconds
|
# randomise routes after 600 seconds
|
||||||
REASSIGN_INTERVAL = 600
|
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
|
MAX_STEMS = 2
|
||||||
|
|
||||||
Stem = namedtuple('Stem', ['child', 'stream', 'timeout'])
|
Stem = namedtuple('Stem', ['child', 'stream', 'timeout'])
|
||||||
|
@ -31,6 +34,14 @@ class Dandelion():
|
||||||
self.refresh = time() + REASSIGN_INTERVAL
|
self.refresh = time() + REASSIGN_INTERVAL
|
||||||
self.lock = RLock()
|
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):
|
def addHash(self, hashId, source=None, stream=1):
|
||||||
if not state.dandelion:
|
if not state.dandelion:
|
||||||
return
|
return
|
||||||
|
@ -38,7 +49,7 @@ class Dandelion():
|
||||||
self.hashMap[hashId] = Stem(
|
self.hashMap[hashId] = Stem(
|
||||||
self.getNodeStem(source),
|
self.getNodeStem(source),
|
||||||
stream,
|
stream,
|
||||||
time() + FLUFF_TRIGGER_TIMEOUT)
|
Dandelion.poissonTimeout())
|
||||||
|
|
||||||
def setHashStream(self, hashId, stream=1):
|
def setHashStream(self, hashId, stream=1):
|
||||||
with self.lock:
|
with self.lock:
|
||||||
|
@ -46,7 +57,7 @@ class Dandelion():
|
||||||
self.hashMap[hashId] = Stem(
|
self.hashMap[hashId] = Stem(
|
||||||
self.hashMap[hashId].child,
|
self.hashMap[hashId].child,
|
||||||
stream,
|
stream,
|
||||||
time() + FLUFF_TRIGGER_TIMEOUT)
|
Dandelion.poissonTimeout())
|
||||||
|
|
||||||
def removeHash(self, hashId, reason="no reason specified"):
|
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)
|
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):
|
for k in (k for k, v in self.nodeMap.iteritems() if v is None):
|
||||||
self.nodeMap[k] = connection
|
self.nodeMap[k] = connection
|
||||||
for k, v in {k: v for k, v in self.hashMap.iteritems() if v.child is None}.iteritems():
|
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))
|
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):
|
for k in (k for k, v in self.nodeMap.iteritems() if v == connection):
|
||||||
self.nodeMap[k] = None
|
self.nodeMap[k] = None
|
||||||
for k, v in {k: v for k, v in self.hashMap.iteritems() if v.child == connection}.iteritems():
|
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):
|
def pickStem(self, parent=None):
|
||||||
try:
|
try:
|
||||||
|
|
Reference in New Issue
Block a user