Dandelion fixes and updates

- also, randomise the item order in an inv/dinv command
This commit is contained in:
Peter Šurda 2017-09-30 13:42:04 +02:00
parent 08748fa9ae
commit b1442ecb0a
Signed by: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87
3 changed files with 23 additions and 19 deletions

View File

@ -274,7 +274,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
random.shuffle(items) random.shuffle(items)
for i in items: for i in items:
if i in DandelionStems().stem and \ if i in DandelionStems().stem and \
self not in DandelionStems().stem[i]: self != DandelionStems().stem[i]:
self.antiIntersectionDelay() self.antiIntersectionDelay()
logger.info('%s asked for a stem object we didn\'t offer to it.', self.destination) logger.info('%s asked for a stem object we didn\'t offer to it.', self.destination)
break break
@ -324,9 +324,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
self.dandelionRefresh = time.time() + REASSIGN_INTERVAL self.dandelionRefresh = time.time() + REASSIGN_INTERVAL
for i in items: for i in items:
# Fluff trigger by RNG, per item DandelionStems().add(i, self, self.dandelionRoutes)
if random.randint(1, 100) < BMConfigParser().safeGetBoolean("network", "dandelion"):
DandelionStem().add(i, self.dandelionRoutes)
self.handleReceivedInventory(i) self.handleReceivedInventory(i)
return True return True

View File

@ -1,7 +1,6 @@
import random from random import choice
from threading import RLock from threading import RLock
import protocol
from singleton import Singleton from singleton import Singleton
# randomise routes after 600 seconds # randomise routes after 600 seconds
@ -12,18 +11,21 @@ FLUFF_TRIGGER_TIMEOUT = 300
class DandelionStems(): class DandelionStems():
def __init__(self): def __init__(self):
self.stem = {} self.stem = {}
self.source = {}
self.timeouts = {} self.timeouts = {}
self.lock = RLock() self.lock = RLock()
def add(self, hashId, stems): def add(self, hashId, source, stems):
with self.lock: with self.lock:
self.stem[hashId] = stems self.stem[hashId] = choice(stems)
self.source[hashId] = source
self.timeouts[hashId] = time.time() self.timeouts[hashId] = time.time()
def remove(self, hashId): def remove(self, hashId):
with self.lock: with self.lock:
try: try:
del self.stem[hashId] del self.stem[hashId]
del self.source[hashId]
del self.timeouts[hashId] del self.timeouts[hashId]
except KeyError: except KeyError:
pass pass

View File

@ -1,5 +1,5 @@
import Queue import Queue
from random import randint from random import randint, shuffle
import threading import threading
from time import time from time import time
@ -35,11 +35,8 @@ class InvThread(threading.Thread, StoppableThread):
data = invQueue.get(False) data = invQueue.get(False)
# locally generated # locally generated
if len(data) == 2: if len(data) == 2:
DandelionStems.add(data[1], None, self.dandelionRoutes)
BMConnectionPool().handleReceivedObject(data[0], data[1]) 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 # came over the network
else: else:
source = BMConnectionPool().getConnectionByAddr(data[2]) source = BMConnectionPool().getConnectionByAddr(data[2])
@ -59,21 +56,28 @@ class InvThread(threading.Thread, StoppableThread):
for inv in chunk: for inv in chunk:
if inv[0] not in connection.streams: if inv[0] not in connection.streams:
continue continue
if inv[1] in DandelionStems().stem:
if connection in DandelionStems().stem[inv[1]]:
stems.append(inv[1])
continue
# else
try: try:
with connection.objectsNewToThemLock: with connection.objectsNewToThemLock:
del connection.objectsNewToThem[inv[1]] del connection.objectsNewToThem[inv[1]]
fluffs.append(inv[1])
except KeyError: except KeyError:
continue 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: if fluffs:
shuffle(fluffs)
connection.append_write_buf(protocol.CreatePacket('inv', \ connection.append_write_buf(protocol.CreatePacket('inv', \
addresses.encodeVarint(len(fluffs)) + "".join(fluffs))) addresses.encodeVarint(len(fluffs)) + "".join(fluffs)))
if stems: if stems:
shuffle(stems)
connection.append_write_buf(protocol.CreatePacket('dinv', \ connection.append_write_buf(protocol.CreatePacket('dinv', \
addresses.encodeVarint(len(stems)) + "".join(stems))) addresses.encodeVarint(len(stems)) + "".join(stems)))
invQueue.iterate() invQueue.iterate()