mirror of
https://github.com/pyMC-dev/pyMC_Repeater.git
synced 2026-07-28 04:23:22 +02:00
fix: tolerate openhop_core without QueuedMessage.sender_prefix
Installed openhop_core releases predating the sender_prefix change
(paired with fd43d86) reject the kwarg, so restoring queued messages
raised TypeError and aborted companion init. Detect support via the
QueuedMessage signature and drop persisted prefixes with a warning on
older cores instead of failing the boot.
This commit is contained in:
+23
-11
@@ -1,5 +1,6 @@
|
||||
import asyncio
|
||||
import functools
|
||||
import inspect
|
||||
import logging
|
||||
import os
|
||||
import signal
|
||||
@@ -780,6 +781,17 @@ class RepeaterDaemon:
|
||||
limit=retention or 100,
|
||||
)
|
||||
loaded_messages = len(message_rows)
|
||||
# openhop_core < the sender_prefix change (paired with fd43d86) has no
|
||||
# QueuedMessage.sender_prefix; drop the prefix there instead of failing init.
|
||||
supports_sender_prefix = "sender_prefix" in inspect.signature(QueuedMessage).parameters
|
||||
if message_rows and not supports_sender_prefix:
|
||||
logger.warning(
|
||||
"Companion %s ('%s'): installed openhop_core QueuedMessage has no "
|
||||
"sender_prefix field; persisted sender prefixes will be dropped "
|
||||
"(update openhop_core to restore signed room-post authors)",
|
||||
companion_hash_str,
|
||||
name,
|
||||
)
|
||||
for msg_dict in message_rows:
|
||||
sk = msg_dict.get("sender_key", b"")
|
||||
if isinstance(sk, str):
|
||||
@@ -787,18 +799,18 @@ class RepeaterDaemon:
|
||||
sp = msg_dict.get("sender_prefix", b"")
|
||||
if isinstance(sp, str):
|
||||
sp = bytes.fromhex(sp) if sp else b""
|
||||
bridge.message_queue.push(
|
||||
QueuedMessage(
|
||||
sender_key=sk,
|
||||
txt_type=msg_dict.get("txt_type", 0),
|
||||
timestamp=msg_dict.get("timestamp", 0),
|
||||
text=msg_dict.get("text", ""),
|
||||
is_channel=bool(msg_dict.get("is_channel", False)),
|
||||
channel_idx=msg_dict.get("channel_idx", 0),
|
||||
path_len=msg_dict.get("path_len", 0),
|
||||
sender_prefix=sp,
|
||||
)
|
||||
msg_kwargs = dict(
|
||||
sender_key=sk,
|
||||
txt_type=msg_dict.get("txt_type", 0),
|
||||
timestamp=msg_dict.get("timestamp", 0),
|
||||
text=msg_dict.get("text", ""),
|
||||
is_channel=bool(msg_dict.get("is_channel", False)),
|
||||
channel_idx=msg_dict.get("channel_idx", 0),
|
||||
path_len=msg_dict.get("path_len", 0),
|
||||
)
|
||||
if supports_sender_prefix:
|
||||
msg_kwargs["sender_prefix"] = sp
|
||||
bridge.message_queue.push(QueuedMessage(**msg_kwargs))
|
||||
|
||||
logger.info(
|
||||
"Companion %s ('%s'): restored %d/%d contact(s), %d/%d channel(s), "
|
||||
|
||||
@@ -128,6 +128,41 @@ class TestRestoreCompanionState:
|
||||
await daemon._restore_companion_state(sqlite, bridge, _HASH, _NAME)
|
||||
assert any("rejected persisted channel" in r.message for r in caplog.records)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_old_core_without_sender_prefix_drops_prefix(self, caplog):
|
||||
# openhop_core releases before the sender_prefix change reject the kwarg;
|
||||
# message restore must degrade (drop the prefix) instead of failing init.
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
@dataclass
|
||||
class LegacyQueuedMessage:
|
||||
sender_key: bytes = b""
|
||||
txt_type: int = 0
|
||||
timestamp: int = 0
|
||||
text: str = ""
|
||||
is_channel: bool = False
|
||||
channel_idx: int = 0
|
||||
path_len: int = 0
|
||||
snr: float = 0.0
|
||||
rssi: int = 0
|
||||
channel_data_payload: bytes = field(default=b"")
|
||||
|
||||
daemon = self._daemon()
|
||||
bridge = self._bridge()
|
||||
sqlite = self._sqlite(
|
||||
messages=[{"sender_key": b"", "text": "hi", "sender_prefix": b"\xab\xcd"}]
|
||||
)
|
||||
with (
|
||||
patch("openhop_core.companion.models.QueuedMessage", LegacyQueuedMessage),
|
||||
caplog.at_level(logging.WARNING),
|
||||
):
|
||||
await daemon._restore_companion_state(sqlite, bridge, _HASH, _NAME)
|
||||
bridge.message_queue.push.assert_called_once()
|
||||
pushed = bridge.message_queue.push.call_args[0][0]
|
||||
assert isinstance(pushed, LegacyQueuedMessage)
|
||||
assert pushed.text == "hi"
|
||||
assert any("sender prefixes will be dropped" in r.message for r in caplog.records)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_zero_retention_skips_message_load(self):
|
||||
daemon = self._daemon()
|
||||
|
||||
Reference in New Issue
Block a user