Fix protocol version reported in server.peers.subscribe
- new library function protocol_version_string() with tests - remove ad-hoc class functions Fixes #251
This commit is contained in:
parent
7349bef13f
commit
f4cc1e2926
30
lib/peer.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
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -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…
Reference in New Issue
Block a user