Example #1
0
 async def on_connect(self, peer: ws.WSChiaConnection):
     if (
         peer.is_outbound is False
         and peer.peer_server_port is not None
         and peer.connection_type is NodeType.FULL_NODE
         and self.server._local_type is NodeType.FULL_NODE
         and self.address_manager is not None
     ):
         timestamped_peer_info = TimestampedPeerInfo(
             peer.peer_host,
             peer.peer_server_port,
             uint64(int(time.time())),
         )
         await self.address_manager.add_to_new_table([timestamped_peer_info], peer.get_peer_info(), 0)
         if self.relay_queue is not None:
             self.relay_queue.put_nowait((timestamped_peer_info, 1))
     if (
         peer.is_outbound
         and peer.peer_server_port is not None
         and peer.connection_type is NodeType.FULL_NODE
         and self.server._local_type is NodeType.FULL_NODE
         and self.address_manager is not None
     ):
         msg = make_msg(ProtocolMessageTypes.request_peers, full_node_protocol.RequestPeers())
         await peer.send_message(msg)
Example #2
0
    async def respond_peers(self, request: introducer_protocol.RespondPeers, peer: WSChiaConnection):
        if not self.wallet_node.has_full_node():
            await self.wallet_node.wallet_peers.respond_peers(request, peer.get_peer_info(), False)
        else:
            await self.wallet_node.wallet_peers.ensure_is_closed()

        if peer is not None and peer.connection_type is NodeType.INTRODUCER:
            await peer.close()
Example #3
0
 async def respond_peers(self, request: full_node_protocol.RespondPeers,
                         peer: WSChiaConnection):
     if not self.wallet_node.has_full_node():
         self.log.info(f"Wallet received {len(request.peer_list)} peers.")
         await self.wallet_node.wallet_peers.respond_peers(
             request, peer.get_peer_info(), True)
     else:
         self.log.info(
             f"Wallet received {len(request.peer_list)} peers, but ignoring, since we have a full node."
         )
         await self.wallet_node.wallet_peers.ensure_is_closed()
     return None
 async def update_peer_timestamp_on_message(self,
                                            peer: ws.WSChiaConnection):
     if (peer.is_outbound and peer.peer_server_port is not None
             and peer.connection_type is NodeType.FULL_NODE
             and self.server._local_type is NodeType.FULL_NODE
             and self.address_manager is not None):
         peer_info = peer.get_peer_info()
         if peer_info.host not in self.connection_time_pretest:
             self.connection_time_pretest[peer_info.host] = time.time()
         if time.time() - self.connection_time_pretest[
                 peer_info.host] > 600:
             self.connection_time_pretest[peer_info.host] = time.time()
             await self.address_manager.connect(peer_info)
Example #5
0
    async def incoming_connection(self, request):
        if request.remote in self.banned_peers and time.time(
        ) < self.banned_peers[request.remote]:
            self.log.warning(
                f"Peer {request.remote} is banned, refusing connection")
            return None
        ws = web.WebSocketResponse(max_msg_size=50 * 1024 * 1024)
        await ws.prepare(request)
        close_event = asyncio.Event()
        cert_bytes = request.transport._ssl_protocol._extra[
            "ssl_object"].getpeercert(True)
        der_cert = x509.load_der_x509_certificate(cert_bytes)
        peer_id = bytes32(der_cert.fingerprint(hashes.SHA256()))
        if peer_id == self.node_id:
            return ws
        connection: Optional[WSChiaConnection] = None
        try:
            connection = WSChiaConnection(
                self._local_type,
                ws,
                self._port,
                self.log,
                False,
                False,
                request.remote,
                self.incoming_messages,
                self.connection_closed,
                peer_id,
                self._inbound_rate_limit_percent,
                self._outbound_rate_limit_percent,
                close_event,
            )
            handshake = await connection.perform_handshake(
                self._network_id,
                protocol_version,
                self._port,
                self._local_type,
            )

            assert handshake is True
            # Limit inbound connections to config's specifications.
            if not self.accept_inbound_connections(connection.connection_type):
                self.log.info(
                    f"Not accepting inbound connection: {connection.get_peer_info()}.Inbound limit reached."
                )
                await connection.close()
                close_event.set()
            else:
                await self.connection_added(connection, self.on_connect)
                if self._local_type is NodeType.INTRODUCER and connection.connection_type is NodeType.FULL_NODE:
                    self.introducer_peers.add(connection.get_peer_info())
        except ProtocolError as e:
            if connection is not None:
                await connection.close(self.invalid_protocol_ban_seconds,
                                       WSCloseCode.PROTOCOL_ERROR, e.code)
            if e.code == Err.INVALID_HANDSHAKE:
                self.log.warning(
                    "Invalid handshake with peer. Maybe the peer is running old software."
                )
                close_event.set()
            elif e.code == Err.INCOMPATIBLE_NETWORK_ID:
                self.log.warning(
                    "Incompatible network ID. Maybe the peer is on another network"
                )
                close_event.set()
            elif e.code == Err.SELF_CONNECTION:
                close_event.set()
            else:
                error_stack = traceback.format_exc()
                self.log.error(
                    f"Exception {e}, exception Stack: {error_stack}")
                close_event.set()
        except Exception as e:
            if connection is not None:
                await connection.close(
                    ws_close_code=WSCloseCode.PROTOCOL_ERROR,
                    error=Err.UNKNOWN)
            error_stack = traceback.format_exc()
            self.log.error(f"Exception {e}, exception Stack: {error_stack}")
            close_event.set()

        await close_event.wait()
        return ws