Browse Source

Move things from Controller to session class

which better belong there:

- PROTOCOL_MIN, PROTOCOL_MAX
- server_features()
- server_version_args()
- inline protocol_tuple()
patch-2
Neil Booth 7 years ago
parent
commit
c790fd567c
  1. 34
      electrumx/server/controller.py
  2. 7
      electrumx/server/peers.py
  3. 33
      electrumx/server/session.py

34
electrumx/server/controller.py

@ -51,21 +51,21 @@ class Controller(ServerBase):
''' '''
CATCHING_UP, LISTENING, PAUSED, SHUTTING_DOWN = range(4) CATCHING_UP, LISTENING, PAUSED, SHUTTING_DOWN = range(4)
PROTOCOL_MIN = '1.1'
PROTOCOL_MAX = '1.4'
AIORPCX_MIN = (0, 5, 6) AIORPCX_MIN = (0, 5, 6)
def __init__(self, env): def __init__(self, env):
'''Initialize everything that doesn't require the event loop.''' '''Initialize everything that doesn't require the event loop.'''
super().__init__(env) super().__init__(env)
if aiorpcx_version < self.AIORPCX_MIN: if aiorpcx_version < self.AIORPCX_MIN:
raise RuntimeError('ElectrumX requires aiorpcX >= ' raise RuntimeError('ElectrumX requires aiorpcX >= '
f'{version_string(self.AIORPCX_MIN)}') f'{version_string(self.AIORPCX_MIN)}')
sclass = env.coin.SESSIONCLS
self.logger.info(f'software version: {electrumx.version}') self.logger.info(f'software version: {electrumx.version}')
self.logger.info(f'aiorpcX version: {version_string(aiorpcx_version)}') self.logger.info(f'aiorpcX version: {version_string(aiorpcx_version)}')
self.logger.info(f'supported protocol versions: ' self.logger.info(f'supported protocol versions: '
f'{self.PROTOCOL_MIN}-{self.PROTOCOL_MAX}') f'{sclass.PROTOCOL_MIN}-{sclass.PROTOCOL_MAX}')
self.logger.info(f'event loop policy: {env.loop_policy}') self.logger.info(f'event loop policy: {env.loop_policy}')
self.coin = env.coin self.coin = env.coin
@ -106,34 +106,6 @@ class Controller(ServerBase):
# Event triggered when electrumx is listening for incoming requests. # Event triggered when electrumx is listening for incoming requests.
self.server_listening = asyncio.Event() self.server_listening = asyncio.Event()
def server_features(self):
'''Return the server features dictionary.'''
return {
'hosts': self.env.hosts_dict(),
'pruning': None,
'server_version': electrumx.version,
'protocol_min': self.PROTOCOL_MIN,
'protocol_max': self.PROTOCOL_MAX,
'genesis_hash': self.coin.GENESIS_HASH,
'hash_function': 'sha256',
}
def server_version_args(self):
'''The arguments to a server.version RPC call to a peer.'''
return [electrumx.version, [self.PROTOCOL_MIN, self.PROTOCOL_MAX]]
def protocol_tuple(self, request):
'''Given a client's protocol version request, return the negotiated
protocol tuple. If the request is unsupported return None.
'''
ptuple, client_min = util.protocol_version(request, self.PROTOCOL_MIN,
self.PROTOCOL_MAX)
if not ptuple and client_min > util.protocol_tuple(self.PROTOCOL_MIN):
version = version_string(client_min)
self.logger.info(f'client requested future protocol version '
f'{version} - is your software out of date?')
return ptuple
async def start_servers(self): async def start_servers(self):
'''Start the RPC server and schedule the external servers to be '''Start the RPC server and schedule the external servers to be
started once the block processor has caught up. started once the block processor has caught up.

7
electrumx/server/peers.py

@ -51,8 +51,7 @@ class PeerSession(ClientSession):
self.peer.ip_addr = address[0] self.peer.ip_addr = address[0]
# Send server.version first # Send server.version first
controller = self.peer_mgr.controller self.send_request('server.version', self.peer_mgr.server_version_args,
self.send_request('server.version', controller.server_version_args(),
self.on_version, timeout=self.timeout) self.on_version, timeout=self.timeout)
def connection_lost(self, exc): def connection_lost(self, exc):
@ -232,8 +231,10 @@ class PeerManager(object):
self.loop = controller.loop self.loop = controller.loop
# Our clearnet and Tor Peers, if any # Our clearnet and Tor Peers, if any
self.myselves = [Peer(ident.host, controller.server_features(), 'env') sclass = env.coin.SESSIONCLS
self.myselves = [Peer(ident.host, sclass.server_features(env), 'env')
for ident in env.identities] for ident in env.identities]
self.server_version_args = sclass.server_version_args()
self.retry_event = asyncio.Event() self.retry_event = asyncio.Event()
# Peers have one entry per hostname. Once connected, the # Peers have one entry per hostname. Once connected, the
# ip_addr property is either None, an onion peer, or the # ip_addr property is either None, an onion peer, or the

33
electrumx/server/session.py

@ -133,6 +133,9 @@ class SessionBase(ServerSession):
class ElectrumX(SessionBase): class ElectrumX(SessionBase):
'''A TCP server that handles incoming Electrum connections.''' '''A TCP server that handles incoming Electrum connections.'''
PROTOCOL_MIN = '1.1'
PROTOCOL_MAX = '1.4'
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.subscribe_headers = False self.subscribe_headers = False
@ -143,8 +146,25 @@ class ElectrumX(SessionBase):
self.hashX_subs = {} self.hashX_subs = {}
self.sv_seen = False self.sv_seen = False
self.mempool_statuses = {} self.mempool_statuses = {}
self.set_protocol_handlers(util.protocol_tuple( self.set_protocol_handlers(util.protocol_tuple(self.PROTOCOL_MIN))
self.controller.PROTOCOL_MIN))
@classmethod
def server_features(cls, env):
'''Return the server features dictionary.'''
return {
'hosts': env.hosts_dict(),
'pruning': None,
'server_version': electrumx.version,
'protocol_min': cls.PROTOCOL_MIN,
'protocol_max': cls.PROTOCOL_MAX,
'genesis_hash': env.coin.GENESIS_HASH,
'hash_function': 'sha256',
}
@classmethod
def server_version_args(cls):
'''The arguments to a server.version RPC call to a peer.'''
return [electrumx.version, [cls.PROTOCOL_MIN, cls.PROTOCOL_MAX]]
def protocol_version_string(self): def protocol_version_string(self):
return util.version_string(self.protocol_tuple) return util.version_string(self.protocol_tuple)
@ -440,8 +460,13 @@ class ElectrumX(SessionBase):
# Find the highest common protocol version. Disconnect if # Find the highest common protocol version. Disconnect if
# that protocol version in unsupported. # that protocol version in unsupported.
ptuple = self.controller.protocol_tuple(protocol_version) ptuple, client_min = util.protocol_version(
protocol_version, self.PROTOCOL_MIN, self.PROTOCOL_MAX)
if ptuple is None: if ptuple is None:
if client_min > util.protocol_tuple(self.PROTOCOL_MIN):
self.logger.info(f'client requested future protocol version '
f'{version_string(client_min)} '
f'- is your software out of date?')
self.close_after_send = True self.close_after_send = True
raise RPCError(BAD_REQUEST, raise RPCError(BAD_REQUEST,
f'unsupported protocol version: {protocol_version}') f'unsupported protocol version: {protocol_version}')
@ -492,7 +517,7 @@ class ElectrumX(SessionBase):
'server.add_peer': self.add_peer, 'server.add_peer': self.add_peer,
'server.banner': self.banner, 'server.banner': self.banner,
'server.donation_address': self.donation_address, 'server.donation_address': self.donation_address,
'server.features': self.controller.server_features, 'server.features': partial(self.server_features, self.env),
'server.peers.subscribe': self.peers_subscribe, 'server.peers.subscribe': self.peers_subscribe,
'server.version': self.server_version, 'server.version': self.server_version,
} }

Loading…
Cancel
Save