Changes based on style and lint checks. (final_code_quality_19) #1401

Closed
coffeedogs wants to merge 1 commits from final_code_quality_19 into v0.6
3 changed files with 61 additions and 75 deletions

View File

@ -1,14 +1,19 @@
"""
src/network/dandelion.py
========================
"""
from collections import namedtuple from collections import namedtuple
from random import choice, sample, expovariate from random import choice, expovariate, sample
from threading import RLock from threading import RLock
from time import time from time import time
from bmconfigparser import BMConfigParser
import network.connectionpool import network.connectionpool
import state
from debug import logging from debug import logging
from queues import invQueue from queues import invQueue
from singleton import Singleton from singleton import Singleton
import state
# randomise routes after 600 seconds # randomise routes after 600 seconds
REASSIGN_INTERVAL = 600 REASSIGN_INTERVAL = 600
@ -21,8 +26,12 @@ MAX_STEMS = 2
Stem = namedtuple('Stem', ['child', 'stream', 'timeout']) Stem = namedtuple('Stem', ['child', 'stream', 'timeout'])
@Singleton @Singleton
class Dandelion(): class Dandelion:
""""""
# pylint: disable=old-style-class
def __init__(self): def __init__(self):
# currently assignable child stems # currently assignable child stems
self.stem = [] self.stem = []
@ -35,31 +44,36 @@ class Dandelion():
self.lock = RLock() self.lock = RLock()
def poissonTimeout(self, start=None, average=0): def poissonTimeout(self, start=None, average=0):
""""""
# pylint: disable=no-self-use
if start is None: if start is None:
start = time() start = time()
if average == 0: if average == 0:
average = FLUFF_TRIGGER_MEAN_DELAY average = FLUFF_TRIGGER_MEAN_DELAY
return start + expovariate(1.0/average) + FLUFF_TRIGGER_FIXED_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):
""""""
PeterSurda commented 2018-12-04 12:52:54 +01:00 (Migrated from github.com)
Review
    """Dandelion class for tracking stem/fluff stages."""
```suggestion """Dandelion class for tracking stem/fluff stages.""" ```
if not state.dandelion: if not state.dandelion:
return return
with self.lock: with self.lock:
self.hashMap[hashId] = Stem( self.hashMap[hashId] = Stem(
self.getNodeStem(source), self.getNodeStem(source),
stream, stream,
self.poissonTimeout()) self.poissonTimeout())
def setHashStream(self, hashId, stream=1): def setHashStream(self, hashId, stream=1):
""""""
with self.lock: with self.lock:
if hashId in self.hashMap: if hashId in self.hashMap:
self.hashMap[hashId] = Stem( self.hashMap[hashId] = Stem(
self.hashMap[hashId].child, self.hashMap[hashId].child,
stream, stream,
self.poissonTimeout()) self.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)
with self.lock: with self.lock:
try: try:
del self.hashMap[hashId] del self.hashMap[hashId]
@ -67,12 +81,15 @@ class Dandelion():
pass pass
def hasHash(self, hashId): def hasHash(self, hashId):
""""""
PeterSurda commented 2018-12-04 12:54:15 +01:00 (Migrated from github.com)
Review
        """Generate deadline using Poisson distribution"""
```suggestion """Generate deadline using Poisson distribution""" ```
return hashId in self.hashMap return hashId in self.hashMap
def objectChildStem(self, hashId): def objectChildStem(self, hashId):
""""""
return self.hashMap[hashId].child return self.hashMap[hashId].child
def maybeAddStem(self, connection): def maybeAddStem(self, connection):
""""""
# fewer than MAX_STEMS outbound connections at last reshuffle? # fewer than MAX_STEMS outbound connections at last reshuffle?
with self.lock: with self.lock:
PeterSurda commented 2018-12-04 12:56:00 +01:00 (Migrated from github.com)
Review
        """Add inventory vector to dandelion stem"""
```suggestion """Add inventory vector to dandelion stem""" ```
if len(self.stem) < MAX_STEMS: if len(self.stem) < MAX_STEMS:
@ -83,8 +100,8 @@ class Dandelion():
self.hashMap[k] = Stem(connection, v.stream, self.poissonTimeout()) self.hashMap[k] = Stem(connection, v.stream, self.poissonTimeout())
invQueue.put((v.stream, k, v.child)) invQueue.put((v.stream, k, v.child))
def maybeRemoveStem(self, connection): def maybeRemoveStem(self, connection):
""""""
# is the stem active? # is the stem active?
with self.lock: with self.lock:
if connection in self.stem: if connection in self.stem:
PeterSurda commented 2018-12-04 12:57:10 +01:00 (Migrated from github.com)
Review
        """Update stream for inventory vector (as inv/dinv commands don't include streams, we only learn this after receiving the object)"""
```suggestion """Update stream for inventory vector (as inv/dinv commands don't include streams, we only learn this after receiving the object)""" ```
@ -96,6 +113,7 @@ class Dandelion():
self.hashMap[k] = Stem(None, v.stream, self.poissonTimeout()) self.hashMap[k] = Stem(None, v.stream, self.poissonTimeout())
def pickStem(self, parent=None): def pickStem(self, parent=None):
""""""
try: try:
# pick a random from available stems # pick a random from available stems
stem = choice(range(len(self.stem))) stem = choice(range(len(self.stem)))
@ -112,6 +130,7 @@ class Dandelion():
return None return None
def getNodeStem(self, node=None): def getNodeStem(self, node=None):
""""""
PeterSurda commented 2018-12-04 12:59:54 +01:00 (Migrated from github.com)
Review
        """Child (i.e. next) node for an inventory vector during stem mode"""
```suggestion """Child (i.e. next) node for an inventory vector during stem mode""" ```
with self.lock: with self.lock:
try: try:
return self.nodeMap[node] return self.nodeMap[node]
@ -120,15 +139,18 @@ class Dandelion():
return self.nodeMap[node] return self.nodeMap[node]
def expire(self): def expire(self):
""""""
with self.lock: with self.lock:
deadline = time() deadline = time()
# only expire those that have a child node, i.e. those without a child not will stick around # only expire those that have a child node, i.e. those without a child not will stick around
toDelete = [[v.stream, k, v.child] for k, v in self.hashMap.iteritems() if v.timeout < deadline and v.child] toDelete = [[v.stream, k, v.child]
for k, v in self.hashMap.iteritems() if v.timeout < deadline and v.child]
for row in toDelete: for row in toDelete:
self.removeHash(row[1], 'expiration') self.removeHash(row[1], 'expiration')
invQueue.put((row[0], row[1], row[2])) invQueue.put((row[0], row[1], row[2]))
def reRandomiseStems(self): def reRandomiseStems(self):
""""""
with self.lock: with self.lock:
try: try:
# random two connections # random two connections

View File

@ -1,54 +0,0 @@
import asyncore
from http import HTTPClient
import paths
from tls import TLSHandshake
# self.sslSock = ssl.wrap_socket(self.sock, keyfile = os.path.join(paths.codePath(), 'sslkeys', 'key.pem'), certfile = os.path.join(paths.codePath(), 'sslkeys', 'cert.pem'), server_side = not self.initiatedConnection, ssl_version=ssl.PROTOCOL_TLSv1, do_handshake_on_connect=False, ciphers='AECDH-AES256-SHA')
class HTTPSClient(HTTPClient, TLSHandshake):
def __init__(self, host, path):
if not hasattr(self, '_map'):
asyncore.dispatcher.__init__(self)
self.tlsDone = False
# TLSHandshake.__init__(self, address=(host, 443), certfile='/home/shurdeek/src/PyBitmessage/sslsrc/keys/cert.pem', keyfile='/home/shurdeek/src/PyBitmessage/src/sslkeys/key.pem', server_side=False, ciphers='AECDH-AES256-SHA')
HTTPClient.__init__(self, host, path, connect=False)
TLSHandshake.__init__(self, address=(host, 443), server_side=False)
def handle_connect(self):
TLSHandshake.handle_connect(self)
def handle_close(self):
if self.tlsDone:
HTTPClient.close(self)
else:
TLSHandshake.close(self)
def readable(self):
if self.tlsDone:
return HTTPClient.readable(self)
else:
return TLSHandshake.readable(self)
def handle_read(self):
if self.tlsDone:
HTTPClient.handle_read(self)
else:
TLSHandshake.handle_read(self)
def writable(self):
if self.tlsDone:
return HTTPClient.writable(self)
else:
return TLSHandshake.writable(self)
def handle_write(self):
if self.tlsDone:
HTTPClient.handle_write(self)
else:
TLSHandshake.handle_write(self)
if __name__ == "__main__":
client = HTTPSClient('anarchy.economicsofbitcoin.com', '/')
asyncore.loop()

View File

@ -1,27 +1,38 @@
"""
src/network/socks4a.py
======================
"""
# pylint: disable=attribute-defined-outside-init
import socket import socket
import struct import struct
from proxy import Proxy, ProxyError, GeneralProxyError from proxy import GeneralProxyError, Proxy, ProxyError
class Socks4aError(ProxyError): class Socks4aError(ProxyError):
""""""
errorCodes = ("Request granted", errorCodes = ("Request granted",
PeterSurda commented 2018-12-04 13:08:28 +01:00 (Migrated from github.com)
Review
    """SOCKS4a error base class"""
```suggestion """SOCKS4a error base class""" ```
"Request rejected or failed", "Request rejected or failed",
"Request rejected because SOCKS server cannot connect to identd on the client", "Request rejected because SOCKS server cannot connect to identd on the client",
"Request rejected because the client program and identd report different user-ids", "Request rejected because the client program and identd report different user-ids",
"Unknown error") "Unknown error")
class Socks4a(Proxy): class Socks4a(Proxy):
""""""
def __init__(self, address=None): def __init__(self, address=None):
Proxy.__init__(self, address) Proxy.__init__(self, address)
self.ipaddr = None self.ipaddr = None
self.destport = address[1] self.destport = address[1]
PeterSurda commented 2018-12-04 13:08:41 +01:00 (Migrated from github.com)
Review
    """SOCKS4a proxy class"""
```suggestion """SOCKS4a proxy class""" ```
def state_init(self): def state_init(self):
""""""
self.set_state("auth_done", 0) self.set_state("auth_done", 0)
return True return True
def state_pre_connect(self): def state_pre_connect(self):
""""""
PeterSurda commented 2018-12-04 13:09:00 +01:00 (Migrated from github.com)
Review
        """Protocol initialisation (before connection is established)"""
```suggestion """Protocol initialisation (before connection is established)""" ```
# Get the response # Get the response
if self.read_buf[0:1] != chr(0x00).encode(): if self.read_buf[0:1] != chr(0x00).encode():
# bad data # bad data
@ -47,14 +58,17 @@ class Socks4a(Proxy):
return True return True
def proxy_sock_name(self): def proxy_sock_name(self):
return socket.inet_ntoa(self.__proxysockname[0]) """"""
return socket.inet_ntoa(self.__proxysockname[0])
class Socks4aConnection(Socks4a): class Socks4aConnection(Socks4a):
""""""
def __init__(self, address): def __init__(self, address):
Socks4a.__init__(self, address=address) Socks4a.__init__(self, address=address)
def state_auth_done(self): def state_auth_done(self):
""""""
# Now we can request the actual connection # Now we can request the actual connection
rmtrslv = False rmtrslv = False
self.append_write_buf(struct.pack('>BBH', 0x04, 0x01, self.destination[1])) self.append_write_buf(struct.pack('>BBH', 0x04, 0x01, self.destination[1]))
@ -65,7 +79,7 @@ class Socks4aConnection(Socks4a):
self.append_write_buf(self.ipaddr) self.append_write_buf(self.ipaddr)
except socket.error: except socket.error:
# Well it's not an IP number, so it's probably a DNS name. # Well it's not an IP number, so it's probably a DNS name.
if Proxy._remote_dns: if Proxy._remote_dns: # pylint: disable=protected-access
# Resolve remotely # Resolve remotely
rmtrslv = True rmtrslv = True
self.ipaddr = None self.ipaddr = None
@ -83,6 +97,7 @@ class Socks4aConnection(Socks4a):
return True return True
def state_pre_connect(self): def state_pre_connect(self):
""""""
try: try:
return Socks4a.state_pre_connect(self) return Socks4a.state_pre_connect(self)
except Socks4aError as e: except Socks4aError as e:
@ -91,12 +106,14 @@ class Socks4aConnection(Socks4a):
PeterSurda commented 2018-12-04 13:10:54 +01:00 (Migrated from github.com)
Review
        """Handle return value when using SOCKS4a for DNS resolving instead of connecting."""
```suggestion """Handle return value when using SOCKS4a for DNS resolving instead of connecting.""" ```
class Socks4aResolver(Socks4a): class Socks4aResolver(Socks4a):
""""""
def __init__(self, host): def __init__(self, host):
self.host = host self.host = host
PeterSurda commented 2018-12-04 13:12:32 +01:00 (Migrated from github.com)
Review
    """Child SOCKS4a class used for making outbound connections."""
```suggestion """Child SOCKS4a class used for making outbound connections.""" ```
self.port = 8444 self.port = 8444
Socks4a.__init__(self, address=(self.host, self.port)) Socks4a.__init__(self, address=(self.host, self.port))
def state_auth_done(self): def state_auth_done(self):
""""""
PeterSurda commented 2018-12-04 13:12:50 +01:00 (Migrated from github.com)
Review
        """Request connection to be made"""
```suggestion """Request connection to be made""" ```
# Now we can request the actual connection # Now we can request the actual connection
self.append_write_buf(struct.pack('>BBH', 0x04, 0xF0, self.destination[1])) self.append_write_buf(struct.pack('>BBH', 0x04, 0xF0, self.destination[1]))
self.append_write_buf(struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01)) self.append_write_buf(struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01))
@ -108,4 +125,5 @@ class Socks4aResolver(Socks4a):
return True return True
def resolved(self): def resolved(self):
""""""
print "Resolved %s as %s" % (self.host, self.proxy_sock_name()) print "Resolved %s as %s" % (self.host, self.proxy_sock_name())