Browse Source

Ignore potential sybil peers

patch-2
Neil Booth 6 years ago
parent
commit
a9d50671e7
  1. 41
      electrumx/server/peers.py

41
electrumx/server/peers.py

@ -17,7 +17,7 @@ from collections import defaultdict, Counter
from aiorpcx import (Connector, RPCSession, SOCKSProxy, from aiorpcx import (Connector, RPCSession, SOCKSProxy,
Notification, handler_invocation, Notification, handler_invocation,
SOCKSError, RPCError, TaskTimeout, TaskGroup, Event, SOCKSError, RPCError, TaskTimeout, TaskGroup, Event,
sleep, run_in_thread, ignore_after, timeout_after) sleep, ignore_after, timeout_after)
from electrumx.lib.peer import Peer from electrumx.lib.peer import Peer
from electrumx.lib.util import class_logger, protocol_tuple from electrumx.lib.util import class_logger, protocol_tuple
@ -152,22 +152,28 @@ class PeerManager(object):
self.logger.info('no proxy detected, will try later') self.logger.info('no proxy detected, will try later')
await sleep(900) await sleep(900)
async def _note_peers(self, peers, limit=2, check_ports=False, async def _note_peers(self, peers, limit=2, check_ports=False, check_matches=False,
source=None): source=None):
'''Add a limited number of peers that are not already present.''' '''Add a limited number of peers that are not already present.'''
new_peers = [] new_peers = []
known = []
for peer in peers: for peer in peers:
if not peer.is_public or (peer.is_tor and not self.proxy): if not peer.is_public or (peer.is_tor and not self.proxy):
continue continue
matches = peer.matches(self.peers) matches = peer.matches(self.peers)
if not matches: if matches:
known.append(peer)
if check_ports:
for match in matches:
if match.check_ports(peer):
self.logger.info(f'ports changed for {peer}')
match.retry_event.set()
else:
new_peers.append(peer) new_peers.append(peer)
elif check_ports:
for match in matches: if check_matches and len(self.peers) >= 6 and len(known) <= len(self.peers) // 2:
if match.check_ports(peer): return False
self.logger.info(f'ports changed for {peer}')
match.retry_event.set()
if new_peers: if new_peers:
source = source or new_peers[0].source source = source or new_peers[0].source
@ -182,6 +188,8 @@ class PeerManager(object):
self.peers.add(peer) self.peers.add(peer)
await self.group.spawn(self._monitor_peer(peer)) await self.group.spawn(self._monitor_peer(peer))
return True
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:
@ -299,12 +307,14 @@ class PeerManager(object):
# Process reported peers if remote peer is good # Process reported peers if remote peer is good
peers = peers_task.result() peers = peers_task.result()
await self._note_peers(peers) if await self._note_peers(peers, check_matches=True):
features = self._features_to_register(peer, peers) features = self._features_to_register(peer, peers)
if features: if features:
self.logger.info(f'registering ourself with {peer}') self.logger.info(f'registering ourself with {peer}')
# We only care to wait for the response # We only care to wait for the response
await session.send_request('server.add_peer', [features]) await session.send_request('server.add_peer', [features])
else:
raise BadPeerError('potential sybil detected')
async def _send_headers_subscribe(self, session, peer, ptuple): async def _send_headers_subscribe(self, session, peer, ptuple):
message = 'blockchain.headers.subscribe' message = 'blockchain.headers.subscribe'
@ -446,8 +456,7 @@ class PeerManager(object):
reason = 'source-destination mismatch' reason = 'source-destination mismatch'
if permit: if permit:
self.logger.info(f'accepted add_peer request from {source} ' self.logger.info(f'accepted add_peer request from {source} for {host}')
f'for {host}')
await self._note_peers([peer], check_ports=True) await self._note_peers([peer], check_ports=True)
else: else:
self.logger.warning(f'rejected add_peer request from {source} ' self.logger.warning(f'rejected add_peer request from {source} '

Loading…
Cancel
Save