From b1442ecb0a1e8c383040a071c648624c38fef5c5 Mon Sep 17 00:00:00 2001 From: Peter Surda Date: Sat, 30 Sep 2017 13:42:04 +0200 Subject: [PATCH] Dandelion fixes and updates - also, randomise the item order in an inv/dinv command --- src/network/bmproto.py | 6 ++---- src/network/dandelion.py | 10 ++++++---- src/network/invthread.py | 26 +++++++++++++++----------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/network/bmproto.py b/src/network/bmproto.py index 66f066ef..8099c5fc 100644 --- a/src/network/bmproto.py +++ b/src/network/bmproto.py @@ -274,7 +274,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): random.shuffle(items) for i in items: if i in DandelionStems().stem and \ - self not in DandelionStems().stem[i]: + self != DandelionStems().stem[i]: self.antiIntersectionDelay() logger.info('%s asked for a stem object we didn\'t offer to it.', self.destination) break @@ -324,9 +324,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): self.dandelionRefresh = time.time() + REASSIGN_INTERVAL for i in items: - # Fluff trigger by RNG, per item - if random.randint(1, 100) < BMConfigParser().safeGetBoolean("network", "dandelion"): - DandelionStem().add(i, self.dandelionRoutes) + DandelionStems().add(i, self, self.dandelionRoutes) self.handleReceivedInventory(i) return True diff --git a/src/network/dandelion.py b/src/network/dandelion.py index ea27915f..045f7288 100644 --- a/src/network/dandelion.py +++ b/src/network/dandelion.py @@ -1,7 +1,6 @@ -import random +from random import choice from threading import RLock -import protocol from singleton import Singleton # randomise routes after 600 seconds @@ -12,18 +11,21 @@ FLUFF_TRIGGER_TIMEOUT = 300 class DandelionStems(): def __init__(self): self.stem = {} + self.source = {} self.timeouts = {} self.lock = RLock() - def add(self, hashId, stems): + def add(self, hashId, source, stems): with self.lock: - self.stem[hashId] = stems + self.stem[hashId] = choice(stems) + self.source[hashId] = source self.timeouts[hashId] = time.time() def remove(self, hashId): with self.lock: try: del self.stem[hashId] + del self.source[hashId] del self.timeouts[hashId] except KeyError: pass diff --git a/src/network/invthread.py b/src/network/invthread.py index 992930db..574e8a3a 100644 --- a/src/network/invthread.py +++ b/src/network/invthread.py @@ -1,5 +1,5 @@ import Queue -from random import randint +from random import randint, shuffle import threading from time import time @@ -35,11 +35,8 @@ class InvThread(threading.Thread, StoppableThread): data = invQueue.get(False) # locally generated if len(data) == 2: + DandelionStems.add(data[1], None, self.dandelionRoutes) BMConnectionPool().handleReceivedObject(data[0], data[1]) - # Fluff trigger by RNG - # auto-ignore if config set to 0, i.e. dandelion is off - if randint(1, 100) < BMConfigParser().safeGetBoolean("network", "dandelion"): - DandelionStems.add(data[1], self.dandelionRoutes) # came over the network else: source = BMConnectionPool().getConnectionByAddr(data[2]) @@ -59,21 +56,28 @@ class InvThread(threading.Thread, StoppableThread): for inv in chunk: if inv[0] not in connection.streams: continue - if inv[1] in DandelionStems().stem: - if connection in DandelionStems().stem[inv[1]]: - stems.append(inv[1]) - continue - # else try: with connection.objectsNewToThemLock: del connection.objectsNewToThem[inv[1]] - fluffs.append(inv[1]) except KeyError: continue + if inv[1] in DandelionStems().stem: + if connection == DandelionStems().stem[inv[1]]: + # Fluff trigger by RNG + # auto-ignore if config set to 0, i.e. dandelion is off + if randint(1, 100) < BMConfigParser().safeGetBoolean("network", "dandelion"): + stems.append(inv[1]) + else: + fluffs.append(inv[1]) + continue + else: + fluffs.append(inv[1]) if fluffs: + shuffle(fluffs) connection.append_write_buf(protocol.CreatePacket('inv', \ addresses.encodeVarint(len(fluffs)) + "".join(fluffs))) if stems: + shuffle(stems) connection.append_write_buf(protocol.CreatePacket('dinv', \ addresses.encodeVarint(len(stems)) + "".join(stems))) invQueue.iterate()