Runnable with both Python3 and Python2, with PyQt4 #2249
|
@ -14,7 +14,6 @@ def start(config, state):
|
||||||
from .announcethread import AnnounceThread
|
from .announcethread import AnnounceThread
|
||||||
from network import connectionpool
|
from network import connectionpool
|
||||||
from .addrthread import AddrThread
|
from .addrthread import AddrThread
|
||||||
from .dandelion import Dandelion
|
|
||||||
from .downloadthread import DownloadThread
|
from .downloadthread import DownloadThread
|
||||||
from .invthread import InvThread
|
from .invthread import InvThread
|
||||||
from .networkthread import BMNetworkThread
|
from .networkthread import BMNetworkThread
|
||||||
|
@ -23,8 +22,6 @@ def start(config, state):
|
||||||
from .uploadthread import UploadThread
|
from .uploadthread import UploadThread
|
||||||
|
|
||||||
readKnownNodes()
|
readKnownNodes()
|
||||||
# init, needs to be early because other thread may access it early
|
|
||||||
state.Dandelion = Dandelion()
|
|
||||||
connectionpool.pool.connectToStream(1)
|
connectionpool.pool.connectToStream(1)
|
||||||
for thread in (
|
for thread in (
|
||||||
BMNetworkThread(), InvThread(), AddrThread(),
|
BMNetworkThread(), InvThread(), AddrThread(),
|
||||||
|
|
|
@ -7,6 +7,7 @@ import time
|
||||||
import protocol
|
import protocol
|
||||||
import state
|
import state
|
||||||
import network.connectionpool # use long name to address recursive import
|
import network.connectionpool # use long name to address recursive import
|
||||||
|
import dandelion
|
||||||
from highlevelcrypto import calculateInventoryHash
|
from highlevelcrypto import calculateInventoryHash
|
||||||
|
|
||||||
logger = logging.getLogger('default')
|
logger = logging.getLogger('default')
|
||||||
|
@ -112,7 +113,7 @@ class BMObject(object): # pylint: disable=too-many-instance-attributes
|
||||||
or advertise it unnecessarily)
|
or advertise it unnecessarily)
|
||||||
"""
|
"""
|
||||||
# if it's a stem duplicate, pretend we don't have it
|
# if it's a stem duplicate, pretend we don't have it
|
||||||
if state.Dandelion.hasHash(self.inventoryHash):
|
if dandelion.instance.hasHash(self.inventoryHash):
|
||||||
return
|
return
|
||||||
if self.inventoryHash in state.Inventory:
|
if self.inventoryHash in state.Inventory:
|
||||||
raise BMObjectAlreadyHaveError()
|
raise BMObjectAlreadyHaveError()
|
||||||
|
|
|
@ -17,6 +17,7 @@ from network import knownnodes
|
||||||
import protocol
|
import protocol
|
||||||
import state
|
import state
|
||||||
import network.connectionpool # use long name to address recursive import
|
import network.connectionpool # use long name to address recursive import
|
||||||
|
import dandelion
|
||||||
from bmconfigparser import config
|
from bmconfigparser import config
|
||||||
from queues import invQueue, objectProcessorQueue, portCheckerQueue
|
from queues import invQueue, objectProcessorQueue, portCheckerQueue
|
||||||
from randomtrackingdict import RandomTrackingDict
|
from randomtrackingdict import RandomTrackingDict
|
||||||
|
@ -350,27 +351,27 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
|
||||||
self.pendingUpload[i] = now
|
self.pendingUpload[i] = now
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _command_inv(self, dandelion=False):
|
def _command_inv(self, extend_dandelion_stem=False):
|
||||||
"""
|
"""
|
||||||
Common inv announce implementation:
|
Common inv announce implementation:
|
||||||
both inv and dinv depending on *dandelion* kwarg
|
both inv and dinv depending on *extend_dandelion_stem* kwarg
|
||||||
"""
|
"""
|
||||||
items = self.decode_payload_content("l32s")
|
items = self.decode_payload_content("l32s")
|
||||||
|
|
||||||
if len(items) > protocol.MAX_OBJECT_COUNT:
|
if len(items) > protocol.MAX_OBJECT_COUNT:
|
||||||
logger.error(
|
logger.error(
|
||||||
'Too many items in %sinv message!', 'd' if dandelion else '')
|
'Too many items in %sinv message!', 'd' if extend_dandelion_stem else '')
|
||||||
raise BMProtoExcessiveDataError()
|
raise BMProtoExcessiveDataError()
|
||||||
|
|
||||||
# ignore dinv if dandelion turned off
|
# ignore dinv if dandelion turned off
|
||||||
if dandelion and not state.dandelion_enabled:
|
if extend_dandelion_stem and not state.dandelion_enabled:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
for i in items:
|
for i in items:
|
||||||
if i in state.Inventory and not state.Dandelion.hasHash(i):
|
if i in state.Inventory and not dandelion.instance.hasHash(i):
|
||||||
continue
|
continue
|
||||||
if dandelion and not state.Dandelion.hasHash(i):
|
if extend_dandelion_stem and not dandelion.instance.hasHash(i):
|
||||||
state.Dandelion.addHash(i, self)
|
dandelion.instance.addHash(i, self)
|
||||||
self.handleReceivedInventory(i)
|
self.handleReceivedInventory(i)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
@ -436,9 +437,9 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if self.object.inventoryHash in state.Inventory and state.Dandelion.hasHash(
|
if self.object.inventoryHash in state.Inventory and dandelion.instance.hasHash(
|
||||||
self.object.inventoryHash):
|
self.object.inventoryHash):
|
||||||
state.Dandelion.removeHash(
|
dandelion.instance.removeHash(
|
||||||
self.object.inventoryHash, "cycle detection")
|
self.object.inventoryHash, "cycle detection")
|
||||||
|
|
||||||
if six.PY2:
|
if six.PY2:
|
||||||
|
|
|
@ -194,3 +194,6 @@ class Dandelion: # pylint: disable=old-style-class
|
||||||
self.nodeMap = {}
|
self.nodeMap = {}
|
||||||
# hashMap stays to cater for pending stems
|
# hashMap stays to cater for pending stems
|
||||||
self.refresh = time() + REASSIGN_INTERVAL
|
self.refresh = time() + REASSIGN_INTERVAL
|
||||||
|
|
||||||
|
|
||||||
|
instance = Dandelion()
|
||||||
|
|
|
@ -10,6 +10,7 @@ import protocol
|
||||||
from network import connectionpool
|
from network import connectionpool
|
||||||
from .objectracker import missingObjects
|
from .objectracker import missingObjects
|
||||||
from .threads import StoppableThread
|
from .threads import StoppableThread
|
||||||
|
import dandelion
|
||||||
|
|
||||||
|
|
||||||
class DownloadThread(StoppableThread):
|
class DownloadThread(StoppableThread):
|
||||||
|
@ -60,7 +61,7 @@ class DownloadThread(StoppableThread):
|
||||||
payload = bytearray()
|
payload = bytearray()
|
||||||
chunkCount = 0
|
chunkCount = 0
|
||||||
for chunk in request:
|
for chunk in request:
|
||||||
if chunk in state.Inventory and not state.Dandelion.hasHash(chunk):
|
if chunk in state.Inventory and not dandelion.instance.hasHash(chunk):
|
||||||
try:
|
try:
|
||||||
del i.objectsNewToMe[chunk]
|
del i.objectsNewToMe[chunk]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|
|
@ -9,6 +9,7 @@ import addresses
|
||||||
import protocol
|
import protocol
|
||||||
import state
|
import state
|
||||||
from network import connectionpool
|
from network import connectionpool
|
||||||
|
import dandelion
|
||||||
from queues import invQueue
|
from queues import invQueue
|
||||||
from .threads import StoppableThread
|
from .threads import StoppableThread
|
||||||
|
|
||||||
|
@ -39,10 +40,10 @@ class InvThread(StoppableThread):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def handleLocallyGenerated(stream, hashId):
|
def handleLocallyGenerated(stream, hashId):
|
||||||
"""Locally generated inventory items require special handling"""
|
"""Locally generated inventory items require special handling"""
|
||||||
state.Dandelion.addHash(hashId, stream=stream)
|
dandelion.instance.addHash(hashId, stream=stream)
|
||||||
for connection in connectionpool.pool.connections():
|
for connection in connectionpool.pool.connections():
|
||||||
if state.dandelion_enabled and connection != \
|
if state.dandelion_enabled and connection != \
|
||||||
state.Dandelion.objectChildStem(hashId):
|
dandelion.instance.objectChildStem(hashId):
|
||||||
continue
|
continue
|
||||||
connection.objectsNewToThem[hashId] = time()
|
connection.objectsNewToThem[hashId] = time()
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ class InvThread(StoppableThread):
|
||||||
chunk = []
|
chunk = []
|
||||||
while True:
|
while True:
|
||||||
# Dandelion fluff trigger by expiration
|
# Dandelion fluff trigger by expiration
|
||||||
handleExpiredDandelion(state.Dandelion.expire())
|
handleExpiredDandelion(dandelion.instance.expire())
|
||||||
try:
|
try:
|
||||||
data = invQueue.get(False)
|
data = invQueue.get(False)
|
||||||
chunk.append((data[0], data[1]))
|
chunk.append((data[0], data[1]))
|
||||||
|
@ -74,7 +75,7 @@ class InvThread(StoppableThread):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
if connection == state.Dandelion.objectChildStem(inv[1]):
|
if connection == dandelion.instance.objectChildStem(inv[1]):
|
||||||
# Fluff trigger by RNG
|
# Fluff trigger by RNG
|
||||||
# auto-ignore if config set to 0, i.e. dandelion is off
|
# auto-ignore if config set to 0, i.e. dandelion is off
|
||||||
if random.randint(1, 100) >= state.dandelion_enabled: # nosec B311
|
if random.randint(1, 100) >= state.dandelion_enabled: # nosec B311
|
||||||
|
@ -104,7 +105,7 @@ class InvThread(StoppableThread):
|
||||||
for _ in range(len(chunk)):
|
for _ in range(len(chunk)):
|
||||||
invQueue.task_done()
|
invQueue.task_done()
|
||||||
|
|
||||||
if state.Dandelion.refresh < time():
|
if dandelion.instance.refresh < time():
|
||||||
state.Dandelion.reRandomiseStems()
|
dandelion.instance.reRandomiseStems()
|
||||||
|
|
||||||
self.stop.wait(1)
|
self.stop.wait(1)
|
||||||
|
|
|
@ -5,8 +5,8 @@ import time
|
||||||
from threading import RLock
|
from threading import RLock
|
||||||
import six
|
import six
|
||||||
|
|
||||||
import state
|
|
||||||
import network.connectionpool # use long name to address recursive import
|
import network.connectionpool # use long name to address recursive import
|
||||||
|
import dandelion
|
||||||
from randomtrackingdict import RandomTrackingDict
|
from randomtrackingdict import RandomTrackingDict
|
||||||
|
|
||||||
haveBloom = False
|
haveBloom = False
|
||||||
|
@ -111,14 +111,14 @@ class ObjectTracker(object):
|
||||||
del i.objectsNewToMe[hashid]
|
del i.objectsNewToMe[hashid]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
if streamNumber in i.streams and (
|
if streamNumber in i.streams and (
|
||||||
not state.Dandelion.hasHash(hashid)
|
not dandelion.instance.hasHash(hashid)
|
||||||
or state.Dandelion.objectChildStem(hashid) == i):
|
or dandelion.instance.objectChildStem(hashid) == i):
|
||||||
with i.objectsNewToThemLock:
|
with i.objectsNewToThemLock:
|
||||||
i.objectsNewToThem[hashid_bytes] = time.time()
|
i.objectsNewToThem[hashid_bytes] = time.time()
|
||||||
# update stream number,
|
# update stream number,
|
||||||
# which we didn't have when we just received the dinv
|
# which we didn't have when we just received the dinv
|
||||||
# also resets expiration of the stem mode
|
# also resets expiration of the stem mode
|
||||||
state.Dandelion.setHashStream(hashid, streamNumber)
|
dandelion.instance.setHashStream(hashid, streamNumber)
|
||||||
|
|
||||||
if i == self:
|
if i == self:
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -17,6 +17,7 @@ import l10n
|
||||||
import protocol
|
import protocol
|
||||||
import state
|
import state
|
||||||
import network.connectionpool # use long name to address recursive import
|
import network.connectionpool # use long name to address recursive import
|
||||||
|
import dandelion
|
||||||
from bmconfigparser import config
|
from bmconfigparser import config
|
||||||
from highlevelcrypto import randomBytes
|
from highlevelcrypto import randomBytes
|
||||||
from queues import invQueue, receiveDataQueue, UISignalQueue
|
from queues import invQueue, receiveDataQueue, UISignalQueue
|
||||||
|
@ -175,7 +176,7 @@ class TCPConnection(BMProto, TLSDispatcher):
|
||||||
knownnodes.increaseRating(self.destination)
|
knownnodes.increaseRating(self.destination)
|
||||||
knownnodes.addKnownNode(
|
knownnodes.addKnownNode(
|
||||||
self.streams, self.destination, time.time())
|
self.streams, self.destination, time.time())
|
||||||
state.Dandelion.maybeAddStem(self)
|
dandelion.instance.maybeAddStem(self)
|
||||||
self.sendAddr()
|
self.sendAddr()
|
||||||
self.sendBigInv()
|
self.sendBigInv()
|
||||||
|
|
||||||
|
@ -237,7 +238,7 @@ class TCPConnection(BMProto, TLSDispatcher):
|
||||||
with self.objectsNewToThemLock:
|
with self.objectsNewToThemLock:
|
||||||
for objHash in state.Inventory.unexpired_hashes_by_stream(stream):
|
for objHash in state.Inventory.unexpired_hashes_by_stream(stream):
|
||||||
# don't advertise stem objects on bigInv
|
# don't advertise stem objects on bigInv
|
||||||
if state.Dandelion.hasHash(objHash):
|
if dandelion.instance.hasHash(objHash):
|
||||||
continue
|
continue
|
||||||
bigInvList[objHash] = 0
|
bigInvList[objHash] = 0
|
||||||
objectCount = 0
|
objectCount = 0
|
||||||
|
@ -299,7 +300,7 @@ class TCPConnection(BMProto, TLSDispatcher):
|
||||||
if host_is_global:
|
if host_is_global:
|
||||||
knownnodes.addKnownNode(
|
knownnodes.addKnownNode(
|
||||||
self.streams, self.destination, time.time())
|
self.streams, self.destination, time.time())
|
||||||
state.Dandelion.maybeRemoveStem(self)
|
dandelion.instance.maybeRemoveStem(self)
|
||||||
else:
|
else:
|
||||||
self.checkTimeOffsetNotification()
|
self.checkTimeOffsetNotification()
|
||||||
if host_is_global:
|
if host_is_global:
|
||||||
|
|
|
@ -7,6 +7,7 @@ import helper_random
|
||||||
import protocol
|
import protocol
|
||||||
import state
|
import state
|
||||||
from network import connectionpool
|
from network import connectionpool
|
||||||
|
import dandelion
|
||||||
from randomtrackingdict import RandomTrackingDict
|
from randomtrackingdict import RandomTrackingDict
|
||||||
from .threads import StoppableThread
|
from .threads import StoppableThread
|
||||||
|
|
||||||
|
@ -40,8 +41,8 @@ class UploadThread(StoppableThread):
|
||||||
chunk_count = 0
|
chunk_count = 0
|
||||||
for chunk in request:
|
for chunk in request:
|
||||||
del i.pendingUpload[chunk]
|
del i.pendingUpload[chunk]
|
||||||
if state.Dandelion.hasHash(chunk) and \
|
if dandelion.instance.hasHash(chunk) and \
|
||||||
i != state.Dandelion.objectChildStem(chunk):
|
i != dandelion.instance.objectChildStem(chunk):
|
||||||
i.antiIntersectionDelay()
|
i.antiIntersectionDelay()
|
||||||
self.logger.info(
|
self.logger.info(
|
||||||
'%s asked for a stem object we didn\'t offer to it.',
|
'%s asked for a stem object we didn\'t offer to it.',
|
||||||
|
|
|
@ -96,6 +96,3 @@ class Placeholder(object): # pylint:disable=too-few-public-methods
|
||||||
|
|
||||||
|
|
||||||
Inventory = Placeholder("Inventory")
|
Inventory = Placeholder("Inventory")
|
||||||
|
|
||||||
|
|
||||||
Dandelion = Placeholder("Dandelion")
|
|
||||||
|
|
Reference in New Issue
Block a user