Beispiel #1
0
 def _fetch_bad_node(self, remote: Node) -> Optional[BadNode]:
     enode = remote.uri()
     cursor = self.db.execute('SELECT * from bad_nodes WHERE enode = ?',
                              (enode, ))
     row = cursor.fetchone()
     if not row:
         return None
     result = BadNode(row['enode'], row['until'], row['reason'],
                      row['error_count'])
     return result
Beispiel #2
0
 def record_blacklist(self, remote: Node, timeout_seconds: int,
                      reason: str) -> None:
     try:
         record = self._get_record(remote.uri())
     except NoResultFound:
         expires_at = datetime.datetime.utcnow() + datetime.timedelta(
             seconds=timeout_seconds)
         self._create_record(remote, expires_at, reason)
     else:
         scaled_expires_at = adjust_repeat_offender_timeout(
             timeout_seconds,
             record.error_count + 1,
         )
         self._update_record(remote, scaled_expires_at, reason)
Beispiel #3
0
    def _create_record(self, remote: Node, expires_at: datetime.datetime,
                       reason: str) -> None:
        uri = remote.uri()

        record = BlacklistRecord(uri=uri, expires_at=expires_at, reason=reason)
        self.session.add(record)
        # mypy doesn't know about the type of the `commit()` function
        self.session.commit()  # type: ignore

        usable_delta = expires_at - datetime.datetime.utcnow()
        self.logger.debug(
            '%s will not be retried for %s because %s',
            remote,
            humanize_seconds(usable_delta.total_seconds()),
            reason,
        )
Beispiel #4
0
    def _create_record(self, remote: Node, timeout_seconds: int,
                       reason: str) -> None:
        uri = remote.uri()
        expires_at = datetime.datetime.utcnow() + datetime.timedelta(
            seconds=timeout_seconds)

        record = BlacklistRecord(uri=uri, expires_at=expires_at, reason=reason)
        self.session.add(record)
        # mypy doesn't know about the type of the `commit()` function
        self.session.commit()  # type: ignore

        self.logger.debug(
            '%s will not be retried for %s because %s',
            remote,
            humanize_seconds(timeout_seconds),
            reason,
        )
Beispiel #5
0
    async def should_connect_to(self, remote: Node) -> bool:
        try:
            record = self._get_record(remote.uri())
        except NoResultFound:
            return True

        now = datetime.datetime.utcnow()
        if now < record.expires_at:
            delta = record.expires_at - now
            self.logger.debug(
                'skipping %s, it failed because "%s" and is not usable for %s',
                remote,
                record.reason,
                humanize_seconds(delta.total_seconds()),
            )
            return False

        return True
Beispiel #6
0
    def _record_bad_node(self, remote: Node, timeout: int,
                         reason: str) -> None:
        enode = remote.uri()
        bad_node = self._fetch_bad_node(remote)
        now = datetime.datetime.utcnow()
        if bad_node:
            new_error_count = bad_node.error_count + 1
            usable_time = now + datetime.timedelta(seconds=timeout *
                                                   new_error_count)
            local_time = utc_to_local(usable_time)
            self.logger.debug('%s will not be retried until %s because %s',
                              remote, local_time, reason)
            self._update_bad_node(enode, usable_time, reason, new_error_count)
            return

        usable_time = now + datetime.timedelta(seconds=timeout)
        local_time = utc_to_local(usable_time)
        self.logger.debug('%s will not be retried until %s because %s', remote,
                          local_time, reason)
        self._insert_bad_node(enode, usable_time, reason, error_count=1)
Beispiel #7
0
    def _update_record(self, remote: Node, expires_at: datetime.datetime,
                       reason: str) -> None:
        uri = remote.uri()
        record = self._get_record(uri)

        if expires_at > record.expires_at:
            # only update expiration if it is further in the future than the existing expiration
            record.expires_at = expires_at
        record.reason = reason
        record.error_count += 1

        self.session.add(record)
        # mypy doesn't know about the type of the `commit()` function
        self.session.commit()  # type: ignore

        usable_delta = expires_at - datetime.datetime.utcnow()
        self.logger.debug(
            '%s will not be retried for %s because %s',
            remote,
            humanize_seconds(usable_delta.total_seconds()),
            reason,
        )
Beispiel #8
0
    def _update_record(self, remote: Node, timeout_seconds: int,
                       reason: str) -> None:
        uri = remote.uri()
        record = self._get_record(uri)
        record.error_count += 1

        adjusted_timeout_seconds = int(timeout_seconds *
                                       math.sqrt(record.error_count))
        record.expires_at += datetime.timedelta(
            seconds=adjusted_timeout_seconds)
        record.reason = reason
        record.error_count += 1

        self.session.add(record)
        # mypy doesn't know about the type of the `commit()` function
        self.session.commit()  # type: ignore

        self.logger.debug(
            '%s will not be retried for %s because %s',
            remote,
            humanize_seconds(adjusted_timeout_seconds),
            reason,
        )
Beispiel #9
0
    def track_peer_connection(self, remote: Node, is_outbound: bool,
                              last_connected_at: Optional[datetime.datetime],
                              genesis_hash: Hash32, protocol: str,
                              protocol_version: int, network_id: int) -> None:
        uri = remote.uri()
        now = datetime.datetime.utcnow()

        if self._remote_exists(uri):
            self.logger.debug2("Updated ETH1 peer record: %s", remote)
            record = self._get_remote(uri)

            record.updated_at = now

            if last_connected_at is not None:
                record.last_connected_at = last_connected_at

            record.genesis_hash = genesis_hash.hex()
            record.protocol = protocol
            record.protocol_version = protocol_version
            record.network_id = network_id
        else:
            self.logger.debug2("New ETH1 peer record: %s", remote)
            record = Remote(
                uri=uri,
                is_outbound=is_outbound,
                created_at=now,
                updated_at=now,
                last_connected_at=last_connected_at,
                genesis_hash=genesis_hash.hex(),
                protocol=protocol,
                protocol_version=protocol_version,
                network_id=network_id,
            )

        self.session.add(record)
        self.session.commit()  # type: ignore
Beispiel #10
0
 async def record_blacklist(self, remote: Node, timeout_seconds: int,
                            reason: str) -> None:
     if self._record_exists(remote.uri()):
         self._update_record(remote, timeout_seconds, reason)
     else:
         self._create_record(remote, timeout_seconds, reason)