Browse Source

Fix protocol version reported in server.peers.subscribe

- new library function protocol_version_string() with tests
- remove ad-hoc class functions

Fixes #251
master
Neil Booth 8 years ago
parent
commit
f4cc1e2926
  1. 30
      lib/peer.py
  2. 7
      lib/util.py
  3. 6
      tests/lib/test_util.py

30
lib/peer.py

@ -28,7 +28,8 @@
import re import re
from ipaddress import ip_address from ipaddress import ip_address
from lib.util import cachedproperty, is_valid_hostname from lib.util import cachedproperty
import lib.util as util
class Peer(object): class Peer(object):
@ -85,18 +86,6 @@ class Peer(object):
'''Deserialize from a dictionary.''' '''Deserialize from a dictionary.'''
return cls(**item) return cls(**item)
@classmethod
def version_tuple(cls, vstr):
'''Convert a version string, such as "1.2", to a (major_version,
minor_version) pair.
'''
if isinstance(vstr, str) and VERSION_REGEX.match(vstr):
if '.' not in vstr:
vstr += '.0'
else:
vstr = '1.0'
return tuple(int(part) for part in vstr.split('.'))
def matches(self, peers): def matches(self, peers):
'''Return peers whose host matches our hostname or IP address. '''Return peers whose host matches our hostname or IP address.
Additionally include all peers whose IP address matches our Additionally include all peers whose IP address matches our
@ -159,7 +148,7 @@ class Peer(object):
if ip: if ip:
return ((ip.is_global or ip.is_private) return ((ip.is_global or ip.is_private)
and not (ip.is_multicast or ip.is_unspecified)) and not (ip.is_multicast or ip.is_unspecified))
return is_valid_hostname(self.host) return util.is_valid_hostname(self.host)
@cachedproperty @cachedproperty
def is_public(self): def is_public(self):
@ -211,10 +200,6 @@ class Peer(object):
result = self.features.get(key) result = self.features.get(key)
return result if isinstance(result, str) else None return result if isinstance(result, str) else None
def _version_string(self, key):
version = self.features.get(key)
return '{:d}.{:d}'.format(*self.version_tuple(version))
@cachedproperty @cachedproperty
def genesis_hash(self): def genesis_hash(self):
'''Returns None if no SSL port, otherwise the port as an integer.''' '''Returns None if no SSL port, otherwise the port as an integer.'''
@ -244,15 +229,20 @@ class Peer(object):
return pruning return pruning
return None return None
def _protocol_version_string(self, key):
version_str = self.features.get(key)
ptuple = util.protocol_tuple(version_str)
return util.protocol_version_string(ptuple)
@cachedproperty @cachedproperty
def protocol_min(self): def protocol_min(self):
'''Minimum protocol version as a string, e.g., 1.0''' '''Minimum protocol version as a string, e.g., 1.0'''
return self._version_string('protcol_min') return self._protocol_version_string('protocol_min')
@cachedproperty @cachedproperty
def protocol_max(self): def protocol_max(self):
'''Maximum protocol version as a string, e.g., 1.1''' '''Maximum protocol version as a string, e.g., 1.1'''
return self._version_string('protcol_max') return self._protocol_version_string('protocol_max')
def to_tuple(self): def to_tuple(self):
'''The tuple ((ip, host, details) expected in response '''The tuple ((ip, host, details) expected in response

7
lib/util.py

@ -279,6 +279,13 @@ def protocol_tuple(s):
except Exception: except Exception:
return (0, ) return (0, )
def protocol_version_string(ptuple):
'''Convert a version tuple such as (1, 2) to "1.2".
There is always at least one dot, so (1, ) becomes "1.0".'''
while len(ptuple) < 2:
ptuple += (0, )
return '.'.join(str(p) for p in ptuple)
def protocol_version(client_req, server_min, server_max): def protocol_version(client_req, server_min, server_max):
'''Given a client protocol request, return the protocol version '''Given a client protocol request, return the protocol version
to use as a tuple. to use as a tuple.

6
tests/lib/test_util.py

@ -94,6 +94,12 @@ def test_protocol_tuple():
assert util.protocol_tuple("0.10") == (0, 10) assert util.protocol_tuple("0.10") == (0, 10)
assert util.protocol_tuple("2.5.3") == (2, 5, 3) assert util.protocol_tuple("2.5.3") == (2, 5, 3)
def test_protocol_version_string():
assert util.protocol_version_string(()) == "0.0"
assert util.protocol_version_string((1, )) == "1.0"
assert util.protocol_version_string((1, 2)) == "1.2"
assert util.protocol_version_string((1, 3, 2)) == "1.3.2"
def test_protocol_version(): def test_protocol_version():
assert util.protocol_version(None, "1.0", "1.0") == (1, 0) assert util.protocol_version(None, "1.0", "1.0") == (1, 0)
assert util.protocol_version("0.10", "0.10", "1.1") == (0, 10) assert util.protocol_version("0.10", "0.10", "1.1") == (0, 10)

Loading…
Cancel
Save