fix conn stats registering and remove meter_interval

This commit is contained in:
Youngjoon Lee 2024-07-04 12:01:51 +09:00
parent 515bc2c50a
commit a0da12a93a
No known key found for this signature in database
GPG Key ID: B4253AFBA618BF4D
4 changed files with 30 additions and 28 deletions

View File

@ -34,13 +34,23 @@ class SimulationConfig:
time_scale: float
duration_sec: int
net_latency_sec: float
meter_interval_sec: float
def validate(self):
assert self.time_scale > 0
assert self.duration_sec > 0
assert self.net_latency_sec > 0
assert self.meter_interval_sec > 0
def scale_time(self, time: float) -> float:
return time * self.time_scale
def scale_rate(self, rate: int) -> float:
return float(rate / self.time_scale)
def scaled_duration(self) -> float:
return self.scale_time(self.duration_sec)
def scaled_net_latency(self) -> float:
return self.scale_time(self.net_latency_sec)
@dataclass

View File

@ -2,8 +2,6 @@ simulation:
time_scale: 0.001
duration_sec: 10000
net_latency_sec: 0.01
meter_interval_sec: 1
logic:
lottery_interval_sec: 1

View File

@ -5,11 +5,11 @@ import time
import pandas
from mixnet.connection import SimplexConnection
from mixnet.sim.config import SimulationConfig
class MeteredRemoteSimplexConnection(SimplexConnection):
latency: float
meter_interval: float
config: SimulationConfig
outputs: asyncio.Queue
conn: asyncio.Queue
inputs: asyncio.Queue
@ -18,9 +18,8 @@ class MeteredRemoteSimplexConnection(SimplexConnection):
input_task: asyncio.Task
input_meters: list[int]
def __init__(self, latency: float, meter_interval: float):
self.latency = latency
self.meter_interval = meter_interval
def __init__(self, config: SimulationConfig):
self.config = config
self.outputs = asyncio.Queue()
self.conn = asyncio.Queue()
self.inputs = asyncio.Queue()
@ -45,13 +44,13 @@ class MeteredRemoteSimplexConnection(SimplexConnection):
async def __run_input_task(self):
start_time = time.time()
while True:
await asyncio.sleep(self.latency)
await asyncio.sleep(self.config.scaled_net_latency())
data = await self.conn.get()
self.__update_meter(self.input_meters, len(data), start_time)
await self.inputs.put(data)
def __update_meter(self, meters: list[int], size: int, start_time: float):
slot = math.floor((time.time() - start_time) / self.meter_interval)
slot = math.floor((time.time() - start_time) / self.config.time_scale)
assert slot >= len(meters) - 1
meters.extend([0] * (slot - len(meters) + 1))
meters[-1] += size
@ -63,6 +62,4 @@ class MeteredRemoteSimplexConnection(SimplexConnection):
return self.__bandwidths(self.input_meters)
def __bandwidths(self, meters: list[int]) -> pandas.Series:
return pandas.Series(meters, name="bandwidth").map(
lambda x: x / self.meter_interval
)
return pandas.Series(meters, name="bandwidth")

View File

@ -17,7 +17,7 @@ class Simulation:
async def run(self):
nodes, conn_measurement = self.init_nodes()
deadline = time.time() + self.scaled_time(self.config.simulation.duration_sec)
deadline = time.time() + self.config.simulation.scaled_duration()
tasks: list[asyncio.Task] = []
for node in nodes:
tasks.append(asyncio.create_task(self.run_logic(node, deadline)))
@ -34,7 +34,9 @@ class Simulation:
for node_config in node_configs
]
),
self.scaled_rate(self.config.mixnet.transmission_rate_per_sec),
self.config.simulation.scale_rate(
self.config.mixnet.transmission_rate_per_sec
),
self.config.mixnet.max_mix_path_length,
)
nodes = [Node(node_config, global_config) for node_config in node_configs]
@ -42,28 +44,23 @@ class Simulation:
conn_stats = ConnectionStats()
for i, node in enumerate(nodes):
inbound_conn, outbound_conn = self.create_conn(), self.create_conn()
node.connect(nodes[(i + 1) % len(nodes)], inbound_conn, outbound_conn)
peer = nodes[(i + 1) % len(nodes)]
node.connect(peer, inbound_conn, outbound_conn)
conn_stats.register(node, inbound_conn, outbound_conn)
conn_stats.register(peer, outbound_conn, inbound_conn)
return nodes, conn_stats
def create_conn(self) -> MeteredRemoteSimplexConnection:
return MeteredRemoteSimplexConnection(
latency=self.scaled_time(self.config.simulation.net_latency_sec),
meter_interval=self.scaled_time(self.config.simulation.meter_interval_sec),
)
return MeteredRemoteSimplexConnection(self.config.simulation)
async def run_logic(self, node: Node, deadline: float):
while time.time() < deadline:
await asyncio.sleep(
self.scaled_time(self.config.logic.lottery_interval_sec)
self.config.simulation.scale_time(
self.config.logic.lottery_interval_sec
)
)
if random.random() < self.config.logic.sender_prob:
await node.send_message(b"selected block")
def scaled_time(self, time: float) -> float:
return time * self.config.simulation.time_scale
def scaled_rate(self, rate: int) -> float:
return float(rate / self.config.simulation.time_scale)