from __future__ import annotations import os from dataclasses import dataclass from functools import lru_cache SCHEMA_VERSION = "v1" def _env_int(name: str, default: int) -> int: try: return int(os.getenv(name, default)) except Exception: return default def _env_float(name: str, default: float) -> float: try: return float(os.getenv(name, default)) except Exception: return default @dataclass(frozen=True) class DHTConfig: """Runtime configuration for the decentralized storage layer.""" schema_version: str = SCHEMA_VERSION min_receipts: int = _env_int("DHT_MIN_RECEIPTS", 5) min_reachability_ratio: float = _env_float("DHT_MIN_REACHABILITY", 0.6) membership_ttl: int = _env_int("DHT_MEMBERSHIP_TTL", 600) replication_target: int = max(3, _env_int("DHT_REPLICATION_TARGET", 3)) lease_ttl: int = _env_int("DHT_LEASE_TTL", 600) heartbeat_interval: int = _env_int("DHT_HEARTBEAT_INTERVAL", 60) heartbeat_miss_threshold: int = _env_int("DHT_HEARTBEAT_MISS_THRESHOLD", 3) rendezvous_base: str = os.getenv("DHT_RENDEZVOUS_HASH", "blake3") pow_difficulty: int = _env_int("DHT_POW_DIFFICULTY", 4) min_asn_diversity: int = _env_int("DHT_MIN_ASN", 3) min_ip_octet_diversity: int = _env_int("DHT_MIN_IP_OCTETS", 3) window_size: int = _env_int("DHT_METRIC_WINDOW_SEC", 3600) default_q: float = _env_float("DHT_MIN_Q", 0.6) seed_refresh_interval: int = _env_int("DHT_SEED_REFRESH_INTERVAL", 30) @lru_cache def load_config() -> DHTConfig: """Load configuration with process-wide memoisation.""" return DHTConfig() dht_config = load_config()