Skip to content

(CTTC) Fix optical slot codec in Context DB

Reporters

  • Lluis Gifre (CTTC)
  • Andrea Sgambelluri (CNIT)

Description

The encoding of optical slots in OpticalLinkModel is wrong. The main defect is that the bind path does not map bits by slot index; it serializes whatever order the dictionary happens to have. See details below.

Deployment environment

All

TFS deployment settings

All involving optical controller

Sequence of actions that resulted in the bug

Run whatever scenario that involves Optical Controller.

Document the explicit error

  1. High severity: process_bind_param() ignores slot numbers and encodes only dict iteration order, so sparse or unordered inputs round-trip incorrectly. src/context/service/database/models/Slot.py:20 iterates value.items() and appends only each val bit. The keys are never used to place the bit in the correct position. Example: for C-band, input {"2": 1} is encoded as binary 1, stored as integer 1, then decoded by src/context/service/database/models/Slot.py:40 into a 20-bit map where only slot 20 is set, not slot 2. That is a data corruption bug, not just a formatting issue.

  2. High severity: even with full maps, the encoding depends on insertion order instead of numeric slot order. src/context/service/database/models/Slot.py:23 assumes the caller already inserted keys in the exact intended bit order. If the input dict arrives as {"10": 1, "2": 0, ...} or from any source where map ordering is unstable, the stored integer changes even though the logical slot map is the same. For a binary packing format, that is not safe.

  3. Medium severity: nullable columns can raise UnboundLocalError in both bind and result conversion. src/context/service/database/models/Slot.py:20 returns int_num even when value is None, but int_num is only assigned inside the if. The same pattern exists in src/context/service/database/models/Slot.py:28, src/context/service/database/models/Slot.py:40, src/context/service/database/models/Slot.py:55, and src/context/service/database/models/Slot.py:70. Since the model columns are nullable in src/context/service/database/models/OpticalLinkModel.py:38, this should return None, not an unbound local.

  4. Medium severity: the decoder hardcodes a 20-bit width, but the encoder does not validate width or key range. src/context/service/database/models/Slot.py:45, src/context/service/database/models/Slot.py:60, and src/context/service/database/models/Slot.py:75 assume 20 bits per band. But src/context/service/database/models/Slot.py:20 will happily encode any number of entries and any keys. If a caller passes too many entries or out-of-band keys, the integer is accepted and the decoded map becomes nonsensical.

  5. When running Optical Controller with large spectrum widths, the following NumericValueOutOfRange error arises:

sqlalchemy.exc.DataError: (psycopg2.errors.NumericValueOutOfRange) numeric constant out of int64 range
[SQL: INSERT INTO opticallink (opticallink_uuid, name, created_at, updated_at, length, src_port, dst_port, local_peer_port, remote_peer_port, used, c_slots, l_slots, s_slots) VALUES (%(opticallink_uuid_m0)s, %(name_m0)s, %(created_at_m0)s, %(updated_at_m0)s, %(length_m0)s, %(src_port_m0)s, %(dst_port_m0)s, %(local_peer_port_m0)s, %(remote_peer_port_m0)s, %(used_m0)s, %(c_slots_m0)s, %(l_slots_m0)s, %(s_slots_m0)s) ON CONFLICT (opticallink_uuid) DO UPDATE SET updated_at = excluded.updated_at, src_port = excluded.src_port, dst_port = excluded.dst_port, local_peer_port = excluded.local_peer_port, remote_peer_port = excluded.remote_peer_port, used = excluded.used, c_slots = excluded.c_slots, l_slots = excluded.l_slots, s_slots = excluded.s_slots RETURNING opticallink.created_at, opticallink.updated_at]
[parameters: {'opticallink_uuid_m0': UUID('eed923ea-b95c-50ba-9218-29d972fac0d3'), 'name_m0': 'MGON3-T2.1', 'created_at_m0': datetime.datetime(2026, 4, 14, 18, 32, 46, 254395, tzinfo=datetime.timezone.utc), 'updated_at_m0': datetime.datetime(2026, 4, 14, 18, 32, 46, 254395, tzinfo=datetime.timezone.utc), 'length_m0': 0.0, 'src_port_m0': 'port-33-out', 'dst_port_m0': '1', 'local_peer_port_m0': 'port-33-in', 'remote_peer_port_m0': '1', 'used_m0': False, 'c_slots_m0': 2135987035889811017307695730503490360232835277722052645468830840757852956580569191431416649351167, 'l_slots_m0': 3685510180489786476798393145496356338786055879312930105836138965083617346086082863365358130056307390177215209990980317284932211552660930305235775636164742230126362623, 's_slots_m0': 5515652263101987298728728207430913795608113109085112352897269396216198887424215820128660001943808587833784893551335930816647064191168732319583111500951066614122648616177179922993422016587311577585463592732098692120575}]

Expected behaviour

Fix the error and properly handle the coding of spectrum occupancy.

Acknowledgements

This work is funded by the European Commission through the HORIZON-JU-SNS-2023 PROTEUS-6G project with Grant Agreement number 101139134.