Hello all,
When running rnsd 1.4.0 locally, I frequently see the following error in the logs:
[Error] Error while handling path request. The contained exception was: division by zero

And today, I would like to know where it comes from... I did a small investigation.
The message seems to be emitted by Transport.path_request_handler() @ https://github.com/markqvist/Reticulum/blob/b2188ce9a746a35b770b10bea1b7ccbe93b4e198/RNS/Transport.py#L2996
The handler itself does not appear to contain any division that could cause a ZeroDivisionError. We need to dig deeper. The exception seems to originate from one of the functions called inside the handler and then bubble up to its broad try/except block.
The relevant call chain appears to be:
Transport.path_request_handler()
└── Transport.path_request()
└── Transport.request_path(..., recursive=True)
When a path is unknown and recursive path discovery is enabled, Transport.path_request() forwards the request to other interfaces:
Transport.request_path(
destination_hash,
on_interface=interface,
tag=tag,
recursive=True,
)
Inside Transport.request_path(), the recursive path-request rate limiting contains 2 possible divisions by 0:
tx_time = (
(len(path_request_data) + RNS.Reticulum.HEADER_MINSIZE) * 8
) / on_interface.bitrate
wait_time = tx_time / on_interface.announce_cap
This suggests that the error may occur when either:
on_interface.bitrate == 0
or:
on_interface.announce_cap == 0
The default values should normally be non-zero: the base interface bitrate defaults to 62500, and the global announce cap defaults to 2. It therefore seems possible that one particular interface implementation or configuration overrides one of these values with zero. None of these directive are modified in my local config either.
At this stage, this is still only the most likely explanation. It does not log the traceback, so the exact failing line is lost.
Logging the interface values immediately before the calculations in Transport.request_path() could identify the affected interface:
RNS.log(
f"Recursive path request on {on_interface}: "
f"bitrate={on_interface.bitrate}, "
f"announce_cap={on_interface.announce_cap}",
RNS.LOG_ERROR,
)
Has anyone else encountered this already ?
I would also be interested to know whether an interface can legitimately have a bitrate or announce cap of 0, or whether these values should be validated before the rate-limiting calculations.