Move server/version.py to Controller class

This commit is contained in:
Neil Booth 2018-04-09 08:18:28 +09:00
parent 34c45e6601
commit 8bf30fba0e
10 changed files with 57 additions and 54 deletions

View File

@ -15,7 +15,7 @@
import os import os
import sys import sys
sys.path.insert(0, os.path.abspath('..')) sys.path.insert(0, os.path.abspath('..'))
from server.version import VERSION from server.controller import Controller
# -- Project information ----------------------------------------------------- # -- Project information -----------------------------------------------------
@ -24,9 +24,9 @@ copyright = '2016-2018, Neil Booth'
author = 'Neil Booth' author = 'Neil Booth'
# The short X.Y version # The short X.Y version
version = VERSION.split()[-1] version = Controller.short_version()
# The full version, including alpha/beta/rc tags # The full version including branding
release = VERSION release = Controller.VERSION
# -- General configuration --------------------------------------------------- # -- General configuration ---------------------------------------------------

View File

@ -53,7 +53,6 @@ class ServerBase(object):
# First asyncio operation must be to set the event loop policy # First asyncio operation must be to set the event loop policy
# as this replaces the event loop # as this replaces the event loop
self.logger.info('event loop policy: {}'.format(self.env.loop_policy))
asyncio.set_event_loop_policy(self.env.loop_policy) asyncio.set_event_loop_policy(self.env.loop_policy)
# Trigger this event to cleanly shutdown # Trigger this event to cleanly shutdown

View File

@ -18,7 +18,6 @@ from collections import defaultdict
from functools import partial from functools import partial
from server.daemon import DaemonError from server.daemon import DaemonError
from server.version import VERSION
from lib.hash import hash_to_str from lib.hash import hash_to_str
from lib.util import chunks, formatted_time from lib.util import chunks, formatted_time
import server.db import server.db
@ -221,8 +220,8 @@ class BlockProcessor(server.db.DB):
self.first_sync = False self.first_sync = False
await self.controller.run_in_executor(self.flush, True) await self.controller.run_in_executor(self.flush, True)
if self.utxo_db.for_sync: if self.utxo_db.for_sync:
self.logger.info('{} synced to height {:,d}' self.logger.info(f'{self.controller.VERSION} synced to '
.format(VERSION, self.height)) f'height {height:,d}')
self.open_dbs() self.open_dbs()
self.caught_up_event.set() self.caught_up_event.set()

View File

@ -46,10 +46,17 @@ class Controller(ServerBase):
''' '''
CATCHING_UP, LISTENING, PAUSED, SHUTTING_DOWN = range(4) CATCHING_UP, LISTENING, PAUSED, SHUTTING_DOWN = range(4)
PROTOCOL_MIN = '0.9'
PROTOCOL_MAX = '1.2'
VERSION = 'ElectrumX 1.4'
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)
self.logger.info(f'software version: {self.VERSION}')
self.logger.info(f'supported protocol versions: '
f'{self.PROTOCOL_MIN}-{self.PROTOCOL_MAX}')
self.logger.info(f'event loop policy: {env.loop_policy}')
self.coin = env.coin self.coin = env.coin
self.servers = {} self.servers = {}
@ -84,6 +91,34 @@ class Controller(ServerBase):
self.mempool = MemPool(self.bp, self) self.mempool = MemPool(self.bp, self)
self.peer_mgr = PeerManager(env, self) self.peer_mgr = PeerManager(env, self)
@classmethod
def short_version(cls):
'''Return e.g. "1.2" for ElectrumX 1.2'''
return cls.VERSION.split()[-1]
def server_features(self):
'''Return the server features dictionary.'''
return {
'hosts': self.env.hosts_dict(),
'pruning': None,
'server_version': self.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 [self.VERSION, [self.PROTOCOL_MIN, self.PROTOCOL_MAX]]
def protocol_tuple(self, client_protocol_str):
'''Given a client's protocol version string, return the negotiated
protocol version tuple, or None if unsupported.
'''
return util.protocol_version(client_protocol_str,
self.PROTOCOL_MIN, self.PROTOCOL_MAX)
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.

View File

@ -20,7 +20,6 @@ from collections import namedtuple
import lib.util as util import lib.util as util
from lib.hash import hash_to_str from lib.hash import hash_to_str
from server.storage import db_class from server.storage import db_class
from server.version import VERSION, PROTOCOL_MIN, PROTOCOL_MAX
UTXO = namedtuple("UTXO", "tx_num tx_pos tx_hash height value") UTXO = namedtuple("UTXO", "tx_num tx_pos tx_hash height value")
@ -131,9 +130,6 @@ class DB(object):
self.read_history_state() self.read_history_state()
self.logger.info('software version: {}'.format(VERSION))
self.logger.info('supported protocol versions: {}-{}'
.format(PROTOCOL_MIN, PROTOCOL_MAX))
self.logger.info('DB version: {:d}'.format(self.db_version)) self.logger.info('DB version: {:d}'.format(self.db_version))
self.logger.info('coin: {}'.format(self.coin.NAME)) self.logger.info('coin: {}'.format(self.coin.NAME))
self.logger.info('network: {}'.format(self.coin.NET)) self.logger.info('network: {}'.format(self.coin.NET))

View File

@ -16,7 +16,6 @@ from ipaddress import ip_address
from lib.coins import Coin from lib.coins import Coin
from lib.env_base import EnvBase from lib.env_base import EnvBase
import lib.util as lib_util import lib.util as lib_util
import server.version as version
NetIdentity = namedtuple('NetIdentity', 'host tcp_port ssl_port nick_suffix') NetIdentity = namedtuple('NetIdentity', 'host tcp_port ssl_port nick_suffix')
@ -146,21 +145,10 @@ class Env(EnvBase):
'_tor', '_tor',
) )
def server_features(self): def hosts_dict(self):
'''Return the server features dictionary.''' return {identity.host: {'tcp_port': identity.tcp_port,
hosts = {identity.host: {'tcp_port': identity.tcp_port, 'ssl_port': identity.ssl_port}
'ssl_port': identity.ssl_port} for identity in self.identities}
for identity in self.identities}
return {
'hosts': hosts,
'pruning': None,
'server_version': version.VERSION,
'protocol_min': version.PROTOCOL_MIN,
'protocol_max': version.PROTOCOL_MAX,
'genesis_hash': self.coin.GENESIS_HASH,
'hash_function': 'sha256',
}
def peer_discovery_enum(self): def peer_discovery_enum(self):
pd = self.default('PEER_DISCOVERY', 'on').strip().lower() pd = self.default('PEER_DISCOVERY', 'on').strip().lower()

View File

@ -20,7 +20,6 @@ import aiorpcx
from lib.peer import Peer from lib.peer import Peer
from lib.util import ConnectionLogger from lib.util import ConnectionLogger
import server.version as version
PEER_GOOD, PEER_STALE, PEER_NEVER, PEER_BAD = range(4) PEER_GOOD, PEER_STALE, PEER_NEVER, PEER_BAD = range(4)
@ -51,9 +50,9 @@ class PeerSession(aiorpcx.ClientSession):
self.peer.ip_addr = address[0] self.peer.ip_addr = address[0]
# Send server.version first # Send server.version first
args = [version.VERSION, [version.PROTOCOL_MIN, version.PROTOCOL_MAX]] controller = self.peer_mgr.controller
self.send_request('server.version', args, self.on_version, self.send_request('server.version', controller.server_version_args(),
timeout=self.timeout) self.on_version, timeout=self.timeout)
def _header_notification(self, header): def _header_notification(self, header):
pass pass
@ -226,7 +225,7 @@ 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, env.server_features(), 'env') self.myselves = [Peer(ident.host, controller.server_features(), 'env')
for ident in env.identities] for ident in env.identities]
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

View File

@ -17,7 +17,6 @@ from aiorpcx import ServerSession, JSONRPCAutoDetect, RPCError
from lib.hash import sha256, hash_to_str from lib.hash import sha256, hash_to_str
import lib.util as util import lib.util as util
from server.daemon import DaemonError from server.daemon import DaemonError
import server.version as version
BAD_REQUEST = 1 BAD_REQUEST = 1
DAEMON_ERROR = 2 DAEMON_ERROR = 2
@ -293,10 +292,6 @@ class ElectrumX(SessionBase):
hashX = self.controller.scripthash_to_hashX(scripthash) hashX = self.controller.scripthash_to_hashX(scripthash)
return await self.hashX_subscribe(hashX, scripthash) return await self.hashX_subscribe(hashX, scripthash)
def server_features(self):
'''Returns a dictionary of server features.'''
return self.env.server_features()
def block_headers(self, start_height, count): def block_headers(self, start_height, count):
'''Return count concatenated block headers as hex for the main chain; '''Return count concatenated block headers as hex for the main chain;
starting at start_height. starting at start_height.
@ -336,11 +331,9 @@ class ElectrumX(SessionBase):
minor, revision = divmod(minor, 10000) minor, revision = divmod(minor, 10000)
revision //= 100 revision //= 100
daemon_version = '{:d}.{:d}.{:d}'.format(major, minor, revision) daemon_version = '{:d}.{:d}.{:d}'.format(major, minor, revision)
server_version = version.VERSION.split()[-1]
for pair in [ for pair in [
('$VERSION', version.VERSION), # legacy ('$SERVER_VERSION', self.controller.short_version()),
('$SERVER_VERSION', server_version), ('$SERVER_SUBVERSION', self.controller.VERSION),
('$SERVER_SUBVERSION', version.VERSION),
('$DAEMON_VERSION', daemon_version), ('$DAEMON_VERSION', daemon_version),
('$DAEMON_SUBVERSION', network_info['subversion']), ('$DAEMON_SUBVERSION', network_info['subversion']),
('$DONATION_ADDRESS', self.env.donation_address), ('$DONATION_ADDRESS', self.env.donation_address),
@ -398,8 +391,7 @@ 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 = util.protocol_version(protocol_version, version.PROTOCOL_MIN, ptuple = self.controller.protocol_tuple(protocol_version)
version.PROTOCOL_MAX)
# From protocol version 1.1, protocol_version cannot be omitted # From protocol version 1.1, protocol_version cannot be omitted
if ptuple is None or (ptuple >= (1, 1) and protocol_version is None): if ptuple is None or (ptuple >= (1, 1) and protocol_version is None):
@ -413,9 +405,9 @@ class ElectrumX(SessionBase):
# The return value depends on the protocol version # The return value depends on the protocol version
if ptuple < (1, 1): if ptuple < (1, 1):
return version.VERSION return self.controller.VERSION
else: else:
return (version.VERSION, self.protocol_version) return (self.controller.VERSION, self.protocol_version)
async def transaction_broadcast(self, raw_tx): async def transaction_broadcast(self, raw_tx):
'''Broadcast a raw transaction to the network. '''Broadcast a raw transaction to the network.
@ -479,7 +471,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.server_features, 'server.features': self.controller.server_features,
'server.peers.subscribe': self.peers_subscribe, 'server.peers.subscribe': self.peers_subscribe,
'server.version': self.server_version, 'server.version': self.server_version,
} }

View File

@ -1,5 +0,0 @@
# Server name and protocol versions
VERSION = 'ElectrumX 1.4'
PROTOCOL_MIN = '0.9'
PROTOCOL_MAX = '1.2'

View File

@ -1,10 +1,10 @@
import setuptools import setuptools
from server.version import VERSION from server.controller import Controller
setuptools.setup( setuptools.setup(
name='electrumx', name='electrumx',
version=VERSION.split()[-1], version=Controller.short_version(),
scripts=['electrumx_server.py', 'electrumx_rpc.py'], scripts=['electrumx_server.py', 'electrumx_rpc.py'],
python_requires='>=3.6', python_requires='>=3.6',
# via environment variables, in which case I've tested with 15.0.4 # via environment variables, in which case I've tested with 15.0.4