aboutsummaryrefslogtreecommitdiff
path: root/ouroboros/qos.py
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2026-06-30 18:56:00 +0200
committerDimitri Staessens <dimitri@ouroboros.rocks>2026-06-30 19:05:31 +0200
commita6c2bf9cbfcd3e13569d3a7d915c27d42fb7bbec (patch)
treefe14d51fd2c9b0b1b34420c5bf12683030e2fa38 /ouroboros/qos.py
parent5f2bc27eacafb2b714317dd9cc0f286c774bdb64 (diff)
downloadpyouroboros-a6c2bf9cbfcd3e13569d3a7d915c27d42fb7bbec.tar.gz
pyouroboros-a6c2bf9cbfcd3e13569d3a7d915c27d42fb7bbec.zip
ouroboros: Use QoSService in QoSSpec
Match the use of service instead of the in_order field in Ouroboros.
Diffstat (limited to 'ouroboros/qos.py')
-rw-r--r--ouroboros/qos.py106
1 files changed, 77 insertions, 29 deletions
diff --git a/ouroboros/qos.py b/ouroboros/qos.py
index bb4ecc4..f1b6d11 100644
--- a/ouroboros/qos.py
+++ b/ouroboros/qos.py
@@ -19,40 +19,88 @@
# Foundation, Inc., http://www.fsf.org/about/contact/.
#
-# Some constants
-MILLION = 1000 * 1000
-BILLION = 1000 * 1000 * 1000
+"""QoS specification for Ouroboros flows."""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+from enum import IntEnum
DEFAULT_PEER_TIMEOUT = 120000
UINT32_MAX = 0xFFFFFFFF
+UINT64_MAX = 0xFFFFFFFFFFFFFFFF
+
+
+class QoSService(IntEnum):
+ """Mirrors ``enum qos_service`` in ``ouroboros/qos.h``."""
+ RAW = 0 # No FRCT; best-effort raw messages
+ MESSAGE = 1 # FRCT, reliable ordered messages
+ STREAM = 2 # FRCT, reliable ordered byte stream
+@dataclass(frozen=True)
class QoSSpec:
+ """QoS specification for a flow.
+
+ Frozen so the module-level ``QOS_*`` predefined cubes are safe to
+ share. Construct a new spec with ``dataclasses.replace(qos, ...)``
+ or ``QoSSpec(...)`` to override fields.
+
+ :ivar service: :class:`QoSService` (gates FRCT when > 0).
+ :ivar delay: Maximum one-way delay in ms.
+ :ivar bandwidth: Required bandwidth in bits/s.
+ :ivar availability: Class of 9s (number of nines of uptime).
+ :ivar loss: Maximum packet loss (per million).
+ :ivar ber: Maximum bit error rate (errors per billion).
+ :ivar max_gap: Maximum interruption in ms.
+ :ivar timeout: Peer timeout in ms (default 120000 ms).
"""
- delay: In ms, default UINT32_MAX
- bandwidth: In bits / s, default 0
- availability: Class of 9s, default 0
- loss: Packet loss, default 1
- ber: Bit error rate, errors per billion bits, default 1
- in_order: In-order delivery, enables FRCT, default 0
- max_gap: Maximum interruption in ms, default UINT32_MAX
- timeout: Peer timeout (ms), default 120000 (2 minutes)
- """
+ service: QoSService = QoSService.RAW
+ delay: int = UINT32_MAX
+ bandwidth: int = 0
+ availability: int = 0
+ loss: int = 1
+ ber: int = 1
+ max_gap: int = UINT32_MAX
+ timeout: int = DEFAULT_PEER_TIMEOUT
+
+
+# Predefined QoS specs, mirroring the static const qosspec_t values in
+# ouroboros/qos.h. "_safe" sets ber=0 (integrity check); "rt" trades
+# reliability for latency.
+
+QOS_RAW = QoSSpec(
+ service=QoSService.RAW,
+ delay=UINT32_MAX, bandwidth=0, availability=0,
+ loss=1, ber=1,
+ max_gap=UINT32_MAX, timeout=0)
+
+QOS_RAW_SAFE = QoSSpec(
+ service=QoSService.RAW,
+ delay=UINT32_MAX, bandwidth=0, availability=0,
+ loss=1, ber=0,
+ max_gap=UINT32_MAX, timeout=0)
+
+QOS_RT = QoSSpec(
+ service=QoSService.MESSAGE,
+ delay=100, bandwidth=UINT64_MAX, availability=3,
+ loss=1, ber=1,
+ max_gap=100, timeout=DEFAULT_PEER_TIMEOUT)
+
+QOS_RT_SAFE = QoSSpec(
+ service=QoSService.MESSAGE,
+ delay=100, bandwidth=UINT64_MAX, availability=3,
+ loss=1, ber=0,
+ max_gap=100, timeout=DEFAULT_PEER_TIMEOUT)
+
+QOS_MSG = QoSSpec(
+ service=QoSService.MESSAGE,
+ delay=1000, bandwidth=0, availability=0,
+ loss=0, ber=0,
+ max_gap=2000, timeout=DEFAULT_PEER_TIMEOUT)
- def __init__(self,
- delay: int = UINT32_MAX,
- bandwidth: int = 0,
- availability: int = 0,
- loss: int = 1,
- ber: int = 1,
- in_order: int = 0,
- max_gap: int = UINT32_MAX,
- timeout: int = DEFAULT_PEER_TIMEOUT):
- self.delay = delay
- self.bandwidth = bandwidth
- self.availability = availability
- self.loss = loss
- self.ber = ber
- self.in_order = in_order
- self.max_gap = max_gap
- self.timeout = timeout
+QOS_STREAM = QoSSpec(
+ service=QoSService.STREAM,
+ delay=1000, bandwidth=0, availability=0,
+ loss=0, ber=0,
+ max_gap=2000, timeout=DEFAULT_PEER_TIMEOUT)