Source code for onbasca.base.models.relaydesc
# SPDX-FileCopyrightText: 2022 The Tor Project, Inc.
#
# SPDX-License-Identifier: BSD-3-Clause
import logging
from django.db import models
from . import BaseModel
logger = logging.getLogger(__name__)
[docs]
class RelayDescManagerBase(models.Manager):
[docs]
def from_relay_desc(self, relay_desc, **kwargs):
kwargs.update(
{
"ed25519_master_key": relay_desc.ed25519_master_key,
"published": relay_desc.published,
"nickname": relay_desc.nickname,
"observed_bandwidth": relay_desc.observed_bandwidth,
"average_bandwidth": relay_desc.average_bandwidth,
"burst_bandwidth": relay_desc.burst_bandwidth,
"can_exit_443": relay_desc.exit_policy.strip_private().can_exit_to( # noqa: E501
port=443
),
"_can_exit_443_strict": (
relay_desc.exit_policy.strip_private().can_exit_to(
port=443, strict=True
)
),
"_can_exit_v6_443": None,
"_uptime": relay_desc.uptime,
}
)
try:
kwargs["_can_exit_v6_443"] = relay_desc.exit_policy_v6.can_exit_to(
port=443
)
except Exception as e:
logger.exception(e)
kwargs = dict(filter(lambda kv: kv[1] is not None, kwargs.items()))
rd, _ = self.update_or_create(
fingerprint=relay_desc.fingerprint, defaults=kwargs
)
rd.set_min_bandwidth()
return rd
[docs]
class RelayDescBase(BaseModel):
objects = RelayDescManagerBase()
fingerprint = models.CharField(max_length=40)
# Relay ForeignKey is not defined here, but in non abstract classes.
published = models.DateTimeField(editable=True, null=True, blank=True)
ed25519_master_key = models.CharField(
max_length=255, null=True, blank=True
)
nickname = models.CharField(max_length=255, null=True, blank=True)
observed_bandwidth = models.PositiveIntegerField(null=True, blank=True)
average_bandwidth = models.PositiveIntegerField(null=True, blank=True)
burst_bandwidth = models.PositiveIntegerField(null=True, blank=True)
_min_bandwidth = models.PositiveIntegerField(null=True, blank=True)
can_exit_443 = models.BooleanField(null=True, blank=True)
_can_exit_443_strict = models.BooleanField(null=True, blank=True)
_can_exit_v6_443 = models.BooleanField(null=True, blank=True)
_uptime = models.PositiveIntegerField(null=True, blank=True)
def __str__(self):
return str(self.relay)
# def save(self, *args, **kwargs):
# super().save(*args, **kwargs)
# self.set_min_bandwidth()
[docs]
def set_min_bandwidth(self):
self._min_bandwidth = min(
self.observed_bandwidth or 0,
self.average_bandwidth or 0,
self.burst_bandwidth or 0,
)
# #41: This will be logged by the scanner.
if self.observed_bandwidth == 0:
logger.info(
"Descriptor observed bandwidth for relay %s (%s), published "
"on %s is 0.",
self.fingerprint,
self.nickname,
self.published,
)
self.save()
return self._min_bandwidth