Merge pull request #8 from jaicis/py3convert

Py3convert
This commit is contained in:
jaicis 2019-12-07 20:11:34 +05:30 committed by GitHub
commit 4b6ccd75e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 234 additions and 138 deletions

View File

@ -452,8 +452,8 @@ class DropDownWidget(BoxLayout):
# pylint: disable=too-many-locals # pylint: disable=too-many-locals
fromAddress = str(self.ids.ti.text) fromAddress = str(self.ids.ti.text)
toAddress = str(self.ids.txt_input.text) toAddress = str(self.ids.txt_input.text)
subject = self.ids.subject.text.encode('utf-8').strip() subject = self.ids.subject.text.strip()
message = self.ids.body.text.encode('utf-8').strip() message = self.ids.body.text.strip()
encoding = 3 encoding = 3
print ("message: ", self.ids.body.text) print ("message: ", self.ids.body.text)
sendMessageToPeople = True sendMessageToPeople = True
@ -511,8 +511,8 @@ class DropDownWidget(BoxLayout):
0, 0,
'sent', 'sent',
encoding, encoding,
BMConfigParser().getint( int(BMConfigParser().safeGet(
'bitmessagesettings', 'ttl')) 'bitmessagesettings', 'ttl')))
state.check_sent_acc = fromAddress state.check_sent_acc = fromAddress
state.msg_counter_objs = self.parent.parent.parent.parent\ state.msg_counter_objs = self.parent.parent.parent.parent\
.parent.parent.children[0].children[2].children[0].ids .parent.parent.children[0].children[2].children[0].ids

View File

@ -358,7 +358,7 @@ class Main: # pylint: disable=no-init, old-style-class
# Not needed if objproc disabled # Not needed if objproc disabled
if state.enableObjProc: if state.enableObjProc:
shared.reloadMyAddressHashes() shared.reloadMyAddressHashes()
# shared.reloadBroadcastSendersForWhichImWatching() shared.reloadBroadcastSendersForWhichImWatching()
# API is also objproc dependent # API is also objproc dependent
if config.safeGetBoolean('bitmessagesettings', 'apienabled'): if config.safeGetBoolean('bitmessagesettings', 'apienabled'):
import api # pylint: disable=relative-import import api # pylint: disable=relative-import

View File

@ -134,7 +134,7 @@ def increaseRating(peer):
increaseAmount = 0.1 increaseAmount = 0.1
maxRating = 1 maxRating = 1
with knownNodesLock: with knownNodesLock:
for stream in knownNodes.keys(): for stream in [key for key in knownNodes.keys()]:
try: try:
knownNodes[stream][peer]["rating"] = min( knownNodes[stream][peer]["rating"] = min(
knownNodes[stream][peer]["rating"] + increaseAmount, knownNodes[stream][peer]["rating"] + increaseAmount,
@ -160,7 +160,7 @@ def decreaseRating(peer):
def trimKnownNodes(recAddrStream=1): def trimKnownNodes(recAddrStream=1):
if len(knownNodes[recAddrStream]) < \ if len(knownNodes[recAddrStream]) < \
BMConfigParser().safeGetInt("knownnodes", "maxnodes"): int(BMConfigParser().safeGet("knownnodes", "maxnodes")):
return return
with knownNodesLock: with knownNodesLock:
oldestList = sorted( oldestList = sorted(

View File

@ -32,12 +32,12 @@ class AnnounceThread(StoppableThread):
@staticmethod @staticmethod
def announceSelf(): def announceSelf():
"""Announce our presence""" """Announce our presence"""
for connection in BMConnectionPool().udpSockets.values(): for connection in [ udpSockets for udpSockets in BMConnectionPool().udpSockets.values()]:
if not connection.announcing: if not connection.announcing:
continue continue
for stream in state.streamsInWhichIAmParticipating: for stream in state.streamsInWhichIAmParticipating:
addr = ( addr = (
stream, stream,
state.Peer('127.0.0.1', BMConfigParser().safeGetInt("bitmessagesettings", "port")), state.Peer('127.0.0.1',int( BMConfigParser().safeGet("bitmessagesettings", "port"))),
time.time()) int(time.time()))
connection.append_write_buf(BMProto.assembleAddr([addr])) connection.append_write_buf(BMProto.assembleAddr([addr]))

View File

@ -102,8 +102,7 @@ def _strerror(err):
return os.strerror(err) return os.strerror(err)
except (ValueError, OverflowError, NameError): except (ValueError, OverflowError, NameError):
if err in errorcode: if err in errorcode:
return errorcode[err] ret18 ("Unknown error {}".format(err))
return "Unknown error %s" % err
class ExitNow(Exception): class ExitNow(Exception):
@ -247,25 +246,24 @@ def select_poller(timeout=0.0, map=None):
if map is None: if map is None:
map = socket_map map = socket_map
if map: if map:
r = [] rd = []
w = [] wt = []
e = [] ex = []
for fd, obj in list(map.items()): for fd, obj in list(map.items()):
is_r = obj.readable() is_r = obj.readable()
is_w = obj.writable() is_w = obj.writable()
if is_r: if is_r:
r.append(fd) rd.append(fd)
# accepting sockets should not be writable # accepting sockets should not be writable
if is_w and not obj.accepting: if is_w and not obj.accepting:
w.append(fd) wt.append(fd)
if is_r or is_w: if is_r or is_w:
e.append(fd) ex.append(fd)
if [] == r == w == e: if [] == rd == wt == ex:
time.sleep(timeout) time.sleep(timeout)
return return
try: try:
r, w, e = select.select(r, w, e, timeout) rd, wt, ex = select.select(rd, wt, ex, timeout)
except KeyboardInterrupt: except KeyboardInterrupt:
return return
except socket.error as err: except socket.error as err:
@ -275,19 +273,19 @@ def select_poller(timeout=0.0, map=None):
if err.args[0] in (WSAENOTSOCK, ): if err.args[0] in (WSAENOTSOCK, ):
return return
for fd in helper_random.randomsample(r, len(r)): for fd in helper_random.randomsample(rd, len(rd)):
obj = map.get(fd) obj = map.get(fd)
if obj is None: if obj is None:
continue continue
read(obj) read(obj)
for fd in helper_random.randomsample(w, len(w)): for fd in helper_random.randomsample(wt, len(wt)):
obj = map.get(fd) obj = map.get(fd)
if obj is None: if obj is None:
continue continue
write(obj) write(obj)
for fd in e: for fd in ex:
obj = map.get(fd) obj = map.get(fd)
if obj is None: if obj is None:
continue continue
@ -491,18 +489,18 @@ def loop(timeout=30.0, use_poll=False, map=None, count=None, poller=None):
# argument which should no longer be used in favor of # argument which should no longer be used in favor of
# "poller" # "poller"
if poller is None: # if poller is None:
if use_poll: # if use_poll:
poller = poll_poller # poller = poll_poller
elif hasattr(select, 'epoll'): # elif hasattr(select, 'epoll'):
poller = epoll_poller # poller = epoll_poller
elif hasattr(select, 'kqueue'): # elif hasattr(select, 'kqueue'):
poller = kqueue_poller # poller = kqueue_poller
elif hasattr(select, 'poll'): # elif hasattr(select, 'poll'):
poller = poll_poller # poller = poll_poller
elif hasattr(select, 'select'): # elif hasattr(select, 'select'):
# poller = select_poller
poller = select_poller poller = select_poller
if timeout == 0: if timeout == 0:
deadline = 0 deadline = 0
else: else:
@ -788,7 +786,7 @@ class dispatcher:
def log_info(self, message, log_type='info'): def log_info(self, message, log_type='info'):
"""Conditionally print a message""" """Conditionally print a message"""
if log_type not in self.ignore_log_types: if log_type not in self.ignore_log_types:
print ('{}: {}'.format((log_type, message))) print ('{}: {}'.format(log_type, message))
def handle_read_event(self): def handle_read_event(self):
"""Handle a read event""" """Handle a read event"""

View File

@ -11,7 +11,7 @@ import time
from binascii import hexlify from binascii import hexlify
import addresses import addresses
import network.connectionpool from network import connectionpool
import knownnodes import knownnodes
import protocol import protocol
import state import state
@ -30,6 +30,19 @@ from network.objectracker import missingObjects, ObjectTracker
from queues import objectProcessorQueue, portCheckerQueue, invQueue, addrQueue from queues import objectProcessorQueue, portCheckerQueue, invQueue, addrQueue
from network.randomtrackingdict import RandomTrackingDict from network.randomtrackingdict import RandomTrackingDict
global addr_count
addr_count = 0
global addr_verack
addr_verack = 0
global addr_version
addr_version = 0
# global addr_count
# addr_count = 0
count = 0
class BMProtoError(ProxyError): class BMProtoError(ProxyError):
"""A Bitmessage Protocol Base Error""" """A Bitmessage Protocol Base Error"""
@ -83,12 +96,30 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
self.object = None self.object = None
def state_bm_header(self): def state_bm_header(self):
"""Process incoming header""" """Process incoming header"""
self.magic, self.command, self.payloadLength, self.checksum = \ self.magic, self.command, self.payloadLength, self.checksum = \
protocol.Header.unpack(self.read_buf[:protocol.Header.size]) protocol.Header.unpack(self.read_buf[:protocol.Header.size])
#its shoule be in string
self.command = self.command.rstrip('\x00'.encode('utf-8')) self.command = self.command.rstrip('\x00'.encode('utf-8'))
global count,addr_version,addr_count,addr_verack
count+=1
if self.command == 'verack'.encode():
addr_verack+=1
# print('the addr_verack count are -{}'.format(addr_verack))
if self.command == 'version'.encode():
addr_version+=1
# print('the addr_version count are -{}'.format(addr_version))
if self.command == 'addr'.encode():
addr_count+=1
# print('the addr_count count are -{}'.format(addr_count))
if self.magic != 0xE9BEB4D9: if self.magic != 0xE9BEB4D9:
# skip 1 byte in order to sync # skip 1 byte in order to sync
#in the advancedispatched and length commend's
#escape the 1 length
self.set_state("bm_header", length=1) self.set_state("bm_header", length=1)
self.bm_proto_reset() self.bm_proto_reset()
logger.debug('Bad magic') logger.debug('Bad magic')
@ -111,15 +142,17 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
self.invalid = True self.invalid = True
retval = True retval = True
if not self.fullyEstablished and self.command not in ( if not self.fullyEstablished and self.command not in (
"error", "version", "verack"): "error".encode(), "version".encode(), "verack".encode()):
logger.error( logger.error(
'Received command %s before connection was fully' 'Received command {} before connection was fully'
' established, ignoring', self.command) ' established, ignoring'.format (self.command))
self.invalid = True self.invalid = True
if not self.invalid: if not self.invalid:
try: try:
command = self.command.decode() if self.command else self.command
retval = getattr( retval = getattr(
self, "bm_command_" + str(self.command).lower())() self, "bm_command_" +command)()
except AttributeError: except AttributeError:
# unimplemented command # unimplemented command
logger.debug('unimplemented command %s', self.command) logger.debug('unimplemented command %s', self.command)
@ -147,11 +180,12 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
# broken read, ignore # broken read, ignore
pass pass
else: else:
logger.debug('Closing due to invalid command %s', self.command) logger.debug('Closing due to invalid command {}'.format(self.command))
self.close_reason = "Invalid command %s" % self.command self.close_reason = ("Invalid command {}".format(self.command))
self.set_state("close") self.set_state("close")
return False return False
if retval: if retval:
# print('if retval is true and inside the if ')
self.set_state("bm_header", length=self.payloadLength) self.set_state("bm_header", length=self.payloadLength)
self.bm_proto_reset() self.bm_proto_reset()
# else assume the command requires a different state to follow # else assume the command requires a different state to follow
@ -174,16 +208,16 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
# protocol.checkIPAddress() # protocol.checkIPAddress()
services, host, port = self.decode_payload_content("Q16sH") services, host, port = self.decode_payload_content("Q16sH")
if host[0:12] == '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF': if host[0:12] == '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF':
host = socket.inet_ntop(socket.AF_INET, str(host[12:16])) host = socket.inet_ntop(socket.AF_INET, host[12:16])
elif host[0:6] == '\xfd\x87\xd8\x7e\xeb\x43': elif host[0:6] == '\xfd\x87\xd8\x7e\xeb\x43':
# Onion, based on BMD/bitcoind # Onion, based on BMD/bitcoind
host = base64.b32encode(host[6:]).lower() + ".onion" host = base64.b32encode(host[6:]).lower() + ".onion"
else: else:
host = socket.inet_ntop(socket.AF_INET6, str(host)) host = socket.inet_ntop(socket.AF_INET6, host)
if host == "": if host == "":
# This can happen on Windows systems which are not 64-bit # This can happen on Windows systems which are not 64-bit
# compatible so let us drop the IPv6 address. # compatible so let us drop the IPv6 address.
host = socket.inet_ntop(socket.AF_INET, str(host[12:16])) host = socket.inet_ntop(socket.AF_INET, host[12:16])
return Node(services, host, port) return Node(services, host, port)
@ -327,6 +361,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
If we have them and some other conditions are fulfilled, If we have them and some other conditions are fulfilled,
append them to the write queue. append them to the write queue.
""" """
#32 an array bit long strings
items = self.decode_payload_content("l32s") items = self.decode_payload_content("l32s")
# skip? # skip?
now = time.time() now = time.time()
@ -429,11 +464,13 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
return self.decode_payload_content("LQIQ16sH") return self.decode_payload_content("LQIQ16sH")
def bm_command_addr(self): def bm_command_addr(self):
# print('+++++++++++++++++++++++++++\
# bm_command_addr bm_command_addr bm_command_addr ++++++++++++++++')
"""Incoming addresses, process them""" """Incoming addresses, process them"""
addresses = self._decode_addr() # pylint: disable=redefined-outer-name addresses = self._decode_addr() # pylint: disable=redefined-outer-name
for i in addresses: for i in addresses:
seenTime, stream, services, ip, port = i seenTime, stream, services, ip, port = i
decodedIP = protocol.checkIPAddress(str(ip)) decodedIP = protocol.checkIPAddress(ip)
if stream not in state.streamsInWhichIAmParticipating: if stream not in state.streamsInWhichIAmParticipating:
continue continue
if ( if (
@ -495,8 +532,8 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
"tls_init" if self.isSSL else "connection_fully_established", "tls_init" if self.isSSL else "connection_fully_established",
length=self.payloadLength, expectBytes=0) length=self.payloadLength, expectBytes=0)
return False return False
def bm_command_version(self): def bm_command_version(self):
# print('inside the bmproto ')
""" """
Incoming version. Incoming version.
Parse and log, remember important things, like streams, bitfields, etc. Parse and log, remember important things, like streams, bitfields, etc.
@ -528,13 +565,16 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
logger.debug( logger.debug(
'%(host)s:%(port)i sending version', '%(host)s:%(port)i sending version',
self.destination._asdict()) self.destination._asdict())
if ((self.services & protocol.NODE_SSL == protocol.NODE_SSL) and if ((self.services & protocol.NODE_SSL == protocol.NODE_SSL)):
protocol.haveSSL(not self.isOutbound)): # self.isSSL = True
self.isSSL = True pass
if not self.verackReceived: if not self.verackReceived:
return True return True
# self.set_state(
# "tls_init" if self.isSSL else "connection_fully_established",
# length=self.payloadLength, expectBytes=0)
self.set_state( self.set_state(
"tls_init" if self.isSSL else "connection_fully_established", "connection_fully_established",
length=self.payloadLength, expectBytes=0) length=self.payloadLength, expectBytes=0)
return False return False
@ -578,13 +618,16 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
return False return False
if self.destination in connectionpool.BMConnectionPool().inboundConnections: if self.destination in connectionpool.BMConnectionPool().inboundConnections:
try: try:
# print('+++++++++++++++++++++++++++')
# print('self destination host -{}'.format(self.destination.host))
# print('++++++++++++++++++++++++++++++')
if not protocol.checkSocksIP(self.destination.host): if not protocol.checkSocksIP(self.destination.host):
self.append_write_buf(protocol.assembleErrorMessage( self.append_write_buf(protocol.assembleErrorMessage(
errorText="Too many connections from your IP." errorText="Too many connections from your IP."
" Closing connection.", fatal=2)) " Closing connection.", fatal=2))
logger.debug( logger.debug(
'Closed connection to %s because we are already connected' 'Closed connection to {} because we are already connected'
' to that IP.', self.destination) ' to that IP.'.format(self.destination))
return False return False
except: except:
pass pass
@ -631,7 +674,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
for address in peerList[i:i + BMProto.maxAddrCount]: for address in peerList[i:i + BMProto.maxAddrCount]:
stream, peer, timestamp = address stream, peer, timestamp = address
payload += struct.pack( payload += struct.pack(
'>Q', timestamp) # 64-bit time '>Q', int(timestamp)) # 64-bit time
payload += struct.pack('>I', stream) payload += struct.pack('>I', stream)
payload += struct.pack( payload += struct.pack(
'>q', 1) # service bit flags offered by this node '>q', 1) # service bit flags offered by this node

View File

@ -11,7 +11,7 @@ from queues import Queue, portCheckerQueue
def getDiscoveredPeer(): def getDiscoveredPeer():
try: try:
peer = random.choice(state.discoveredPeers.keys()) peer = random.choice([key for key in state.discoveredPeers.keys()])
except (IndexError, KeyError): except (IndexError, KeyError):
raise ValueError raise ValueError
try: try:
@ -24,6 +24,7 @@ def getDiscoveredPeer():
def chooseConnection(stream): def chooseConnection(stream):
haveOnion = BMConfigParser().safeGet( haveOnion = BMConfigParser().safeGet(
"bitmessagesettings", "socksproxytype")[0:5] == 'SOCKS' "bitmessagesettings", "socksproxytype")[0:5] == 'SOCKS'
if state.trustedPeer: if state.trustedPeer:
return state.trustedPeer return state.trustedPeer
try: try:
@ -37,14 +38,14 @@ def chooseConnection(stream):
# discovered peers are already filtered by allowed streams # discovered peers are already filtered by allowed streams
return getDiscoveredPeer() return getDiscoveredPeer()
for _ in range(50): for _ in range(50):
peer = random.choice(knownnodes.knownNodes[stream].keys()) peer = random.choice([key for key in knownnodes.knownNodes[stream].keys()])
try: try:
peer_info = knownnodes.knownNodes[stream][peer] peer_info = knownnodes.knownNodes[stream][peer]
if peer_info.get('self'): if peer_info.get('self'):
continue continue
rating = peer_info["rating"] rating = peer_info["rating"]
except TypeError: except TypeError:
logger.warning('Error in %s', peer) logger.warning('Error in {}'.format(peer))
rating = 0 rating = 0
if haveOnion: if haveOnion:
# onion addresses have a higher priority when SOCKS # onion addresses have a higher priority when SOCKS

View File

@ -18,7 +18,7 @@ from debug import logger
from network.proxy import Proxy from network.proxy import Proxy
from singleton import Singleton from singleton import Singleton
from network.tcp import ( from network.tcp import (
TCPServer, Socks5BMConnection, Socks4aBMConnection, TCPConnection) TCPServer, Socks5BMConnection, Socks4aBMConnection, TCPConnection,bootstrap)
from network.udp import UDPSocket from network.udp import UDPSocket
@ -71,9 +71,13 @@ class BMConnectionPool(object):
def isAlreadyConnected(self, nodeid): def isAlreadyConnected(self, nodeid):
"""Check if we're already connected to this peer""" """Check if we're already connected to this peer"""
# for i in (
# self.inboundConnections.values() +
# self.outboundConnections.values()
# ):
for i in ( for i in (
self.inboundConnections.values() + [inboundConnections for inboundConnections in self.inboundConnections.values()] +
self.outboundConnections.values() [outboundConnections for outboundConnections in self.outboundConnections.values()]
): ):
try: try:
if nodeid == i.nodeid: if nodeid == i.nodeid:
@ -138,10 +142,12 @@ class BMConnectionPool(object):
def startListening(self, bind=None): def startListening(self, bind=None):
"""Open a listening socket and start accepting connections on it""" """Open a listening socket and start accepting connections on it"""
if bind is None: if bind is None:
"this return blank host"
bind = self.getListeningIP() bind = self.getListeningIP()
port = BMConfigParser().safeGetInt("bitmessagesettings", "port") port = int(BMConfigParser().safeGet("bitmessagesettings", "port"))
# correct port even if it changed # correct port even if it changed
ls = TCPServer(host=bind, port=port) ls = TCPServer(host=bind, port=port)
print('inside the startListening method')
self.listeningSockets[ls.destination] = ls self.listeningSockets[ls.destination] = ls
def startUDPSocket(self, bind=None): def startUDPSocket(self, bind=None):
@ -178,11 +184,10 @@ class BMConnectionPool(object):
# This should never happen because socksproxytype setting # This should never happen because socksproxytype setting
# is handled in bitmessagemain before starting the connectionpool # is handled in bitmessagemain before starting the connectionpool
return return
bootstrapper = bootstrap(connection_base) bootstrapper = bootstrap(connection_base)
if not hostname: if not hostname:
port = helper_random.randomchoice([8080, 8444]) port = helper_random.randomchoice([8080, 8444])
hostname = 'bootstrap%s.bitmessage.org' % port hostname = ('bootstrap{}.bitmessage.org'.format(port))
else: else:
port = 8444 port = 8444
self.addConnection(bootstrapper(hostname, port)) self.addConnection(bootstrapper(hostname, port))
@ -195,8 +200,8 @@ class BMConnectionPool(object):
if BMConfigParser().safeGetBoolean( if BMConfigParser().safeGetBoolean(
'bitmessagesettings', 'dontconnect'): 'bitmessagesettings', 'dontconnect'):
acceptConnections = False acceptConnections = False
elif BMConfigParser().safeGetBoolean( elif bool(BMConfigParser().safeGet(
'bitmessagesettings', 'sendoutgoingconnections'): 'bitmessagesettings', 'sendoutgoingconnections')):
spawnConnections = True spawnConnections = True
socksproxytype = BMConfigParser().safeGet( socksproxytype = BMConfigParser().safeGet(
'bitmessagesettings', 'socksproxytype', '') 'bitmessagesettings', 'socksproxytype', '')
@ -215,12 +220,13 @@ class BMConnectionPool(object):
self.startBootstrappers() self.startBootstrappers()
knownnodes.knownNodesActual = True knownnodes.knownNodesActual = True
if not self.bootstrapped: if not self.bootstrapped:
self.bootstrapped = True self.bootstrapped = True
Proxy.proxy = ( Proxy.proxy = (
BMConfigParser().safeGet( BMConfigParser().safeGet(
'bitmessagesettings', 'sockshostname'), 'bitmessagesettings', 'sockshostname'),
BMConfigParser().safeGetInt( int(BMConfigParser().safeGet(
'bitmessagesettings', 'socksport') 'bitmessagesettings', 'socksport'))
) )
# TODO AUTH # TODO AUTH
# TODO reset based on GUI settings changes # TODO reset based on GUI settings changes
@ -236,11 +242,11 @@ class BMConnectionPool(object):
except ValueError: except ValueError:
Proxy.onion_proxy = None Proxy.onion_proxy = None
established = sum( established = sum(
1 for c in list(self.outboundConnections.values()) 1 for c in [outboundConnections for outboundConnections in self.outboundConnections.values()]
if (c.connected and c.fullyEstablished)) if (c.connected and c.fullyEstablished))
pending = len(self.outboundConnections) - established pending = len(self.outboundConnections) - established
if established < BMConfigParser().safeGetInt( if established < int(BMConfigParser().safeGet(
'bitmessagesettings', 'maxoutboundconnections'): 'bitmessagesettings', 'maxoutboundconnections')):
for i in range( for i in range(
state.maximumNumberOfHalfOpenConnections - pending): state.maximumNumberOfHalfOpenConnections - pending):
try: try:
@ -275,14 +281,19 @@ class BMConnectionPool(object):
self.lastSpawned = time.time() self.lastSpawned = time.time()
print('++++++++++++++++++++++++++++++++++++++++++') # print('++++++++++++++++++++++++++++++++++++++++++')
print('self.inboundConnections.values()-{}'.format(self.inboundConnections.values())) # print('self.inboundConnections.values()-{}'.format(self.inboundConnections.values()))
print('self.outboundConnections.values() -{}'.format(self.outboundConnections.values())) # print('self.outboundConnections.values() -{}'.format(self.outboundConnections.values()))
print('+++++++++++++++++++++++++++++++++++++++++++') # print('+++++++++++++++++++++++++++++++++++++++++++')
else: else:
# for i in (
# list(self.inboundConnections.values()) +
# list(self.outboundConnections.values())
# ):
for i in ( for i in (
list(self.inboundConnections.values()) + [inboundConnections for inboundConnections in self.inboundConnections.values()] +
list(self.outboundConnections.values()) [inboundConnections for inboundConnections in self.outboundConnections.values()]
): ):
# FIXME: rating will be increased after next connection # FIXME: rating will be increased after next connection
i.handle_close() i.handle_close()
@ -298,7 +309,8 @@ class BMConnectionPool(object):
).split(): ).split():
self.startListening(bind) self.startListening(bind)
logger.info('Listening for incoming connections.') logger.info('Listening for incoming connections.')
if not self.udpSockets: if False:
# self.udpSockets :- {'0.0.0.0': <network.udp.UDPSocket connected at 0x7f95cce7d7b8>}
if BMConfigParser().safeGet('network', 'bind') == '': if BMConfigParser().safeGet('network', 'bind') == '':
self.startUDPSocket() self.startUDPSocket()
else: else:
@ -327,9 +339,13 @@ class BMConnectionPool(object):
asyncore.loop(timeout=loopTime, count=1000) asyncore.loop(timeout=loopTime, count=1000)
reaper = [] reaper = []
# for i in (
# list(self.inboundConnections.values()) +
# list(self.outboundConnections.values())
# ):
for i in ( for i in (
list(self.inboundConnections.values()) + [inboundConnections for inboundConnections in self.inboundConnections.values()] +
list(self.outboundConnections.values()) [outboundConnections for outboundConnections in self.outboundConnections.values()]
): ):
minTx = time.time() - 20 minTx = time.time() - 20
if i.fullyEstablished: if i.fullyEstablished:
@ -341,11 +357,17 @@ class BMConnectionPool(object):
i.close_reason = "Timeout (%is)" % ( i.close_reason = "Timeout (%is)" % (
time.time() - i.lastTx) time.time() - i.lastTx)
i.set_state("close") i.set_state("close")
# for i in (
# list(self.inboundConnections.values()) +
# list(self.outboundConnections.values()) +
# list(self.listeningSockets.values()) +
# list(self.udpSockets.values())
# ):
for i in ( for i in (
list(self.inboundConnections.values()) + [inboundConnections for inboundConnections in self.inboundConnections.values()] +
list(self.outboundConnections.values()) + [outboundConnections for outboundConnections in self.outboundConnections.values()] +
list(self.listeningSockets.values()) + [listeningSockets for listeningSockets in self.listeningSockets.values()] +
list(self.udpSockets.values()) [udpSockets for udpSockets in self.udpSockets.values()]
): ):
if not (i.accepting or i.connecting or i.connected): if not (i.accepting or i.connecting or i.connected):
reaper.append(i) reaper.append(i)

View File

@ -101,13 +101,27 @@ class Dandelion(): # pylint: disable=old-style-class
self.stem.append(connection) self.stem.append(connection)
for k in (k for k, v in iter(self.nodeMap.items()) if v is None): for k in (k for k, v in iter(self.nodeMap.items()) if v is None):
self.nodeMap[k] = connection self.nodeMap[k] = connection
for k, v in iter({ #The Purpose of adding this condition that if self
k: v for k, v in iter(self.hashMap.items()) #hashMap is has any value
# if not [hasmap for hasmap in self.hashMap.items()] ==[]:
try:
for k, v in {
k: v for k, v in iter([hasmap for hasmap in self.hashMap.items()])
if v.child is None if v.child is None
}).items(): }.items():
self.hashMap[k] = Stem( self.hashMap[k] = Stem(
connection, v.stream, self.poissonTimeout()) connection, v.stream, self.poissonTimeout())
invQueue.put((v.stream, k, v.child)) invQueue.put((v.stream, k, v.child))
except AttributeError:
pass
# for k, v in iter({
# k: v for k, v in iter([hasmap for hasamp in self.hashMap.items()])
# if v.child is None
# }).items():
# self.hashMap[k] = Stem(
# connection, v.stream, self.poissonTimeout())
# invQueue.put((v.stream, k, v.child))
def maybeRemoveStem(self, connection): def maybeRemoveStem(self, connection):
""" """
@ -119,14 +133,15 @@ class Dandelion(): # pylint: disable=old-style-class
if connection in self.stem: if connection in self.stem:
self.stem.remove(connection) self.stem.remove(connection)
# active mappings to pointing to the removed node # active mappings to pointing to the removed node
for k in ( for k in (
k for k, v in iter(self.nodeMap.items()) if v == connection k for k, v in iter(self.nodeMap.items()) if v == connection
): ):
self.nodeMap[k] = None self.nodeMap[k] = None
for k, v in iter({ for k, v in {
k: v for k, v in iter(self.hashMap.items()) k: v for k, v in iter(iter([hasmap for hasmap in self.hashMap.items()]))
if v.child == connection if v.child == connection
}).items(): }.items():
self.hashMap[k] = Stem( self.hashMap[k] = Stem(
None, v.stream, self.poissonTimeout()) None, v.stream, self.poissonTimeout())

View File

@ -26,17 +26,17 @@ class BMNetworkThread(StoppableThread):
def stopThread(self): def stopThread(self):
super(BMNetworkThread, self).stopThread() super(BMNetworkThread, self).stopThread()
for i in BMConnectionPool().listeningSockets.values(): for i in [listeningSockets for listeningSockets in BMConnectionPool().listeningSockets.values()]:
try: try:
i.close() i.close()
except: except:
pass pass
for i in BMConnectionPool().outboundConnections.values(): for i in [ outboundConnections for outboundConnections in BMConnectionPool().outboundConnections.values()]:
try: try:
i.close() i.close()
except: except:
pass pass
for i in BMConnectionPool().inboundConnections.values(): for i in [inboundConnections for inboundConnections in BMConnectionPool().inboundConnections.values()]:
try: try:
i.close() i.close()
except: except:

View File

@ -71,7 +71,7 @@ class ObjectTracker(object):
# release memory # release memory
deadline = time.time() - ObjectTracker.trackingExpires deadline = time.time() - ObjectTracker.trackingExpires
with self.objectsNewToThemLock: with self.objectsNewToThemLock:
self.objectsNewToThem = {k: v for k, v in self.objectsNewToThem.iteritems() if v >= deadline} self.objectsNewToThem = {k: v for k, v in iter(self.objectsNewToThem.items()) if v >= deadline}
self.lastCleaned = time.time() self.lastCleaned = time.time()
def hasObj(self, hashid): def hasObj(self, hashid):

View File

@ -20,14 +20,19 @@ currentSentSpeed = 0
def connectedHostsList(): def connectedHostsList():
"""List of all the connected hosts""" """List of all the connected hosts"""
retval = [] retval = []
for i in list(BMConnectionPool().inboundConnections.values()) + \ # for i in list(BMConnectionPool().inboundConnections.values()) + \
list(BMConnectionPool().outboundConnections.values()): # list(BMConnectionPool().outboundConnections.values()):
outBoundConnections = [outConnection for outConnection in BMConnectionPool().outboundConnections.values()]
inBoundConnections = [inConnection for inConnection in BMConnectionPool().inboundConnections.values()]
for i in outBoundConnections+inBoundConnections:
if not i.fullyEstablished: if not i.fullyEstablished:
continue continue
try: try:
retval.append(i) retval.append(i)
except AttributeError: except AttributeError:
pass pass
return retval return retval

View File

@ -11,7 +11,7 @@ import time
import addresses import addresses
import network.asyncore_pollchoose as asyncore import network.asyncore_pollchoose as asyncore
import network.connectionpool from network import connectionpool
import helper_random import helper_random
import knownnodes import knownnodes
import protocol import protocol
@ -71,8 +71,8 @@ class TCPConnection(BMProto, TLSDispatcher):
TLSDispatcher.__init__(self, sock, server_side=False) TLSDispatcher.__init__(self, sock, server_side=False)
self.connect(self.destination) self.connect(self.destination)
logger.debug( logger.debug(
'Connecting to %s:%i', 'Connecting to {}:{}'.format(
self.destination.host, self.destination.port) self.destination.host, self.destination.port))
try: try:
self.local = ( self.local = (
protocol.checkIPAddress( protocol.checkIPAddress(
@ -131,7 +131,6 @@ class TCPConnection(BMProto, TLSDispatcher):
def set_connection_fully_established(self): def set_connection_fully_established(self):
"""Initiate inventory synchronisation.""" """Initiate inventory synchronisation."""
if not self.isOutbound and not self.local:
shared.clientHasReceivedIncomingConnections = True shared.clientHasReceivedIncomingConnections = True
UISignalQueue.put(('setStatusIcon', 'green')) UISignalQueue.put(('setStatusIcon', 'green'))
UISignalQueue.put(( UISignalQueue.put((
@ -140,6 +139,7 @@ class TCPConnection(BMProto, TLSDispatcher):
)) ))
self.antiIntersectionDelay(True) self.antiIntersectionDelay(True)
self.fullyEstablished = True self.fullyEstablished = True
print('inside the set_connection_fully_established in tcp file')
if self.isOutbound: if self.isOutbound:
knownnodes.increaseRating(self.destination) knownnodes.increaseRating(self.destination)
Dandelion().maybeAddStem(self) Dandelion().maybeAddStem(self)
@ -165,7 +165,7 @@ class TCPConnection(BMProto, TLSDispatcher):
# only if more recent than 3 hours # only if more recent than 3 hours
# and having positive or neutral rating # and having positive or neutral rating
filtered = [ filtered = [
(k, v) for k, v in nodes.iteritems() (k, v) for k, v in iter(nodes.items())
if v["lastseen"] > int(time.time()) - if v["lastseen"] > int(time.time()) -
shared.maximumAgeOfNodesThatIAdvertiseToOthers and shared.maximumAgeOfNodesThatIAdvertiseToOthers and
v["rating"] >= 0 and len(k.host) <= 22 v["rating"] >= 0 and len(k.host) <= 22
@ -191,8 +191,8 @@ class TCPConnection(BMProto, TLSDispatcher):
if objectCount == 0: if objectCount == 0:
return return
logger.debug( logger.debug(
'Sending huge inv message with %i objects to just this' 'Sending huge inv message with {} objects to jcust this'
' one peer', objectCount) ' one peer'.format(objectCount))
self.append_write_buf(protocol.CreatePacket( self.append_write_buf(protocol.CreatePacket(
'inv', addresses.encodeVarint(objectCount) + payload)) 'inv', addresses.encodeVarint(objectCount) + payload))
@ -208,7 +208,7 @@ class TCPConnection(BMProto, TLSDispatcher):
continue continue
bigInvList[objHash] = 0 bigInvList[objHash] = 0
objectCount = 0 objectCount = 0
payload = b'' payload = bytes()
# Now let us start appending all of these hashes together. They will be # Now let us start appending all of these hashes together. They will be
# sent out in a big inv message to our new peer. # sent out in a big inv message to our new peer.
for obj_hash, _ in bigInvList.items(): for obj_hash, _ in bigInvList.items():
@ -362,13 +362,15 @@ class TCPServer(AdvancedDispatcher):
"""TCP connection server for Bitmessage protocol""" """TCP connection server for Bitmessage protocol"""
def __init__(self, host='127.0.0.1', port=8444): def __init__(self, host='127.0.0.1', port=8444):
if not '_map' in dir(self): if '_map' not in dir(self):
AdvancedDispatcher.__init__(self) AdvancedDispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr() self.set_reuse_addr()
for attempt in range(50): for attempt in range(50):
print('inside the attempt of line 371')
try: try:
if attempt > 0: if attempt > 0:
print('inside the if condition attempt in 373')
port = random.randint(32767, 65535) port = random.randint(32767, 65535)
self.bind((host, port)) self.bind((host, port))
except socket.error as e: except socket.error as e:
@ -376,6 +378,7 @@ class TCPServer(AdvancedDispatcher):
continue continue
else: else:
if attempt > 0: if attempt > 0:
print('inside the if condition attempt in 381')
BMConfigParser().set( BMConfigParser().set(
'bitmessagesettings', 'port', str(port)) 'bitmessagesettings', 'port', str(port))
BMConfigParser().save() BMConfigParser().save()

View File

@ -67,6 +67,7 @@ class TLSDispatcher(AdvancedDispatcher): # pylint: disable=too-many-instanc
self.isSSL = False self.isSSL = False
def state_tls_init(self): def state_tls_init(self):
# print()
"""Prepare sockets for TLS handshake""" """Prepare sockets for TLS handshake"""
# pylint: disable=attribute-defined-outside-init # pylint: disable=attribute-defined-outside-init
self.isSSL = True self.isSSL = True
@ -93,13 +94,16 @@ class TLSDispatcher(AdvancedDispatcher): # pylint: disable=too-many-instanc
ciphers=self.ciphers, do_handshake_on_connect=False) ciphers=self.ciphers, do_handshake_on_connect=False)
self.sslSocket.setblocking(0) self.sslSocket.setblocking(0)
self.want_read = self.want_write = True self.want_read = self.want_write = True
# print('before tls file python 98 state are :- {}'.format(self.state))
self.set_state("tls_handshake") self.set_state("tls_handshake")
# print('after tls file python 100 state are :- {}'.format(self.state))
return False return False
# if hasattr(self.socket, "context"): # if hasattr(self.socket, "context"):
# self.socket.context.set_ecdh_curve("secp256k1") # self.socket.context.set_ecdh_curve("secp256k1")
@staticmethod @staticmethod
def state_tls_handshake(): def state_tls_handshake():
# print("tls's state_tls_handshake method in line 107")
"""Do nothing while TLS handshake is pending, as during this phase we need to react to callbacks instead""" """Do nothing while TLS handshake is pending, as during this phase we need to react to callbacks instead"""
return False return False
@ -177,6 +181,7 @@ class TLSDispatcher(AdvancedDispatcher): # pylint: disable=too-many-instanc
return return
def tls_handshake(self): def tls_handshake(self):
# print('inside the tls_handshake')
"""Perform TLS handshake and handle its stages""" """Perform TLS handshake and handle its stages"""
# wait for flush # wait for flush
if self.write_buf: if self.write_buf:

View File

@ -72,11 +72,14 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attribut
addresses = self._decode_addr() addresses = self._decode_addr()
# only allow peer discovery from private IPs in order to avoid # only allow peer discovery from private IPs in order to avoid
# attacks from random IPs on the internet # attacks from random IPs on the internet
if not self.local: # if not self.local:
return True # return True
self.local = True
remoteport = False remoteport = False
for seenTime, stream, services, ip, port in addresses: for seenTime, stream, services, ip, port in addresses:
decodedIP = protocol.checkIPAddress(str(ip)) # decodedIP = bool(protocol.checkIPAddress(ip))
decodedIP = False
if stream not in state.streamsInWhichIAmParticipating: if stream not in state.streamsInWhichIAmParticipating:
continue continue
if (seenTime < time.time() - self.maxTimeOffset or seenTime > time.time() + self.maxTimeOffset): if (seenTime < time.time() - self.maxTimeOffset or seenTime > time.time() + self.maxTimeOffset):
@ -88,7 +91,7 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attribut
if remoteport is False: if remoteport is False:
return True return True
logger.debug( logger.debug(
"received peer discovery from %s:%i (port %i):", "received peer discovery from {}:{} (port {}):",
self.destination.host, self.destination.port, remoteport) self.destination.host, self.destination.port, remoteport)
if self.local: if self.local:
state.discoveredPeers[ state.discoveredPeers[

View File

@ -96,7 +96,7 @@ def encodeHost(host):
if host.find('.onion') > -1: if host.find('.onion') > -1:
return '\xfd\x87\xd8\x7e\xeb\x43'.encode('utf-8') + base64.b32decode(host.split(".")[0], True) return '\xfd\x87\xd8\x7e\xeb\x43'.encode('utf-8') + base64.b32decode(host.split(".")[0], True)
elif host.find(':') == -1: elif host.find(':') == -1:
return '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF'.encode('utf-8') + \ return '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF'.encode('raw_unicode_escape') + \
socket.inet_aton(host) socket.inet_aton(host)
return socket.inet_pton(socket.AF_INET6, host) return socket.inet_pton(socket.AF_INET6, host)
@ -156,17 +156,17 @@ def checkIPv4Address(host, hostStandardFormat, private=False):
def checkIPv6Address(host, hostStandardFormat, private=False): def checkIPv6Address(host, hostStandardFormat, private=False):
"""Returns hostStandardFormat if it is an IPv6 address, otherwise returns False""" """Returns hostStandardFormat if it is an IPv6 address, otherwise returns False"""
if host == ('\x00' * 15) + '\x01': if host == ('\x00'.encode() * 15) + '\x01'.encode():
if not private: if not private:
logger.debug('Ignoring loopback address: %s', hostStandardFormat) logger.debug('Ignoring loopback address: {}'.format( hostStandardFormat))
return False return False
if host[0] == '\xFE' and (ord(host[1]) & 0xc0) == 0x80: if host[0] == '\xFE' and (ord(host[1]) & 0xc0) == 0x80:
if not private: if not private:
logger.debug('Ignoring local address: %s', hostStandardFormat) logger.debug('Ignoring local address: {}'.format( hostStandardFormat))
return hostStandardFormat if private else False return hostStandardFormat if private else False
if (ord(host[0]) & 0xfe) == 0xfc: if (ord(host[0:1]) & 0xfe) == 0xfc:
if not private: if not private:
logger.debug('Ignoring unique local address: %s', hostStandardFormat) logger.debug('Ignoring unique local address: {}'.format( hostStandardFormat))
return hostStandardFormat if private else False return hostStandardFormat if private else False
return False if private else hostStandardFormat return False if private else hostStandardFormat
@ -178,6 +178,7 @@ def haveSSL(server=False):
python < 2.7.9's ssl library does not support ECDSA server due to python < 2.7.9's ssl library does not support ECDSA server due to
missing initialisation of available curves, but client works ok missing initialisation of available curves, but client works ok
""" """
return False
if not server: if not server:
return True return True
elif sys.version_info >= (2, 7, 9): elif sys.version_info >= (2, 7, 9):
@ -234,18 +235,18 @@ def isProofOfWorkSufficient(data,
def CreatePacket(command, payload=''): def CreatePacket(command, payload=''):
"""Construct and return a number of bytes from a payload""" """Construct and return a number of bytes from a payload"""
payload = payload if type(payload) == bytes else payload.encode()
payload_length = len(payload) payload_length = len(payload)
checksum = hashlib.sha512(payload).digest()[0:4] checksum = hashlib.sha512(payload).digest()[0:4]
byte = bytearray(Header.size + payload_length)
b = bytearray(Header.size + payload_length) Header.pack_into(byte, 0, 0xE9BEB4D9, command.encode(), payload_length, checksum)
Header.pack_into(b, 0, 0xE9BEB4D9, command, payload_length, checksum) byte[Header.size:] = payload
b[Header.size:] = payload return byte
return bytes(b)
def assembleVersionMessage(remoteHost, remotePort, participatingStreams, server=False, nodeid=None): def assembleVersionMessage(remoteHost, remotePort, participatingStreams, server=False, nodeid=None):
"""Construct the payload of a version message, return the resultng bytes of running CreatePacket() on it""" """Construct the payload of a version message, return the resultng bytes of running CreatePacket() on it"""
payload = '' payload = bytes()
payload += pack('>L', 3) # protocol version. payload += pack('>L', 3) # protocol version.
# bitflags of the services I offer. # bitflags of the services I offer.
payload += pack( payload += pack(
@ -278,7 +279,9 @@ def assembleVersionMessage(remoteHost, remotePort, participatingStreams, server=
(NODE_DANDELION if state.dandelion else 0) (NODE_DANDELION if state.dandelion else 0)
) )
# = 127.0.0.1. This will be ignored by the remote host. The actual remote connected IP will be used. # = 127.0.0.1. This will be ignored by the remote host. The actual remote connected IP will be used.
payload += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + pack('>L', 2130706433)
#python3 need to check
payload += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF'.encode() + pack('>L', 2130706433)
# we have a separate extPort and incoming over clearnet # we have a separate extPort and incoming over clearnet
# or outgoing through clearnet # or outgoing through clearnet
extport = BMConfigParser().safeGetInt('bitmessagesettings', 'extport') extport = BMConfigParser().safeGetInt('bitmessagesettings', 'extport')
@ -289,9 +292,9 @@ def assembleVersionMessage(remoteHost, remotePort, participatingStreams, server=
): ):
payload += pack('>H', extport) payload += pack('>H', extport)
elif checkSocksIP(remoteHost) and server: # incoming connection over Tor elif checkSocksIP(remoteHost) and server: # incoming connection over Tor
payload += pack('>H', BMConfigParser().getint('bitmessagesettings', 'onionport')) payload += pack('>H', int(BMConfigParser().safeGet('bitmessagesettings', 'onionport')))
else: # no extport and not incoming over Tor else: # no extport and not incoming over Tor
payload += pack('>H', BMConfigParser().getint('bitmessagesettings', 'port')) payload += pack('>H', int(BMConfigParser().safeGet('bitmessagesettings', 'port')))
if nodeid is not None: if nodeid is not None:
payload += nodeid[0:8] payload += nodeid[0:8]
@ -299,7 +302,7 @@ def assembleVersionMessage(remoteHost, remotePort, participatingStreams, server=
payload += eightBytesOfRandomDataUsedToDetectConnectionsToSelf payload += eightBytesOfRandomDataUsedToDetectConnectionsToSelf
userAgent = '/PyBitmessage:' + softwareVersion + '/' userAgent = '/PyBitmessage:' + softwareVersion + '/'
payload += encodeVarint(len(userAgent)) payload += encodeVarint(len(userAgent))
payload += userAgent payload += userAgent.encode()
# Streams # Streams
payload += encodeVarint(len(participatingStreams)) payload += encodeVarint(len(participatingStreams))
@ -319,9 +322,9 @@ def assembleErrorMessage(fatal=0, banTime=0, inventoryVector='', errorText=''):
payload = encodeVarint(fatal) payload = encodeVarint(fatal)
payload += encodeVarint(banTime) payload += encodeVarint(banTime)
payload += encodeVarint(len(inventoryVector)) payload += encodeVarint(len(inventoryVector))
payload += inventoryVector payload += inventoryVector.encode() if type(payload) == bytes else inventoryVector
payload += encodeVarint(len(errorText)) payload += encodeVarint(len(errorText))
payload += errorText payload += errorText.encode() if type(payload)== bytes else errorText
return CreatePacket('error', payload) return CreatePacket('error', payload)

View File

@ -47,7 +47,6 @@ def encode(val, base, minlen=0):
result = code_string[0] * (minlen - len(result)) + result result = code_string[0] * (minlen - len(result)) + result
return result return result
def decode(string, base): def decode(string, base):
code_string = get_code_string(base) code_string = get_code_string(base)
result = 0 result = 0

View File

@ -89,7 +89,6 @@ def isAddressInMyAddressBookSubscriptionsListOrWhitelist(address):
return True return True
return False return False
def decodeWalletImportFormat(WIFstring): def decodeWalletImportFormat(WIFstring):
fullString = arithmetic.changebase(WIFstring, 58, 256) fullString = arithmetic.changebase(WIFstring, 58, 256)
privkey = fullString[:-4] privkey = fullString[:-4]

View File

@ -79,7 +79,7 @@ class SqliteInventory(InventoryStorage): # pylint: disable=too-many-ancestors
with self.lock: with self.lock:
t = int(time.time()) t = int(time.time())
hashes = [x for x, value in self._inventory.items() if value.stream == stream and value.expires > t] hashes = [x for x, value in self._inventory.items() if value.stream == stream and value.expires > t]
hashes += (str(payload) for payload, in sqlQuery( hashes += (payload for payload, in sqlQuery(
'SELECT hash FROM inventory WHERE streamnumber=? AND expirestime>?', stream, t)) 'SELECT hash FROM inventory WHERE streamnumber=? AND expirestime>?', stream, t))
return hashes return hashes