Skip to content

feat: finalize transport v2 migration (Phase C)#637

Merged
grunch merged 2 commits into
mainfrom
v2-phase-c
Jul 3, 2026
Merged

feat: finalize transport v2 migration (Phase C)#637
grunch merged 2 commits into
mainfrom
v2-phase-c

Conversation

@Catrya

@Catrya Catrya commented Jul 1, 2026

Copy link
Copy Markdown
Member
  • Remove global Config.mostroVersion; message version now derived from the transport (toJson defaults to 1, wrapNip44 passes 2)
  • Extract testable buildOrdersFilter() from the subscription manager with unit tests (v1 kind 1059 / v2 kind 14 authors-pinned)
  • About screen shows the node's protocol_version with an explanatory dialog (l10n en/es/it/de/fr)
  • Docs: mark the v1 -> v2 migration complete (status, §4.2, §4.3, Phase C/D)
  • Tidy: import order in subscription_manager; drop duplicate publishEvent stub in mostro_service_test

Summary by CodeRabbit

  • New Features

    • Added support for displaying a node’s protocol version in the app’s node details view.
    • Updated the app to automatically align message handling with the appropriate transport format.
  • Bug Fixes

    • Improved version handling so messages use the correct default format across supported transports.
  • Tests

    • Added coverage for transport-specific order filtering and message compatibility.

- Remove global Config.mostroVersion; message version now derived from
  the transport (toJson defaults to 1, wrapNip44 passes 2)
- Extract testable buildOrdersFilter() from the subscription manager
  with unit tests (v1 kind 1059 / v2 kind 14 authors-pinned)
- About screen shows the node's protocol_version with an explanatory
  dialog (l10n en/es/it/de/fr)
- Docs: mark the v1 -> v2 migration complete (status, §4.2, §4.3,
  Phase C/D)
- Tidy: import order in subscription_manager; drop duplicate publishEvent
  stub in mostro_service_test
@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Catrya, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 21 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ab451550-e55f-4f99-b1b3-f451c3038391

📥 Commits

Reviewing files that changed from the base of the PR and between 18839c1 and 9e6faa7.

📒 Files selected for processing (1)
  • docs/architecture/TRANSPORT_V2_MIGRATION.md

Walkthrough

Removes the global Config.mostroVersion constant; MostroMessage.toJson now defaults version to 1 directly. SubscriptionManager extracts a testable buildOrdersFilter helper for transport-aware orders filters. Adds protocol-version UI display and localization strings, updates migration docs, and adjusts tests.

Changes

Version derivation and transport-aware filtering

Layer / File(s) Summary
Remove global version constant
lib/core/config.dart
Deletes the static mostroVersion field from Config.
Version default in message serialization
lib/data/models/mostro_message.dart
toJson now defaults version to 1 instead of referencing Config.mostroVersion, with comments noting wrapNip44 supplies version: 2.
Transport-aware orders filter helper
lib/features/subscriptions/subscription_manager.dart, test/features/subscriptions/orders_filter_test.dart
Extracts orders filter construction into a @visibleForTesting buildOrdersFilter function mapping Transport.giftWrap/Transport.nip44 to NostrFilter shapes, wired into SubscriptionManager, with new unit tests.
Protocol version UI and localization
lib/features/settings/about_screen.dart, lib/l10n/intl_en.arb, lib/l10n/intl_de.arb, lib/l10n/intl_es.arb, lib/l10n/intl_fr.arb, lib/l10n/intl_it.arb
Adds a protocol version info row in the node details card and corresponding localized label/explanation strings across five locales.
Migration docs and test payload updates
docs/architecture/TRANSPORT_V2_MIGRATION.md, test/services/mostro_service_test.dart
Marks the transport v2 migration status as complete, updates the version-derivation and touch-points sections, finalizes phase notes, and replaces Config.mostroVersion references in service tests with a hardcoded 1.

Estimated code review effort: 2 (Simple) | ~12 minutes

Possibly related issues

Possibly related PRs

  • MostroP2P/mobile#620: Both modify the same transport v2 migration doc describing per-node protocol_version auto-detection and version mapping.
  • MostroP2P/mobile#621: Prior transport v2 filter logic in subscription_manager.dart is refactored here into the shared buildOrdersFilter helper.
  • MostroP2P/mobile#624: Both touch mostro_message.dart version/transport plumbing that this PR simplifies by removing Config.mostroVersion.

Suggested reviewers: grunch, ermeme, AndreaDiazCorreia

Poem

A constant hopped away today,
No more mostroVersion in its way,
Transport whispers "one" or "two",
The filter learns just what to do. 🐇
Docs are tidy, tests all pass—
This bunny's burrow, built to last! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: finalizing the transport v2 migration for Phase C.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch v2-phase-c

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
lib/data/models/mostro_message.dart (1)

30-34: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Don't describe the default JSON as transport-derived for logging/storage.

wrapNip44() correctly overrides this to 2, but lib/services/mostro_service.dart still logs order.toJson() with no version override. That means a v2 send goes out on the wire as version: 2 while the logged payload still shows version: 1. Either thread the resolved version into those non-wire call sites or narrow this comment so it only describes the actual send paths.

✏️ Possible wording tweak
-      // The message version is derived from the wire transport: 1 for gift wrap
-      // (the default here, used by storage/logging and the v1 send path) and 2
-      // for NIP-44 direct (passed explicitly by `wrapNip44`). See §4.2 of
-      // docs/architecture/TRANSPORT_V2_MIGRATION.md.
+      // Bare JSON serialization defaults to protocol v1.
+      // Transport-specific send paths override this where needed:
+      // `wrap()` keeps v1, while `wrapNip44()` passes `version: 2`.
+      // See §4.2 of docs/architecture/TRANSPORT_V2_MIGRATION.md.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/data/models/mostro_message.dart` around lines 30 - 34, The default
version value in MostroMessage is being described too broadly as
transport-derived, but non-wire call sites like MostroService still use
order.toJson() without overriding it and will log storage payloads with version
1. Narrow the comment in MostroMessage.toJson() so it only describes the actual
send paths, or thread the resolved version through the logging/storage
serialization path in MostroMessage and MostroService so the logged payload
matches the wire version.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/architecture/TRANSPORT_V2_MIGRATION.md`:
- Around line 21-26: The phase introduction still describes the migration as
future work, which conflicts with the updated completed-state wording. Update
the introductory text in TRANSPORT_V2_MIGRATION.md near the phases section so it
no longer says the phases are for “subsequent branches” or that the document
“does not execute them,” and make it consistent with the completed status
already stated; use the surrounding phase overview text and headings as the
anchor for the edit.

In `@lib/features/settings/about_screen.dart`:
- Around line 338-343: The protocol version row in about_screen’s info card is
rendering nullable data directly via AboutScreen/_buildInfoRowWithDialog, so
legacy nodes can show the literal string "null". Update the value passed for
instance.protocolVersion to use a null fallback consistent with the other
optional fields in this card, such as S.of(context)!.notAvailableShort, so
nullable protocolVersion is displayed as a friendly unavailable label instead of
null.

---

Nitpick comments:
In `@lib/data/models/mostro_message.dart`:
- Around line 30-34: The default version value in MostroMessage is being
described too broadly as transport-derived, but non-wire call sites like
MostroService still use order.toJson() without overriding it and will log
storage payloads with version 1. Narrow the comment in MostroMessage.toJson() so
it only describes the actual send paths, or thread the resolved version through
the logging/storage serialization path in MostroMessage and MostroService so the
logged payload matches the wire version.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e755971a-d417-4a7e-a9a3-66cc73ecf3eb

📥 Commits

Reviewing files that changed from the base of the PR and between ac6e946 and 18839c1.

📒 Files selected for processing (12)
  • docs/architecture/TRANSPORT_V2_MIGRATION.md
  • lib/core/config.dart
  • lib/data/models/mostro_message.dart
  • lib/features/settings/about_screen.dart
  • lib/features/subscriptions/subscription_manager.dart
  • lib/l10n/intl_de.arb
  • lib/l10n/intl_en.arb
  • lib/l10n/intl_es.arb
  • lib/l10n/intl_fr.arb
  • lib/l10n/intl_it.arb
  • test/features/subscriptions/orders_filter_test.dart
  • test/services/mostro_service_test.dart
💤 Files with no reviewable changes (1)
  • lib/core/config.dart

Comment thread docs/architecture/TRANSPORT_V2_MIGRATION.md
Comment thread lib/features/settings/about_screen.dart

@ermeme ermeme Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. I verified the transport split, the protocol_version-driven subscription filter, and the UI/docs updates.

@grunch grunch requested a review from AndreaDiazCorreia July 1, 2026 20:52

@ermeme ermeme Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Approve

I rechecked the current head of PR #637 and the transport-v2 wiring looks internally consistent.

What I verified

  • MostroMessage.wrapForTransport() is now the single entry point for outbound transport selection.
  • wrapNip44() stamps version: 2, while the legacy path still defaults to version: 1.
  • SubscriptionManager.buildOrdersFilter() correctly splits receive-side filters:
    • v1 → kind 1059 with p = tradeKeys
    • v2 → kind 14 with authors = [mostroPubkey] and p = tradeKeys
  • The node's protocol_version is surfaced through MostroInstance.protocolVersion and is used consistently on both send and receive paths.
  • The About screen change is safe because it reads MostroInstance.protocolVersion from the model, not the nullable Nostr extension getter.
  • The docs now match the implementation and the migration is clearly marked complete.

Test coverage

  • The new buildOrdersFilter() tests cover both transport branches.
  • The existing service tests still exercise message signing / verification behavior on the send path.

Notes

  • I did not find a blocking correctness issue in the current head.
  • The only thing I'd keep watching is that the transport switch relies on the node info event arriving and the subscription manager re-subscribing when it does; the current implementation already accounts for that, so this is a watchpoint rather than a blocker.

Overall: clean implementation, sensible decomposition, and the migration is wired coherently end-to-end.

@mostronatorcoder mostronatorcoder Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed the current head and I do not see a blocking issue.

What I checked:

  • Removing the global Config.mostroVersion is the right cleanup. The message version is now derived from the wire transport at the serialization/wrap boundary, which avoids drift between v1 gift-wrap and v2 NIP-44 paths.
  • MostroMessage.toJson() defaulting to version: 1 is consistent with the remaining v1/storage/logging callers, while wrapNip44 explicitly forces version: 2 for protocol-v2 traffic.
  • Extracting buildOrdersFilter() is a good move and the v2 filter keeps the important authors: [mostroPubkey] pin, so kind-14 Mostro replies stay disambiguated from peer chat.
  • The About screen surfacing protocol_version is aligned with the migration model and helps explain transport selection without changing behavior.
  • The docs update matches the code state for this branch.

I could not run Flutter tests in this sandbox because flutter is not installed here, but the PR check run on the current head is green and I do not see a correctness blocker in the changes themselves.

Approved on the current revision.

@grunch grunch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strict review: full diff inspected against the surrounding code, all call sites of toJson/serialize/sign/wrap* grepped across lib/ and test/, PR-relevant test suites executed locally (all green), plus multi-pass analysis (correctness, silent failures, test coverage, docs/comment accuracy, Flutter idioms).

Correctness — no findings

  • Config.mostroVersion removal is clean: zero dangling references; every outbound send (mostro_service.dart, restore_manager.dart ×3, dispute_repository.dart) routes through wrapForTransport, so there is no v1/v2 version-drift risk.
  • sign/serialize (v1) and wrapNip44 (v2) build tuple element 0, the trade signature and the identity-proof payload from the same serialized JSON — they cannot drift apart.
  • The version field written to Sembast (mostro_storage.dart) is write-only metadata (fromJson/deserialized never read it), so the ?? 1 default is behavior-preserving for storage/logging.
  • buildOrdersFilter extraction is a pure refactor; calling a @visibleForTesting top-level function from the same library is valid and lint-clean. _appliedOrdersTransport tracking preserved.
  • instance.protocolVersion in the About screen is the non-nullable MostroInstance.protocolVersion (defaults to 1), so no "null" can render.
  • ARB: both new keys present and consistent in all 5 locales (en/es/it/de/fr), flat structure, metadata convention matches sibling mostroDaemonVersion. Docs (§4.2, §4.3, Phase C/D, "Migration complete") verified accurate against the code and the five referenced test files.

@grunch grunch merged commit 88a4967 into main Jul 3, 2026
2 checks passed
@grunch grunch deleted the v2-phase-c branch July 3, 2026 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants