diff --git a/.github/actions/setup-dev-environment/action.yml b/.github/actions/setup-dev-environment/action.yml index d97fb175..e3ecfcfd 100644 --- a/.github/actions/setup-dev-environment/action.yml +++ b/.github/actions/setup-dev-environment/action.yml @@ -50,9 +50,9 @@ runs: if command -v python >/dev/null 2>&1; then py=python fi - if "$py" -m pip install --user 'rns>=1.3.9' 2>/dev/null; then + if "$py" -m pip install --user 'rns>=1.4.0' 2>/dev/null; then : - elif "$py" -m pip install --user --break-system-packages 'rns>=1.3.9' 2>/dev/null; then + elif "$py" -m pip install --user --break-system-packages 'rns>=1.4.0' 2>/dev/null; then : else echo "WARNING: could not install rnid via pip (tree verify may be skipped)" >&2 diff --git a/CHANGELOG.md b/CHANGELOG.md index ada7a46d..24ff5abb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ All notable changes to this project will be documented in this file. - LXMFy 1.6.5 vendor refresh, wasmtime, mutation test tasks - Network visualiser WebGL + WASM renderer (vis-network fallback) and Settings renderer preference - Interfaces: internal mode, recursive path requests, announces-from-internal, discovery location command, and Backbone fast-flapping options (RNS 1.3.7 to 1.3.9) +- Dependencies: **RNS** 1.4.0 and **LXMF** 1.1.0, with local propagation node controls for sequential stamp validation, static-peer bypass, max inbound syncs, transfer size reporting, and inbound delivery cancel ### Changed diff --git a/android/app/build.gradle b/android/app/build.gradle index af4797d4..37678117 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -13,7 +13,7 @@ def pythonTempDir = new File(buildDir, "python-tmp") def vendorWheelDir = new File(rootProject.projectDir, "vendor") def lxstPatchedWheel = new File(rootProject.projectDir, "vendor/lxst-0.4.8-py3-none-any.whl") def bleakPatchedWheel = new File(rootProject.projectDir, "vendor/bleak-3.0.2-py3-none-any.whl") -def rnsPatchedWheel = new File(rootProject.projectDir, "vendor/rns-1.3.9-py3-none-any.whl") +def rnsPatchedWheel = new File(rootProject.projectDir, "vendor/rns-1.4.0-py3-none-any.whl") def allAndroidAbis = ["arm64-v8a", "x86_64", "armeabi-v7a"] def selectedAndroidAbis = ( project.findProperty("meshchatxAbis") @@ -341,7 +341,7 @@ chaquopy { // shim, usb4a context bridge, and able BLE stack so USB/BT/BLE RNode can // run. RNode over TCP needs neither native module and always works. install rnsPatchedWheel.absolutePath - install "lxmf>=1.0.1" + install "lxmf>=1.1.0" install "numpy==1.26.2" install "chaquopy-libcodec2==1.2.0" install "pycodec2==4.1.1" diff --git a/meshchatx.rsm b/meshchatx.rsm index 33582c11..73e12456 100644 Binary files a/meshchatx.rsm and b/meshchatx.rsm differ diff --git a/meshchatx/meshchat.py b/meshchatx/meshchat.py index 0b324591..694ca413 100644 --- a/meshchatx/meshchat.py +++ b/meshchatx/meshchat.py @@ -3851,7 +3851,7 @@ class ReticulumMeshChat: if isinstance(stats, dict) else _numeric(getattr(router, "propagation_per_sync_limit", 0)) ) - return { + result = { "is_running": is_running, "identity_hash": ctx.identity.hash.hex(), "destination_hash": destination_hash, @@ -3890,7 +3890,21 @@ class ReticulumMeshChat: else getattr(router, "propagation_stamp_cost", 0) ), ), + "inbound_delivery_count": 0, + "max_inbound_syncs": int( + getattr(router, "propagation_max_inbound_syncs", 0) or 0, + ), + "sequential_validation": bool( + getattr(router, "propagation_sequential_validation", True), + ), + "static_peers_bypass_sequential": not bool( + getattr(router, "propagation_static_peer_sequential", False), + ), } + if hasattr(router, "inbound_count"): + with contextlib.suppress(Exception): + result["inbound_delivery_count"] = int(router.inbound_count() or 0) + return result def _get_reticulum_section(self): try: @@ -12494,16 +12508,24 @@ class ReticulumMeshChat: router = self.message_router current_state = None current_progress = 0.0 + transfer_size = None if router is not None: try: current_state = router.propagation_transfer_state current_progress = router.propagation_transfer_progress + transfer_size = getattr( + router, + "propagation_transfer_size", + None, + ) # COMPLETE is terminal, so reset to idle so the UI does not keep # looking "busy" after a finished auto/manual sync. if current_state == router.PR_COMPLETE: with contextlib.suppress(Exception): router.propagation_transfer_state = router.PR_IDLE router.propagation_transfer_progress = 0.0 + if hasattr(router, "propagation_transfer_size"): + router.propagation_transfer_size = None except Exception: pass sync_metrics = self._collect_propagation_sync_metrics() @@ -12521,6 +12543,13 @@ class ReticulumMeshChat: last_result = None if current_state is None: current_state = 0 + transfer_size_bytes = None + if isinstance(transfer_size, (int, float)) and transfer_size > 0: + transfer_size_bytes = int(transfer_size) + inbound_delivery_count = 0 + if router is not None and hasattr(router, "inbound_count"): + with contextlib.suppress(Exception): + inbound_delivery_count = int(router.inbound_count() or 0) return web.json_response( { "propagation_node_status": { @@ -12528,6 +12557,8 @@ class ReticulumMeshChat: current_state, ), "progress": progress_pct, + "transfer_size_bytes": transfer_size_bytes, + "inbound_delivery_count": inbound_delivery_count, "messages_received": last_result, "messages_stored": sync_metrics["messages_stored"], "delivery_confirmations": sync_metrics[ @@ -12578,6 +12609,32 @@ class ReticulumMeshChat: }, ) + @routes.post("/api/v1/lxmf/propagation-node/cancel-inbound") + async def propagation_node_cancel_inbound(request): + router = self.message_router + if router is None or not hasattr(router, "cancel_all_inbound"): + return web.json_response( + { + "message": "Inbound delivery cancellation is unavailable.", + }, + status=503, + ) + try: + cancelled = int(router.cancel_all_inbound() or 0) + except Exception as exc: + return web.json_response( + { + "message": f"Failed to cancel inbound deliveries: {exc}", + }, + status=500, + ) + return web.json_response( + { + "message": f"Cancelled {cancelled} inbound deliveries", + "cancelled": cancelled, + }, + ) + @routes.post("/api/v1/lxmf/propagation-node/stop") async def propagation_node_stop(request): self.config.lxmf_local_propagation_node_enabled.set(False) @@ -18655,6 +18712,34 @@ class ReticulumMeshChat: if self.config.lxmf_local_propagation_node_enabled.get(): self.message_router.announce_propagation_node() + if "lxmf_propagation_sequential_validation" in data: + value = self._parse_bool( + data["lxmf_propagation_sequential_validation"], + ) + self.config.lxmf_propagation_sequential_validation.set(value) + if self.message_router is not None: + self.message_router.propagation_sequential_validation = value + + if "lxmf_propagation_static_peers_bypass_sequential" in data: + value = self._parse_bool( + data["lxmf_propagation_static_peers_bypass_sequential"], + ) + self.config.lxmf_propagation_static_peers_bypass_sequential.set(value) + if self.message_router is not None: + self.message_router.propagation_static_peer_sequential = not value + + if "lxmf_propagation_max_inbound_syncs" in data: + value = self._coerce_int(data["lxmf_propagation_max_inbound_syncs"]) + if value is None: + value = self.config.lxmf_propagation_max_inbound_syncs.get() + if value < 1: + value = 1 + elif value > 64: + value = 64 + self.config.lxmf_propagation_max_inbound_syncs.set(value) + if self.message_router is not None: + self.message_router.propagation_max_inbound_syncs = value + # update auto sync interval if "lxmf_preferred_propagation_node_auto_sync_interval_seconds" in data: value = self._coerce_int( @@ -20896,6 +20981,9 @@ class ReticulumMeshChat: "lxmf_user_icon_background_colour": ctx.config.lxmf_user_icon_background_colour.get(), "lxmf_inbound_stamp_cost": ctx.config.lxmf_inbound_stamp_cost.get(), "lxmf_propagation_node_stamp_cost": ctx.config.lxmf_propagation_node_stamp_cost.get(), + "lxmf_propagation_sequential_validation": ctx.config.lxmf_propagation_sequential_validation.get(), + "lxmf_propagation_static_peers_bypass_sequential": ctx.config.lxmf_propagation_static_peers_bypass_sequential.get(), + "lxmf_propagation_max_inbound_syncs": ctx.config.lxmf_propagation_max_inbound_syncs.get(), "lxmf_flood_protection_enabled": ctx.config.lxmf_flood_protection_enabled.get(), "lxmf_flood_threshold_per_minute": ctx.config.lxmf_flood_threshold_per_minute.get(), "lxmf_flood_max_stamp_cost": ctx.config.lxmf_flood_max_stamp_cost.get(), diff --git a/meshchatx/src/backend/config_manager.py b/meshchatx/src/backend/config_manager.py index 2dc96232..19e8119b 100644 --- a/meshchatx/src/backend/config_manager.py +++ b/meshchatx/src/backend/config_manager.py @@ -106,6 +106,21 @@ class ConfigManager: "lxmf_propagation_node_stamp_cost", 16, ) # for propagation node messages + self.lxmf_propagation_sequential_validation = self.BoolConfig( + self, + "lxmf_propagation_sequential_validation", + True, + ) + self.lxmf_propagation_static_peers_bypass_sequential = self.BoolConfig( + self, + "lxmf_propagation_static_peers_bypass_sequential", + True, + ) + self.lxmf_propagation_max_inbound_syncs = self.IntConfig( + self, + "lxmf_propagation_max_inbound_syncs", + 3, + ) self.lxmf_inbound_stamp_cost_before_block = self.IntConfig( self, "lxmf_inbound_stamp_cost_before_block", diff --git a/meshchatx/src/backend/data/THIRD_PARTY_NOTICES.txt b/meshchatx/src/backend/data/THIRD_PARTY_NOTICES.txt index 6c7c621d..2b465b96 100644 --- a/meshchatx/src/backend/data/THIRD_PARTY_NOTICES.txt +++ b/meshchatx/src/backend/data/THIRD_PARTY_NOTICES.txt @@ -46,7 +46,7 @@ frozenlist 1.8.0 idna 3.18 License: BSD-3-Clause Author: Kim Davies -lxmf 1.0.1 +lxmf 1.1.0 License: Reticulum License Author: Mark Qvist lxmfy 1.6.5 @@ -88,7 +88,7 @@ pyserial 3.5 reticulum-meshchatx 4.8.0 License: 0BSD AND MIT Author: Quad4 -rns 1.3.9 +rns 1.4.0 License: Reticulum License Author: Mark Qvist wasmtime 46.0.1 diff --git a/meshchatx/src/backend/data/licenses_backend.json b/meshchatx/src/backend/data/licenses_backend.json index e79c86da..ef16fc96 100644 --- a/meshchatx/src/backend/data/licenses_backend.json +++ b/meshchatx/src/backend/data/licenses_backend.json @@ -8,7 +8,7 @@ { "name": "aiohttp", "version": "3.14.1", - "author": "—", + "author": "\u2014", "license": "Apache-2.0 AND MIT" }, { @@ -32,7 +32,7 @@ { "name": "audioop-lts", "version": "0.2.2", - "author": "—", + "author": "\u2014", "license": "PSF-2.0" }, { @@ -50,7 +50,7 @@ { "name": "cbor2", "version": "6.1.1", - "author": "Alex Grönholm ", + "author": "Alex Gr\u00f6nholm ", "license": "MIT" }, { @@ -85,7 +85,7 @@ }, { "name": "lxmf", - "version": "1.0.1", + "version": "1.1.0", "author": "Mark Qvist", "license": "Reticulum License" }, @@ -169,7 +169,7 @@ }, { "name": "rns", - "version": "1.3.9", + "version": "1.4.0", "author": "Mark Qvist", "license": "Reticulum License" }, diff --git a/meshchatx/src/backend/identity_context.py b/meshchatx/src/backend/identity_context.py index c2b1a435..cfad244b 100644 --- a/meshchatx/src/backend/identity_context.py +++ b/meshchatx/src/backend/identity_context.py @@ -256,10 +256,22 @@ class IdentityContext: # 4. Initialize LXMF Router propagation_stamp_cost = self.config.lxmf_propagation_node_stamp_cost.get() + max_inbound_syncs = self.config.lxmf_propagation_max_inbound_syncs.get() + if not isinstance(max_inbound_syncs, int) or max_inbound_syncs < 1: + max_inbound_syncs = 3 + sequential_validation = bool( + self.config.lxmf_propagation_sequential_validation.get(), + ) + static_sequential = not bool( + self.config.lxmf_propagation_static_peers_bypass_sequential.get(), + ) self.message_router = create_lxmf_router( identity=self.identity, storagepath=self.lxmf_router_path, propagation_cost=propagation_stamp_cost, + max_inbound_syncs=max_inbound_syncs, + sequential_validation=sequential_validation, + static_sequential=static_sequential, ) self.message_router.PROCESSING_INTERVAL = 1 self.message_router.delivery_per_transfer_limit = ( diff --git a/meshchatx/src/backend/interface_editor.py b/meshchatx/src/backend/interface_editor.py index 8ce5daca..ab91d2e9 100644 --- a/meshchatx/src/backend/interface_editor.py +++ b/meshchatx/src/backend/interface_editor.py @@ -340,7 +340,7 @@ class InterfaceEditor: interface_details: dict, data: dict, ) -> str | None: - """Persist BackboneInterface fast-flapping options (RNS 1.3.9).""" + """Persist BackboneInterface fast-flapping options (RNS 1.4.0).""" err = InterfaceEditor.apply_yes_no_option( interface_details, data, diff --git a/meshchatx/src/backend/meshchat_utils.py b/meshchatx/src/backend/meshchat_utils.py index 82f6dc0f..df37fdb2 100644 --- a/meshchatx/src/backend/meshchat_utils.py +++ b/meshchatx/src/backend/meshchat_utils.py @@ -11,7 +11,14 @@ import RNS.vendor.umsgpack as msgpack from LXMF import LXMRouter -def create_lxmf_router(identity, storagepath, propagation_cost=None): +def create_lxmf_router( + identity, + storagepath, + propagation_cost=None, + max_inbound_syncs=None, + sequential_validation=None, + static_sequential=None, +): """Construct an LXMF.LXMRouter without signal-handler crashes off the main thread. signal.signal only works on the main thread; on workers it is temporarily @@ -20,23 +27,27 @@ def create_lxmf_router(identity, storagepath, propagation_cost=None): if propagation_cost is None: propagation_cost = 0 + kwargs = { + "identity": identity, + "storagepath": storagepath, + "propagation_cost": propagation_cost, + } + if max_inbound_syncs is not None: + kwargs["max_inbound_syncs"] = max_inbound_syncs + if sequential_validation is not None: + kwargs["sequential_validation"] = sequential_validation + if static_sequential is not None: + kwargs["static_sequential"] = static_sequential + if threading.current_thread() != threading.main_thread(): original_signal = signal.signal try: signal.signal = lambda s, h: None - return LXMF.LXMRouter( - identity=identity, - storagepath=storagepath, - propagation_cost=propagation_cost, - ) + return LXMF.LXMRouter(**kwargs) finally: signal.signal = original_signal else: - return LXMF.LXMRouter( - identity=identity, - storagepath=storagepath, - propagation_cost=propagation_cost, - ) + return LXMF.LXMRouter(**kwargs) def parse_bool_query_param(value: str | None) -> bool: diff --git a/meshchatx/src/backend/rnsh_manager.py b/meshchatx/src/backend/rnsh_manager.py index 2f809c4f..1bfdc645 100644 --- a/meshchatx/src/backend/rnsh_manager.py +++ b/meshchatx/src/backend/rnsh_manager.py @@ -293,7 +293,7 @@ class RNSHSession: # same shared instance and rpc_key) as the MeshChatX app. Without this # rnsh bootstraps its own default config, becomes a mismatched shared # instance client and fails RPC auth with "digest sent was rejected". - # RNS 1.3.9+: --rnsconfig is the Reticulum config dir. -c/--config is + # RNS 1.4.0+: --rnsconfig is the Reticulum config dir. -c/--config is # the rnsh config directory (HOME/.rnsh via _build_env). config_path = self.resolved_config_dir if config_path: diff --git a/meshchatx/src/frontend/components/settings/SettingsPage.vue b/meshchatx/src/frontend/components/settings/SettingsPage.vue index 8e3a783a..60846dd1 100644 --- a/meshchatx/src/frontend/components/settings/SettingsPage.vue +++ b/meshchatx/src/frontend/components/settings/SettingsPage.vue @@ -3699,6 +3699,59 @@ {{ $t("app.propagation_stamp_description") }} + + +
+
+ {{ $t("app.propagation_max_inbound_syncs") }} +
+ +
+ {{ $t("app.propagation_max_inbound_syncs_description") }} +
+
@@ -3893,6 +3946,9 @@ export default { lxmf_propagation_transfer_limit_in_bytes: 1000 * 256, lxmf_propagation_sync_limit_in_bytes: 1000 * 10240, lxmf_local_propagation_node_enabled: null, + lxmf_propagation_sequential_validation: true, + lxmf_propagation_static_peers_bypass_sequential: true, + lxmf_propagation_max_inbound_syncs: 3, lxmf_preferred_propagation_node_destination_hash: null, lxmf_preferred_propagation_node_auto_select: null, archives_max_storage_gb: 1, @@ -5351,6 +5407,30 @@ export default { ); }, 1000); }, + async onLxmfPropagationSequentialValidationChange(value) { + await this.updateConfig({ + lxmf_propagation_sequential_validation: value, + }); + }, + async onLxmfPropagationStaticPeersBypassChange(value) { + await this.updateConfig({ + lxmf_propagation_static_peers_bypass_sequential: value, + }); + }, + async onLxmfPropagationMaxInboundSyncsChange() { + if (this.saveTimeouts.propagation_max_inbound_syncs) { + clearTimeout(this.saveTimeouts.propagation_max_inbound_syncs); + } + this.saveTimeouts.propagation_max_inbound_syncs = setTimeout(async () => { + let v = Number(this.config.lxmf_propagation_max_inbound_syncs); + if (!v || v < 1) v = 1; + else if (v > 64) v = 64; + this.config.lxmf_propagation_max_inbound_syncs = v; + await this.updateConfig({ + lxmf_propagation_max_inbound_syncs: v, + }); + }, 1000); + }, async onLxmfFloodProtectionEnabledChange(value) { await this.updateConfig({ lxmf_flood_protection_enabled: value, diff --git a/meshchatx/src/frontend/js/registries/coreSettingsSectionKeywords.js b/meshchatx/src/frontend/js/registries/coreSettingsSectionKeywords.js index 8e4842e9..274b766e 100644 --- a/meshchatx/src/frontend/js/registries/coreSettingsSectionKeywords.js +++ b/meshchatx/src/frontend/js/registries/coreSettingsSectionKeywords.js @@ -358,6 +358,12 @@ export const CORE_SETTINGS_SECTION_KEYWORDS = { "app.auto_sync_interval", "app.propagation_stamp_cost", "app.propagation_stamp_description", + "app.propagation_sequential_validation", + "app.propagation_sequential_validation_description", + "app.propagation_static_peers_bypass_sequential", + "app.propagation_static_peers_bypass_sequential_description", + "app.propagation_max_inbound_syncs", + "app.propagation_max_inbound_syncs_description", ], location: [ "app.location", diff --git a/meshchatx/src/frontend/locales/de.json b/meshchatx/src/frontend/locales/de.json index 4e8dd4fb..b884993e 100644 --- a/meshchatx/src/frontend/locales/de.json +++ b/meshchatx/src/frontend/locales/de.json @@ -501,7 +501,13 @@ "remote_management_allowed": "Remote management allow-list", "remote_management_allowed_description": "Identity hashes allowed to query this instance remotely with rnstatus/rnpath. One 32-character hex hash per line.", "remote_management_allowed_placeholder": "9fb6d773498fb3feda407ed8ef2c3229", - "remote_management_allowed_save": "Save allow-list" + "remote_management_allowed_save": "Save allow-list", + "propagation_sequential_validation": "Sequential PN Stamp Validation", + "propagation_sequential_validation_description": "Validate inbound propagation sync stamp batches one at a time. Other peers receive a throttle response while a batch is validating. Disable only on fast hosts.", + "propagation_static_peers_bypass_sequential": "Static Peers Bypass Sequential Validation", + "propagation_static_peers_bypass_sequential_description": "Allow configured static peers to sync immediately even when another stamp batch is already validating.", + "propagation_max_inbound_syncs": "Max Concurrent Inbound Syncs", + "propagation_max_inbound_syncs_description": "How many concurrent inbound propagation sync transfers to accept. Extra offers are throttled. Range: 1-64. Default: 3." }, "common": { "open": "Öffnen", @@ -1386,7 +1392,7 @@ "location_cmd_placeholder": "/path/to/gps-script", "location_cmd_hint": "Absoluter Pfad zu einem Programm, das latitude,longitude,height ausgibt. Reticulum startet es für Discovery-Announces (RNS location_cmd).", "block_fast_flapping_label": "Schnell wechselnde Clients blockieren", - "block_fast_flapping_hint": "Ignoriert Clients, die sich zu schnell verbinden und trennen (RNS 1.3.9 BackboneInterface-Standard).", + "block_fast_flapping_hint": "Ignoriert Clients, die sich zu schnell verbinden und trennen (RNS 1.4.0 BackboneInterface-Standard).", "fast_flapping_block_time_label": "Sperrzeit (Minuten)", "fast_flapping_threshold_label": "Schwelle (Sekunden)", "fast_flapping_grace_label": "Kulanz-Flaps" diff --git a/meshchatx/src/frontend/locales/en.json b/meshchatx/src/frontend/locales/en.json index 2474d417..6b46abdb 100644 --- a/meshchatx/src/frontend/locales/en.json +++ b/meshchatx/src/frontend/locales/en.json @@ -275,6 +275,12 @@ "last_synced_never": "Last synced: never.", "propagation_stamp_cost": "Propagation Node Stamp Cost", "propagation_stamp_description": "Require proof-of-work stamps for messages sent through your node. Higher values require more work. Range: 13-254. Default: 16. **Note:** Changing this requires a restart.", + "propagation_sequential_validation": "Sequential PN Stamp Validation", + "propagation_sequential_validation_description": "Validate inbound propagation sync stamp batches one at a time. Other peers receive a throttle response while a batch is validating. Disable only on fast hosts.", + "propagation_static_peers_bypass_sequential": "Static Peers Bypass Sequential Validation", + "propagation_static_peers_bypass_sequential_description": "Allow configured static peers to sync immediately even when another stamp batch is already validating.", + "propagation_max_inbound_syncs": "Max Concurrent Inbound Syncs", + "propagation_max_inbound_syncs_description": "How many concurrent inbound propagation sync transfers to accept. Extra offers are throttled. Range: 1-64. Default: 3.", "language": "Language", "select_language": "Select your preferred language.", "tagline": "All-in-one Reticulum client", @@ -1261,7 +1267,7 @@ "location_cmd_placeholder": "/path/to/gps-script", "location_cmd_hint": "Absolute path to an executable that prints latitude,longitude,height. Reticulum runs it for discovery announces (RNS location_cmd).", "block_fast_flapping_label": "Block fast-flapping clients", - "block_fast_flapping_hint": "Ignore clients that connect and disconnect too quickly (RNS 1.3.9 BackboneInterface defaults).", + "block_fast_flapping_hint": "Ignore clients that connect and disconnect too quickly (RNS 1.4.0 BackboneInterface defaults).", "fast_flapping_block_time_label": "Block time (minutes)", "fast_flapping_threshold_label": "Threshold (seconds)", "fast_flapping_grace_label": "Grace flaps", diff --git a/meshchatx/src/frontend/locales/es.json b/meshchatx/src/frontend/locales/es.json index b470f7e2..a01eeb60 100644 --- a/meshchatx/src/frontend/locales/es.json +++ b/meshchatx/src/frontend/locales/es.json @@ -501,7 +501,13 @@ "remote_management_allowed": "Remote management allow-list", "remote_management_allowed_description": "Identity hashes allowed to query this instance remotely with rnstatus/rnpath. One 32-character hex hash per line.", "remote_management_allowed_placeholder": "9fb6d773498fb3feda407ed8ef2c3229", - "remote_management_allowed_save": "Save allow-list" + "remote_management_allowed_save": "Save allow-list", + "propagation_sequential_validation": "Sequential PN Stamp Validation", + "propagation_sequential_validation_description": "Validate inbound propagation sync stamp batches one at a time. Other peers receive a throttle response while a batch is validating. Disable only on fast hosts.", + "propagation_static_peers_bypass_sequential": "Static Peers Bypass Sequential Validation", + "propagation_static_peers_bypass_sequential_description": "Allow configured static peers to sync immediately even when another stamp batch is already validating.", + "propagation_max_inbound_syncs": "Max Concurrent Inbound Syncs", + "propagation_max_inbound_syncs_description": "How many concurrent inbound propagation sync transfers to accept. Extra offers are throttled. Range: 1-64. Default: 3." }, "common": { "open": "Abierto", @@ -1334,7 +1340,7 @@ "location_cmd_placeholder": "/path/to/gps-script", "location_cmd_hint": "Ruta absoluta a un ejecutable que imprime latitude,longitude,height. Reticulum lo ejecuta para announces de discovery (RNS location_cmd).", "block_fast_flapping_label": "Bloquear clientes de flapping rápido", - "block_fast_flapping_hint": "Ignora clientes que se conectan y desconectan demasiado rápido (valores por defecto de BackboneInterface en RNS 1.3.9).", + "block_fast_flapping_hint": "Ignora clientes que se conectan y desconectan demasiado rápido (valores por defecto de BackboneInterface en RNS 1.4.0).", "fast_flapping_block_time_label": "Tiempo de bloqueo (minutos)", "fast_flapping_threshold_label": "Umbral (segundos)", "fast_flapping_grace_label": "Flaps de gracia" diff --git a/meshchatx/src/frontend/locales/fi.json b/meshchatx/src/frontend/locales/fi.json index fdad15ef..8bd86d43 100644 --- a/meshchatx/src/frontend/locales/fi.json +++ b/meshchatx/src/frontend/locales/fi.json @@ -501,7 +501,13 @@ "remote_management_allowed": "Remote management allow-list", "remote_management_allowed_description": "Identity hashes allowed to query this instance remotely with rnstatus/rnpath. One 32-character hex hash per line.", "remote_management_allowed_placeholder": "9fb6d773498fb3feda407ed8ef2c3229", - "remote_management_allowed_save": "Save allow-list" + "remote_management_allowed_save": "Save allow-list", + "propagation_sequential_validation": "Sequential PN Stamp Validation", + "propagation_sequential_validation_description": "Validate inbound propagation sync stamp batches one at a time. Other peers receive a throttle response while a batch is validating. Disable only on fast hosts.", + "propagation_static_peers_bypass_sequential": "Static Peers Bypass Sequential Validation", + "propagation_static_peers_bypass_sequential_description": "Allow configured static peers to sync immediately even when another stamp batch is already validating.", + "propagation_max_inbound_syncs": "Max Concurrent Inbound Syncs", + "propagation_max_inbound_syncs_description": "How many concurrent inbound propagation sync transfers to accept. Extra offers are throttled. Range: 1-64. Default: 3." }, "common": { "open": "Avaa", @@ -1334,7 +1340,7 @@ "location_cmd_placeholder": "/path/to/gps-script", "location_cmd_hint": "Absoluuttinen polku ohjelmaan, joka tulostaa latitude,longitude,height. Reticulum ajaa sen discovery-announceja varten (RNS location_cmd).", "block_fast_flapping_label": "Estaa nopea flapping", - "block_fast_flapping_hint": "Ohittaa asiakkaat, jotka yhdistavat ja katkaisevat liian nopeasti (RNS 1.3.9 BackboneInterface-oletukset).", + "block_fast_flapping_hint": "Ohittaa asiakkaat, jotka yhdistavat ja katkaisevat liian nopeasti (RNS 1.4.0 BackboneInterface-oletukset).", "fast_flapping_block_time_label": "Estoaika (minuuttia)", "fast_flapping_threshold_label": "Kynnys (sekuntia)", "fast_flapping_grace_label": "Armo-flapit" diff --git a/meshchatx/src/frontend/locales/fr.json b/meshchatx/src/frontend/locales/fr.json index fa6e5454..d5ef9fbf 100644 --- a/meshchatx/src/frontend/locales/fr.json +++ b/meshchatx/src/frontend/locales/fr.json @@ -501,7 +501,13 @@ "remote_management_allowed": "Remote management allow-list", "remote_management_allowed_description": "Identity hashes allowed to query this instance remotely with rnstatus/rnpath. One 32-character hex hash per line.", "remote_management_allowed_placeholder": "9fb6d773498fb3feda407ed8ef2c3229", - "remote_management_allowed_save": "Save allow-list" + "remote_management_allowed_save": "Save allow-list", + "propagation_sequential_validation": "Sequential PN Stamp Validation", + "propagation_sequential_validation_description": "Validate inbound propagation sync stamp batches one at a time. Other peers receive a throttle response while a batch is validating. Disable only on fast hosts.", + "propagation_static_peers_bypass_sequential": "Static Peers Bypass Sequential Validation", + "propagation_static_peers_bypass_sequential_description": "Allow configured static peers to sync immediately even when another stamp batch is already validating.", + "propagation_max_inbound_syncs": "Max Concurrent Inbound Syncs", + "propagation_max_inbound_syncs_description": "How many concurrent inbound propagation sync transfers to accept. Extra offers are throttled. Range: 1-64. Default: 3." }, "common": { "open": "Ouvrir", @@ -1334,7 +1340,7 @@ "location_cmd_placeholder": "/path/to/gps-script", "location_cmd_hint": "Chemin absolu vers un exécutable qui affiche latitude,longitude,height. Reticulum l'exécute pour les announces de discovery (RNS location_cmd).", "block_fast_flapping_label": "Bloquer le flapping rapide", - "block_fast_flapping_hint": "Ignore les clients qui se connectent et se déconnectent trop rapidement (défauts BackboneInterface RNS 1.3.9).", + "block_fast_flapping_hint": "Ignore les clients qui se connectent et se déconnectent trop rapidement (défauts BackboneInterface RNS 1.4.0).", "fast_flapping_block_time_label": "Durée de blocage (minutes)", "fast_flapping_threshold_label": "Seuil (secondes)", "fast_flapping_grace_label": "Flaps de grace" diff --git a/meshchatx/src/frontend/locales/it.json b/meshchatx/src/frontend/locales/it.json index eb83ff3e..e1cfa005 100644 --- a/meshchatx/src/frontend/locales/it.json +++ b/meshchatx/src/frontend/locales/it.json @@ -501,7 +501,13 @@ "remote_management_allowed": "Remote management allow-list", "remote_management_allowed_description": "Identity hashes allowed to query this instance remotely with rnstatus/rnpath. One 32-character hex hash per line.", "remote_management_allowed_placeholder": "9fb6d773498fb3feda407ed8ef2c3229", - "remote_management_allowed_save": "Save allow-list" + "remote_management_allowed_save": "Save allow-list", + "propagation_sequential_validation": "Sequential PN Stamp Validation", + "propagation_sequential_validation_description": "Validate inbound propagation sync stamp batches one at a time. Other peers receive a throttle response while a batch is validating. Disable only on fast hosts.", + "propagation_static_peers_bypass_sequential": "Static Peers Bypass Sequential Validation", + "propagation_static_peers_bypass_sequential_description": "Allow configured static peers to sync immediately even when another stamp batch is already validating.", + "propagation_max_inbound_syncs": "Max Concurrent Inbound Syncs", + "propagation_max_inbound_syncs_description": "How many concurrent inbound propagation sync transfers to accept. Extra offers are throttled. Range: 1-64. Default: 3." }, "common": { "open": "Apri", @@ -1386,7 +1392,7 @@ "location_cmd_placeholder": "/path/to/gps-script", "location_cmd_hint": "Percorso assoluto a un eseguibile che stampa latitude,longitude,height. Reticulum lo esegue per gli announce di discovery (RNS location_cmd).", "block_fast_flapping_label": "Blocca client con flapping rapido", - "block_fast_flapping_hint": "Ignora client che si connettono e disconnettono troppo in fretta (default BackboneInterface RNS 1.3.9).", + "block_fast_flapping_hint": "Ignora client che si connettono e disconnettono troppo in fretta (default BackboneInterface RNS 1.4.0).", "fast_flapping_block_time_label": "Tempo di blocco (minuti)", "fast_flapping_threshold_label": "Soglia (secondi)", "fast_flapping_grace_label": "Flap di grazia" diff --git a/meshchatx/src/frontend/locales/nl.json b/meshchatx/src/frontend/locales/nl.json index 1ec3a8b7..b20653cf 100644 --- a/meshchatx/src/frontend/locales/nl.json +++ b/meshchatx/src/frontend/locales/nl.json @@ -501,7 +501,13 @@ "remote_management_allowed": "Remote management allow-list", "remote_management_allowed_description": "Identity hashes allowed to query this instance remotely with rnstatus/rnpath. One 32-character hex hash per line.", "remote_management_allowed_placeholder": "9fb6d773498fb3feda407ed8ef2c3229", - "remote_management_allowed_save": "Save allow-list" + "remote_management_allowed_save": "Save allow-list", + "propagation_sequential_validation": "Sequential PN Stamp Validation", + "propagation_sequential_validation_description": "Validate inbound propagation sync stamp batches one at a time. Other peers receive a throttle response while a batch is validating. Disable only on fast hosts.", + "propagation_static_peers_bypass_sequential": "Static Peers Bypass Sequential Validation", + "propagation_static_peers_bypass_sequential_description": "Allow configured static peers to sync immediately even when another stamp batch is already validating.", + "propagation_max_inbound_syncs": "Max Concurrent Inbound Syncs", + "propagation_max_inbound_syncs_description": "How many concurrent inbound propagation sync transfers to accept. Extra offers are throttled. Range: 1-64. Default: 3." }, "common": { "open": "Openen", @@ -1334,7 +1340,7 @@ "location_cmd_placeholder": "/path/to/gps-script", "location_cmd_hint": "Absoluut pad naar een uitvoerbaar bestand dat latitude,longitude,height print. Reticulum voert dit uit voor discovery-announces (RNS location_cmd).", "block_fast_flapping_label": "Snelle flapping-clients blokkeren", - "block_fast_flapping_hint": "Negeert clients die te snel verbinden en verbreken (RNS 1.3.9 BackboneInterface-standaarden).", + "block_fast_flapping_hint": "Negeert clients die te snel verbinden en verbreken (RNS 1.4.0 BackboneInterface-standaarden).", "fast_flapping_block_time_label": "Blokkeertijd (minuten)", "fast_flapping_threshold_label": "Drempel (seconden)", "fast_flapping_grace_label": "Grace-flaps" diff --git a/meshchatx/src/frontend/locales/ru.json b/meshchatx/src/frontend/locales/ru.json index f0ba44ca..98d4e039 100644 --- a/meshchatx/src/frontend/locales/ru.json +++ b/meshchatx/src/frontend/locales/ru.json @@ -501,7 +501,13 @@ "remote_management_allowed": "Remote management allow-list", "remote_management_allowed_description": "Identity hashes allowed to query this instance remotely with rnstatus/rnpath. One 32-character hex hash per line.", "remote_management_allowed_placeholder": "9fb6d773498fb3feda407ed8ef2c3229", - "remote_management_allowed_save": "Save allow-list" + "remote_management_allowed_save": "Save allow-list", + "propagation_sequential_validation": "Sequential PN Stamp Validation", + "propagation_sequential_validation_description": "Validate inbound propagation sync stamp batches one at a time. Other peers receive a throttle response while a batch is validating. Disable only on fast hosts.", + "propagation_static_peers_bypass_sequential": "Static Peers Bypass Sequential Validation", + "propagation_static_peers_bypass_sequential_description": "Allow configured static peers to sync immediately even when another stamp batch is already validating.", + "propagation_max_inbound_syncs": "Max Concurrent Inbound Syncs", + "propagation_max_inbound_syncs_description": "How many concurrent inbound propagation sync transfers to accept. Extra offers are throttled. Range: 1-64. Default: 3." }, "common": { "open": "Открыть", @@ -1386,7 +1392,7 @@ "location_cmd_placeholder": "/path/to/gps-script", "location_cmd_hint": "Абсолютный путь к исполняемому файлу, печатающему latitude,longitude,height. Reticulum запускает его для discovery-announces (RNS location_cmd).", "block_fast_flapping_label": "Блокировать быстрый flapping", - "block_fast_flapping_hint": "Игнорирует клиентов, которые слишком быстро подключаются и отключаются (стандарты BackboneInterface RNS 1.3.9).", + "block_fast_flapping_hint": "Игнорирует клиентов, которые слишком быстро подключаются и отключаются (стандарты BackboneInterface RNS 1.4.0).", "fast_flapping_block_time_label": "Время блокировки (минуты)", "fast_flapping_threshold_label": "Порог (секунды)", "fast_flapping_grace_label": "Льготные flaps" diff --git a/meshchatx/src/frontend/locales/zh.json b/meshchatx/src/frontend/locales/zh.json index a8e064f8..a9357b66 100644 --- a/meshchatx/src/frontend/locales/zh.json +++ b/meshchatx/src/frontend/locales/zh.json @@ -501,7 +501,13 @@ "remote_management_allowed": "Remote management allow-list", "remote_management_allowed_description": "Identity hashes allowed to query this instance remotely with rnstatus/rnpath. One 32-character hex hash per line.", "remote_management_allowed_placeholder": "9fb6d773498fb3feda407ed8ef2c3229", - "remote_management_allowed_save": "Save allow-list" + "remote_management_allowed_save": "Save allow-list", + "propagation_sequential_validation": "Sequential PN Stamp Validation", + "propagation_sequential_validation_description": "Validate inbound propagation sync stamp batches one at a time. Other peers receive a throttle response while a batch is validating. Disable only on fast hosts.", + "propagation_static_peers_bypass_sequential": "Static Peers Bypass Sequential Validation", + "propagation_static_peers_bypass_sequential_description": "Allow configured static peers to sync immediately even when another stamp batch is already validating.", + "propagation_max_inbound_syncs": "Max Concurrent Inbound Syncs", + "propagation_max_inbound_syncs_description": "How many concurrent inbound propagation sync transfers to accept. Extra offers are throttled. Range: 1-64. Default: 3." }, "common": { "open": "打开", @@ -1334,7 +1340,7 @@ "location_cmd_placeholder": "/path/to/gps-script", "location_cmd_hint": "可执行文件的绝对路径,输出 latitude,longitude,height。Reticulum 会在发现通告时运行它(RNS location_cmd)。", "block_fast_flapping_label": "阻止快速抖动客户端", - "block_fast_flapping_hint": "忽略连接与断开过快的客户端(RNS 1.3.9 BackboneInterface 默认值)。", + "block_fast_flapping_hint": "忽略连接与断开过快的客户端(RNS 1.4.0 BackboneInterface 默认值)。", "fast_flapping_block_time_label": "封锁时间(分钟)", "fast_flapping_threshold_label": "阈值(秒)", "fast_flapping_grace_label": "宽限抖动次数" diff --git a/pyproject.toml b/pyproject.toml index 7c5a16bf..440d3210 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,10 +21,10 @@ classifiers = [ ] dependencies = [ "aiohttp>=3.14.1", - "lxmf>=1.0.1", + "lxmf>=1.1.0", "psutil>=7.2.2", "pyserial>=3.5", - "rns>=1.3.9", + "rns>=1.4.0", "websockets>=16.0", "bcrypt>=5.0.0,<6.0.0", "aiohttp-session>=2.12.1,<3.0.0", diff --git a/requirements.txt b/requirements.txt index 2d7fa923..15502c6a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -542,9 +542,9 @@ idna==3.18 \ --hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \ --hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848 # via yarl -lxmf==1.0.1 \ - --hash=sha256:96fbf9a02dcd311fd31129724c08faa5f42a0e4e1bab63bea7552fbc983f4fb8 \ - --hash=sha256:d12ead448296cbd09203462d8dc96a26eb71ef168b4197b133a970d483a607ea +lxmf==1.1.0 \ + --hash=sha256:187e5cba257163ba1cffa1b49a33dc8893cf3b982397ccd77461ceaa5cd54af1 \ + --hash=sha256:3836550364e059aa94eb955f9a862d20287643518d7a0b2a167b3b58c1d07cbd # via # lxst # reticulum-meshchatx @@ -985,9 +985,9 @@ pyserial==3.5 \ # via # reticulum-meshchatx # rns -rns==1.3.9 \ - --hash=sha256:ceeac4799dda72b48a34b1e36de538e64009cba5b7b28d086918c0120ca8bfa4 \ - --hash=sha256:fd3745c1aba4dcbf8833fa87a3157ec9900745a32d6d96ba330d623a98932a15 +rns==1.4.0 \ + --hash=sha256:a88c6ae15c289867b2d8ee8f6ba4363f4dc728283f892b0790dba226f7dddcae \ + --hash=sha256:fa9e76d0a78bf253eae66137e6bbdc65f470db3950a95b034ce32ca845ff0e44 # via # lxmf # lxst diff --git a/scripts/build-android-wheels-local.sh b/scripts/build-android-wheels-local.sh index 175efcf2..9aebc124 100755 --- a/scripts/build-android-wheels-local.sh +++ b/scripts/build-android-wheels-local.sh @@ -30,7 +30,7 @@ Options: --numpy-version V NumPy version used during pycodec2 build (default: 1.26.2) --lxst-version V LXST wheel version for metadata patch (default: 0.4.8) --bleak-version V bleak pure-python wheel version to vendor (default: 3.0.2) - --rns-version V rns wheel version to patch (default: 1.3.9) + --rns-version V rns wheel version to patch (default: 1.4.0) --no-lxst-patch Skip LXST metadata patch --no-rns-patch Skip RNS Android RNodeInterface patch --only-recipes LIST Comma-separated recipe directory names under @@ -60,7 +60,7 @@ LIBCODEC2_VERSION="1.2.0" NUMPY_VERSION="1.26.2" LXST_VERSION="0.4.8" BLEAK_VERSION="3.0.2" -RNS_VERSION="1.3.9" +RNS_VERSION="1.4.0" PATCH_LXST="1" PATCH_RNS="1" ONLY_RECIPES="" diff --git a/tests/backend/test_smoke_extended.py b/tests/backend/test_smoke_extended.py index 1a80c7cd..fc8fead7 100644 --- a/tests/backend/test_smoke_extended.py +++ b/tests/backend/test_smoke_extended.py @@ -227,5 +227,31 @@ def test_lxmf_router_creation_smoke(): identity = RNS.Identity() with tempfile.TemporaryDirectory() as tmpdir: with patch("LXMF.LXMRouter") as mock_router: - create_lxmf_router(identity, tmpdir) - mock_router.assert_called() + create_lxmf_router( + identity, + tmpdir, + propagation_cost=16, + max_inbound_syncs=2, + sequential_validation=True, + static_sequential=False, + ) + mock_router.assert_called_once() + kwargs = mock_router.call_args.kwargs + assert kwargs["propagation_cost"] == 16 + assert kwargs["max_inbound_syncs"] == 2 + assert kwargs["sequential_validation"] is True + assert kwargs["static_sequential"] is False + + +def test_lxmf_router_creation_accepts_new_defaults(): + """LXMF 1.1.0 LXMRouter accepts sequential/inbound sync kwargs.""" + import inspect + + import LXMF + + params = inspect.signature(LXMF.LXMRouter.__init__).parameters + assert "max_inbound_syncs" in params + assert "sequential_validation" in params + assert "static_sequential" in params + assert hasattr(LXMF.LXMRouter, "inbound_count") + assert hasattr(LXMF.LXMRouter, "cancel_all_inbound") \ No newline at end of file diff --git a/uv.lock b/uv.lock index b8c1f97b..c40fb492 100644 --- a/uv.lock +++ b/uv.lock @@ -1081,14 +1081,14 @@ wheels = [ [[package]] name = "lxmf" -version = "1.0.1" +version = "1.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "rns" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/33/2b/b1df90fce728db3a0659da44bfa8f1337670ccc6a937b7a988c119a4b05c/lxmf-1.0.1.tar.gz", hash = "sha256:d12ead448296cbd09203462d8dc96a26eb71ef168b4197b133a970d483a607ea", size = 71315, upload-time = "2026-06-01T12:26:07.874Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8b/69/2ba34eee87c8fa91605d5e35ecb33a3a6e65f43085c7d3e369b724e05e03/lxmf-1.1.0.tar.gz", hash = "sha256:187e5cba257163ba1cffa1b49a33dc8893cf3b982397ccd77461ceaa5cd54af1", size = 74933, upload-time = "2026-07-20T16:58:07.498Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/86/ff/4374bc1ed3a6b5e3d4c9c9e40793b7ecf77998d3a41eae66501155aac8f3/lxmf-1.0.1-py3-none-any.whl", hash = "sha256:96fbf9a02dcd311fd31129724c08faa5f42a0e4e1bab63bea7552fbc983f4fb8", size = 64470, upload-time = "2026-06-01T12:26:06.044Z" }, + { url = "https://files.pythonhosted.org/packages/07/b4/5ad93f8920ced6d233ba2ff9ec6677f71db7412434da508478d49bb40fe2/lxmf-1.1.0-py3-none-any.whl", hash = "sha256:3836550364e059aa94eb955f9a862d20287643518d7a0b2a167b3b58c1d07cbd", size = 67948, upload-time = "2026-07-20T16:58:05.97Z" }, ] [[package]] @@ -1951,14 +1951,14 @@ requires-dist = [ { name = "bleak", specifier = ">=3.0.2,<4.0" }, { name = "cbor2", specifier = ">=6.1.1" }, { name = "cryptography", specifier = ">=49.0.0,<50.0.0" }, - { name = "lxmf", specifier = ">=1.0.1" }, + { name = "lxmf", specifier = ">=1.1.0" }, { name = "lxst", specifier = ">=0.5.0" }, { name = "miniaudio", specifier = ">=1.70,<2.0" }, { name = "ply", specifier = ">=3.11,<4.0" }, { name = "psutil", specifier = ">=7.2.2" }, { name = "pycparser", specifier = ">=3.0" }, { name = "pyserial", specifier = ">=3.5" }, - { name = "rns", specifier = ">=1.3.9" }, + { name = "rns", specifier = ">=1.4.0" }, { name = "wasmtime", specifier = ">=28.0.0" }, { name = "websockets", specifier = ">=16.0" }, ] @@ -1993,15 +1993,15 @@ wheels = [ [[package]] name = "rns" -version = "1.3.9" +version = "1.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cryptography" }, { name = "pyserial" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/52/28a6db2911f32feeffd9800a88929762321be14700a67a3f5d289ad9ecc0/rns-1.3.9.tar.gz", hash = "sha256:fd3745c1aba4dcbf8833fa87a3157ec9900745a32d6d96ba330d623a98932a15", size = 519005, upload-time = "2026-07-19T00:33:44.851Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3c/45/5aaed5107e0d3f434aada725224e1c54af96555959da312c01e12228c1de/rns-1.4.0.tar.gz", hash = "sha256:fa9e76d0a78bf253eae66137e6bbdc65f470db3950a95b034ce32ca845ff0e44", size = 519727, upload-time = "2026-07-20T17:13:03.624Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ac/ef/b9b3bccc082a70ebdf862147c83f2dc09ecce9fceed034af610fbc50af66/rns-1.3.9-py3-none-any.whl", hash = "sha256:ceeac4799dda72b48a34b1e36de538e64009cba5b7b28d086918c0120ca8bfa4", size = 606018, upload-time = "2026-07-19T00:33:39.354Z" }, + { url = "https://files.pythonhosted.org/packages/56/4e/1a50351fba424b891a61e5f0fed9f3f631d7a034ae5edcc531d79562467c/rns-1.4.0-py3-none-any.whl", hash = "sha256:a88c6ae15c289867b2d8ee8f6ba4363f4dc728283f892b0790dba226f7dddcae", size = 606736, upload-time = "2026-07-20T17:12:58.403Z" }, ] [[package]] diff --git a/vendor/lxmfy/README.md b/vendor/lxmfy/README.md index a4ea5cca..1dabcfb4 100644 --- a/vendor/lxmfy/README.md +++ b/vendor/lxmfy/README.md @@ -19,7 +19,7 @@ Easily create LXMF bots for the Reticulum Network with this extensible framework ## Installation -**Requirements:** Python 3.11+, [RNS](https://pypi.org/project/rns/) 1.3.5+, [LXMF](https://pypi.org/project/lxmf/) 1.0.1+ (installed automatically with LXMFy). +**Requirements:** Python 3.11+, [RNS](https://pypi.org/project/rns/) 1.4.0+, [LXMF](https://pypi.org/project/lxmf/) 1.1.0+ (installed automatically with LXMFy). There are many ways to install LXMFy, you pick: diff --git a/vendor/lxmfy/pyproject.toml b/vendor/lxmfy/pyproject.toml index cd78ad91..4450ed7a 100644 --- a/vendor/lxmfy/pyproject.toml +++ b/vendor/lxmfy/pyproject.toml @@ -15,8 +15,8 @@ classifiers = [ "Operating System :: OS Independent", ] dependencies = [ - "lxmf>=1.0.1", - "rns>=1.3.5" + "lxmf>=1.1.0", + "rns>=1.4.0" ] [project.urls] diff --git a/vendor/rns_filesync/README.md b/vendor/rns_filesync/README.md index 8e3715b6..892dd345 100644 --- a/vendor/rns_filesync/README.md +++ b/vendor/rns_filesync/README.md @@ -51,7 +51,7 @@ pip install -e ".[dev]" # or: make install-user ``` -Requires rns>=1.3.9. Current package version: **1.0.0**. +Requires rns>=1.4.0. Current package version: **1.0.0**. ```bash rns-filesync -v diff --git a/vendor/rns_filesync/README_RU.md b/vendor/rns_filesync/README_RU.md index e9ea2834..48d2f8cd 100644 --- a/vendor/rns_filesync/README_RU.md +++ b/vendor/rns_filesync/README_RU.md @@ -2,7 +2,7 @@ English README is the source of truth: [README.md](README.md). -Кратко: библиотека и CLI для синхронизации каталогов через Reticulum (`rns>=1.3.9`). +Кратко: библиотека и CLI для синхронизации каталогов через Reticulum (`rns>=1.4.0`). Конфиг и ACL как у rngit: `~/.rns_filesync/config`, правила `r:hash` / `w:all`, файлы `.allowed`. ```bash diff --git a/vendor/rns_filesync/pyproject.toml b/vendor/rns_filesync/pyproject.toml index 57be99c2..9eaf375f 100644 --- a/vendor/rns_filesync/pyproject.toml +++ b/vendor/rns_filesync/pyproject.toml @@ -10,7 +10,7 @@ readme = "README.md" license = { text = "BSD-2-Clause" } requires-python = ">=3.10" dependencies = [ - "rns>=1.3.9", + "rns>=1.4.0", ] [project.optional-dependencies] diff --git a/vendor/rns_filesync/requirements.txt b/vendor/rns_filesync/requirements.txt index 717fcd58..f50b3c94 100644 --- a/vendor/rns_filesync/requirements.txt +++ b/vendor/rns_filesync/requirements.txt @@ -1 +1 @@ -rns>=1.3.9 +rns>=1.4.0