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 7 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
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):
@ -85,18 +86,6 @@ class Peer(object):
'''Deserialize from a dictionary.'''
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):
'''Return peers whose host matches our hostname or IP address.
Additionally include all peers whose IP address matches our
@ -159,7 +148,7 @@ class Peer(object):
if ip:
return ((ip.is_global or ip.is_private)
and not (ip.is_multicast or ip.is_unspecified))
return is_valid_hostname(self.host)
return util.is_valid_hostname(self.host)
@cachedproperty
def is_public(self):
@ -211,10 +200,6 @@ class Peer(object):
result = self.features.get(key)
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
def genesis_hash(self):
'''Returns None if no SSL port, otherwise the port as an integer.'''
@ -244,15 +229,20 @@ class Peer(object):
return pruning
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
def protocol_min(self):
'''Minimum protocol version as a string, e.g., 1.0'''
return self._version_string('protcol_min')
return self._protocol_version_string('protocol_min')
@cachedproperty
def protocol_max(self):
'''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):
'''The tuple ((ip, host, details) expected in response

7
lib/util.py

@ -279,6 +279,13 @@ def protocol_tuple(s):
except Exception:
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):
'''Given a client protocol request, return the protocol version
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("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():
assert util.protocol_version(None, "1.0", "1.0") == (1, 0)
assert util.protocol_version("0.10", "0.10", "1.1") == (0, 10)

Loading…
Cancel
Save