nomos-specs/mixnet/sim/config.py

117 lines
2.4 KiB
Python
Raw Normal View History

2024-07-03 23:29:26 +09:00
from __future__ import annotations
2024-07-05 17:01:11 +09:00
import hashlib
import random
2024-07-03 23:29:26 +09:00
from dataclasses import dataclass
import dacite
import yaml
from pysphinx.sphinx import X25519PrivateKey
from mixnet.config import NodeConfig
@dataclass
class Config:
simulation: SimulationConfig
logic: LogicConfig
mixnet: MixnetConfig
@classmethod
def load(cls, yaml_path: str) -> Config:
with open(yaml_path, "r") as f:
data = yaml.safe_load(f)
2024-07-05 17:01:11 +09:00
config = dacite.from_dict(
data_class=Config,
data=data,
config=dacite.Config(type_hooks={random.Random: seed_to_random}),
)
2024-07-03 23:29:26 +09:00
# Validations
config.simulation.validate()
config.logic.validate()
config.mixnet.validate()
return config
@dataclass
class SimulationConfig:
duration_sec: int
net_latency_sec: float
def validate(self):
assert self.duration_sec > 0
assert self.net_latency_sec > 0
2024-07-03 23:29:26 +09:00
@dataclass
class LogicConfig:
2024-07-05 17:01:11 +09:00
sender_lottery: LotteryConfig
2024-07-03 23:29:26 +09:00
def validate(self):
2024-07-05 17:01:11 +09:00
self.sender_lottery.validate()
@dataclass
class LotteryConfig:
interval_sec: float
probability: float
seed: random.Random
def validate(self):
assert self.interval_sec > 0
assert self.probability > 0
assert self.seed is not None
2024-07-03 23:29:26 +09:00
@dataclass
class MixnetConfig:
num_nodes: int
transmission_rate_per_sec: int
2024-07-05 17:01:11 +09:00
peering: PeeringConfig
mix_path: MixPathConfig
2024-07-03 23:29:26 +09:00
def validate(self):
assert self.num_nodes > 0
assert self.transmission_rate_per_sec > 0
2024-07-05 17:01:11 +09:00
self.peering.validate()
self.mix_path.validate()
2024-07-03 23:29:26 +09:00
def node_configs(self) -> list[NodeConfig]:
return [
NodeConfig(
2024-07-05 17:01:11 +09:00
self._gen_private_key(i),
self.peering.degree,
2024-07-03 23:29:26 +09:00
self.transmission_rate_per_sec,
)
2024-07-05 17:01:11 +09:00
for i in range(self.num_nodes)
2024-07-03 23:29:26 +09:00
]
2024-07-05 17:01:11 +09:00
def _gen_private_key(self, node_idx: int) -> X25519PrivateKey:
return X25519PrivateKey.from_private_bytes(
hashlib.sha256(node_idx.to_bytes(4, "big")).digest()[:32]
)
@dataclass
class PeeringConfig:
degree: int
def validate(self):
assert self.degree > 0
@dataclass
class MixPathConfig:
max_length: int
seed: random.Random
def validate(self):
assert self.max_length > 0
assert self.seed is not None
def seed_to_random(seed: int) -> random.Random:
return random.Random(seed)