Commit fc3d3b99 authored by juga's avatar juga
Browse files

fix: v3bwfile: network means by relay type

Calculate network stream and filtered bandwidth averages per relay
type, to obtain bandwidth weights the same way as Torflow.

Closes #40059.
parent bd57e473
...@@ -187,6 +187,14 @@ MAX_RECENT_PRIORITY_RELAY_COUNT = ( ...@@ -187,6 +187,14 @@ MAX_RECENT_PRIORITY_RELAY_COUNT = (
MAX_RECENT_PRIORITY_LIST_COUNT * MAX_RELAYS_PER_PRIORITY_LIST MAX_RECENT_PRIORITY_LIST_COUNT * MAX_RELAYS_PER_PRIORITY_LIST
) )
# Used by util/stem.py
G = 0
M = 1
E = 2
GE = 3
# Used by lib/scaling.py to calculate network means by relay type
RELAY_TYPES = [G, M, E, GE]
def fail_hard(*a, **kw): def fail_hard(*a, **kw):
''' Log something ... and then exit as fast as possible ''' ''' Log something ... and then exit as fast as possible '''
......
from statistics import mean from statistics import mean
from sbws.globals import RELAY_TYPES
from sbws.util.stem import rs_relay_type
def bw_measurements_from_results(results): def bw_measurements_from_results(results):
return [ return [
......
...@@ -985,6 +985,11 @@ class V3BWLine(object): ...@@ -985,6 +985,11 @@ class V3BWLine(object):
len(bw_line_str), BW_LINE_SIZE) len(bw_line_str), BW_LINE_SIZE)
return bw_line_str return bw_line_str
def set_relay_type(self, relay_type):
self.relay_type = relay_type
def del_relay_type(self):
delattr(self, "relay_type")
class V3BWFile(object): class V3BWFile(object):
""" """
...@@ -1226,12 +1231,11 @@ class V3BWFile(object): ...@@ -1226,12 +1231,11 @@ class V3BWFile(object):
""" """
log.info("Calculating relays' bandwidth using Torflow method.") log.info("Calculating relays' bandwidth using Torflow method.")
bw_lines_tf = copy.deepcopy(bw_lines) bw_lines_tf = copy.deepcopy(bw_lines)
# mean (Torflow's strm_avg) mu_type, muf_type = scaling.network_means_by_relay_type(
mu = mean([l.bw_mean for l in bw_lines]) bw_lines_tf, router_statuses_d
# filtered mean (Torflow's filt_avg) )
muf = mean([l.bw_filt for l in bw_lines]) log.debug('mu %s', mu_type)
log.debug('mu %s', mu) log.debug('muf %s', muf_type)
log.debug('muf %s', muf)
# Torflow's ``tot_net_bw``, sum of the scaled bandwidth for the relays # Torflow's ``tot_net_bw``, sum of the scaled bandwidth for the relays
# that are in the last consensus # that are in the last consensus
...@@ -1292,10 +1296,12 @@ class V3BWFile(object): ...@@ -1292,10 +1296,12 @@ class V3BWFile(object):
continue continue
# Torflow's scaling # Torflow's scaling
ratio_stream = l.bw_mean / mu # relay_type is set in `network_means_by_relay_type` in the lines
ratio_stream_filtered = l.bw_filt / muf # above
ratio_stream = l.bw_mean / mu_type[l.relay_type]
ratio_stream_filtered = l.bw_filt / muf_type[l.relay_type]
l.del_relay_type()
ratio = max(ratio_stream, ratio_stream_filtered) ratio = max(ratio_stream, ratio_stream_filtered)
# Assign it to an attribute, so it's not lost before capping and # Assign it to an attribute, so it's not lost before capping and
# rounding # rounding
l.bw = ratio * min_bandwidth l.bw = ratio * min_bandwidth
......
...@@ -12,9 +12,11 @@ import logging ...@@ -12,9 +12,11 @@ import logging
import os import os
from sbws.globals import fail_hard from sbws.globals import fail_hard
from sbws.globals import (TORRC_STARTING_POINT, TORRC_RUNTIME_OPTIONS, from sbws.globals import (TORRC_STARTING_POINT, TORRC_RUNTIME_OPTIONS,
TORRC_OPTIONS_CAN_FAIL) TORRC_OPTIONS_CAN_FAIL, G, M, E, GE)
from sbws import settings from sbws import settings
from stem import Flag
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
stream_building_lock = RLock() stream_building_lock = RLock()
...@@ -325,3 +327,21 @@ def is_torrc_starting_point_set(tor_controller): ...@@ -325,3 +327,21 @@ def is_torrc_starting_point_set(tor_controller):
if not bad_options: if not bad_options:
log.info("Tor is correctly configured to work with sbws.") log.info("Tor is correctly configured to work with sbws.")
return bad_options return bad_options
def rs_relay_type(rs):
# In torflow, the equivalent to the bw_lines is initialized to "", so when
# the relay is not in the previous consensus and it is not known which
# flags it has, it would return "Medium", as it's the fail case in
# Node.node_class().
# It is not known if it is a bug, or a desired side effect that they relays
# not in the consensus will end up in the Middle class
if not rs:
return M
if Flag.EXIT in rs.flags and Flag.GUARD in rs.flags:
return GE
if Flag.GUARD in rs.flags:
return G
if Flag.EXIT in rs.flags:
return E
return M
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment