Prepare 1.7.1
This commit is contained in:
parent
d962c97ef1
commit
0b4f6b3d6d
@ -7,6 +7,18 @@
|
|||||||
and memory consumption whilst serving clients. Those problems
|
and memory consumption whilst serving clients. Those problems
|
||||||
should not occur with Python 3.7.
|
should not occur with Python 3.7.
|
||||||
|
|
||||||
|
Version 1.7.1 (28 Jul 2018)
|
||||||
|
============================
|
||||||
|
|
||||||
|
* switch to aiorpcX 0.5.8 which implements some curio task management
|
||||||
|
primitives on top of asyncio that make writing correct async code
|
||||||
|
much easier, as well as making it simpler to reason about
|
||||||
|
* use those primitives to restructure the peer manager, which is now
|
||||||
|
fully concurrent again, as well as the block processor and
|
||||||
|
controller
|
||||||
|
* fix `#534`_ introduced in 1.7
|
||||||
|
* minor coin tweaks (ghost43, cipig)
|
||||||
|
|
||||||
Version 1.7 (25 Jul 2018)
|
Version 1.7 (25 Jul 2018)
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
@ -160,3 +172,4 @@ bitcoincash:qzxpdlt8ehu9ehftw6rqsy2jgfq4nsltxvhrdmdfpn
|
|||||||
.. _#506: https://github.com/kyuupichan/electrumx/issues/506
|
.. _#506: https://github.com/kyuupichan/electrumx/issues/506
|
||||||
.. _#519: https://github.com/kyuupichan/electrumx/issues/519
|
.. _#519: https://github.com/kyuupichan/electrumx/issues/519
|
||||||
.. _#523: https://github.com/kyuupichan/electrumx/issues/523
|
.. _#523: https://github.com/kyuupichan/electrumx/issues/523
|
||||||
|
.. _#534: https://github.com/kyuupichan/electrumx/issues/534
|
||||||
|
|||||||
@ -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('..'))
|
||||||
VERSION="ElectrumX 1.7"
|
VERSION="ElectrumX 1.7.1"
|
||||||
|
|
||||||
# -- Project information -----------------------------------------------------
|
# -- Project information -----------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
version = 'ElectrumX 1.7'
|
version = 'ElectrumX 1.7.1'
|
||||||
version_short = version.split()[-1]
|
version_short = version.split()[-1]
|
||||||
|
|
||||||
from electrumx.server.controller import Controller
|
from electrumx.server.controller import Controller
|
||||||
|
|||||||
@ -185,8 +185,8 @@ class PeerManager(object):
|
|||||||
async def _monitor_peer(self, peer):
|
async def _monitor_peer(self, peer):
|
||||||
# Stop monitoring if we were dropped (a duplicate peer)
|
# Stop monitoring if we were dropped (a duplicate peer)
|
||||||
while peer in self.peers:
|
while peer in self.peers:
|
||||||
is_good = await self._is_peer_good(peer)
|
if await self._should_drop_peer(peer):
|
||||||
if self._should_drop_peer(peer, is_good):
|
self.peers.discard(peer)
|
||||||
break
|
break
|
||||||
# Figure out how long to sleep before retrying. Retry a
|
# Figure out how long to sleep before retrying. Retry a
|
||||||
# good connection when it is about to turn stale, otherwise
|
# good connection when it is about to turn stale, otherwise
|
||||||
@ -198,47 +198,9 @@ class PeerManager(object):
|
|||||||
async with ignore_after(pause):
|
async with ignore_after(pause):
|
||||||
await peer.retry_event.wait()
|
await peer.retry_event.wait()
|
||||||
|
|
||||||
async def _should_drop_peer(self, peer, is_good):
|
async def _should_drop_peer(self, peer):
|
||||||
now = time.time()
|
|
||||||
if self.env.force_proxy or peer.is_tor:
|
|
||||||
how = f'via {kind} over Tor'
|
|
||||||
else:
|
|
||||||
how = f'via {kind} at {peer.ip_addr}'
|
|
||||||
status = 'verified' if good else 'failed to verify'
|
|
||||||
elapsed = now - peer.last_try
|
|
||||||
self.logger.info(f'{status} {peer} {how} in {elapsed:.1f}s')
|
|
||||||
|
|
||||||
if good:
|
|
||||||
peer.try_count = 0
|
|
||||||
peer.last_good = now
|
|
||||||
peer.source = 'peer'
|
|
||||||
# At most 2 matches if we're a host name, potentially
|
|
||||||
# several if we're an IP address (several instances
|
|
||||||
# can share a NAT).
|
|
||||||
matches = peer.matches(self.peers)
|
|
||||||
for match in matches:
|
|
||||||
if match.ip_address:
|
|
||||||
if len(matches) > 1:
|
|
||||||
self.peers.remove(match)
|
|
||||||
# Force the peer's monitoring task to exit
|
|
||||||
match.retry_event.set()
|
|
||||||
elif peer.host in match.features['hosts']:
|
|
||||||
match.update_features_from_peer(peer)
|
|
||||||
else:
|
|
||||||
# Forget the peer if long-term unreachable
|
|
||||||
if peer.last_good and not peer.bad:
|
|
||||||
try_limit = 10
|
|
||||||
else:
|
|
||||||
try_limit = 3
|
|
||||||
if peer.try_count >= try_limit:
|
|
||||||
desc = 'bad' if peer.bad else 'unreachable'
|
|
||||||
self.logger.info(f'forgetting {desc} peer: {peer}')
|
|
||||||
self.peers.discard(peer)
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def _is_peer_good(self, peer):
|
|
||||||
peer.try_count += 1
|
peer.try_count += 1
|
||||||
|
is_good = False
|
||||||
for kind, port in peer.connection_port_pairs():
|
for kind, port in peer.connection_port_pairs():
|
||||||
peer.last_try = time.time()
|
peer.last_try = time.time()
|
||||||
|
|
||||||
@ -263,7 +225,8 @@ class PeerManager(object):
|
|||||||
try:
|
try:
|
||||||
async with PeerSession(peer.host, port, **kwargs) as session:
|
async with PeerSession(peer.host, port, **kwargs) as session:
|
||||||
await self._verify_peer(session, peer)
|
await self._verify_peer(session, peer)
|
||||||
return True
|
is_good = True
|
||||||
|
break
|
||||||
except BadPeerError as e:
|
except BadPeerError as e:
|
||||||
self.logger.error(f'[{peer}] marking bad: ({e})')
|
self.logger.error(f'[{peer}] marking bad: ({e})')
|
||||||
peer.mark_bad()
|
peer.mark_bad()
|
||||||
@ -277,6 +240,43 @@ class PeerManager(object):
|
|||||||
self.logger.info(f'[{peer}] {kind} connection to '
|
self.logger.info(f'[{peer}] {kind} connection to '
|
||||||
f'port {port} failed: {e}')
|
f'port {port} failed: {e}')
|
||||||
|
|
||||||
|
now = time.time()
|
||||||
|
if self.env.force_proxy or peer.is_tor:
|
||||||
|
how = f'via {kind} over Tor'
|
||||||
|
else:
|
||||||
|
how = f'via {kind} at {peer.ip_addr}'
|
||||||
|
status = 'verified' if is_good else 'failed to verify'
|
||||||
|
elapsed = now - peer.last_try
|
||||||
|
self.logger.info(f'{status} {peer} {how} in {elapsed:.1f}s')
|
||||||
|
|
||||||
|
if is_good:
|
||||||
|
peer.try_count = 0
|
||||||
|
peer.last_good = now
|
||||||
|
peer.source = 'peer'
|
||||||
|
# At most 2 matches if we're a host name, potentially
|
||||||
|
# several if we're an IP address (several instances
|
||||||
|
# can share a NAT).
|
||||||
|
matches = peer.matches(self.peers)
|
||||||
|
for match in matches:
|
||||||
|
if match.ip_address:
|
||||||
|
if len(matches) > 1:
|
||||||
|
self.peers.remove(match)
|
||||||
|
# Force the peer's monitoring task to exit
|
||||||
|
match.retry_event.set()
|
||||||
|
elif peer.host in match.features['hosts']:
|
||||||
|
match.update_features_from_peer(peer)
|
||||||
|
else:
|
||||||
|
# Forget the peer if long-term unreachable
|
||||||
|
if peer.last_good and not peer.bad:
|
||||||
|
try_limit = 10
|
||||||
|
else:
|
||||||
|
try_limit = 3
|
||||||
|
if peer.try_count >= try_limit:
|
||||||
|
desc = 'bad' if peer.bad else 'unreachable'
|
||||||
|
self.logger.info(f'forgetting {desc} peer: {peer}')
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
async def _verify_peer(self, session, peer):
|
async def _verify_peer(self, session, peer):
|
||||||
if not peer.is_tor:
|
if not peer.is_tor:
|
||||||
address = session.peer_address()
|
address = session.peer_address()
|
||||||
|
|||||||
4
setup.py
4
setup.py
@ -1,5 +1,5 @@
|
|||||||
import setuptools
|
import setuptools
|
||||||
version = '1.7'
|
version = '1.7.1'
|
||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name='electrumX',
|
name='electrumX',
|
||||||
@ -11,7 +11,7 @@ setuptools.setup(
|
|||||||
# "tribus_hash" package is required to sync Denarius network.
|
# "tribus_hash" package is required to sync Denarius network.
|
||||||
# "blake256" package is required to sync Decred network.
|
# "blake256" package is required to sync Decred network.
|
||||||
# "xevan_hash" package is required to sync Xuez network.
|
# "xevan_hash" package is required to sync Xuez network.
|
||||||
install_requires=['aiorpcX == 0.5.6', 'attrs>=15',
|
install_requires=['aiorpcX == 0.5.8', 'attrs>=15',
|
||||||
'plyvel', 'pylru', 'aiohttp >= 2'],
|
'plyvel', 'pylru', 'aiohttp >= 2'],
|
||||||
packages=setuptools.find_packages(include=('electrumx*',)),
|
packages=setuptools.find_packages(include=('electrumx*',)),
|
||||||
description='ElectrumX Server',
|
description='ElectrumX Server',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user