Skip to content

refactor: remove deprecated token columns from disputes table#516

Merged
grunch merged 3 commits into
mainfrom
remove-token
Sep 4, 2025
Merged

refactor: remove deprecated token columns from disputes table#516
grunch merged 3 commits into
mainfrom
remove-token

Conversation

@grunch

@grunch grunch commented Sep 4, 2025

Copy link
Copy Markdown
Member
  • Update mostro-core to latest version removing buyer_token and seller_token
  • Remove deprecated token columns from disputes migration
  • Add automatic migration function to drop legacy columns from existing databases
  • Ensure backward compatibility with existing database installations
  • Update related dispute handling code to work with new schema

Summary by CodeRabbit

  • New Features

    • Automatic startup migration removes deprecated dispute columns to keep data current.
  • Refactor

    • Simplified dispute workflow and admin notifications by removing per-party tokens.
    • Improved DM logging to include destination public key.
    • Reduced parameters for order creation calls.
  • Tests

    • Lightning invoice validation updated to use regtest/testnet data.
  • Chores

    • Updated dependencies (reqwest, mostro-core) for compatibility.

@coderabbitai

coderabbitai Bot commented Sep 4, 2025

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@grunch has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 4 minutes and 23 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between b8947ba and 90ba28e.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • src/app/dispute.rs (5 hunks)
  • src/db.rs (3 hunks)

Walkthrough

Dependency updates in Cargo.toml (reqwest, mostro-core); DB migration SQL and runtime code remove buyer_token/seller_token; dispute flows and Payload::Dispute arity simplified (tokenless); SmallOrder::new arity reduced; send_dm logging enhanced; invoice test adjusted.

Changes

Cohort / File(s) Summary
Dependencies
Cargo.toml
Updated dependency versions: reqwest and mostro-core (features adjusted).
Schema migration (tokens removal)
migrations/20230928145530_disputes.sql
Removed buyer_token and seller_token columns from disputes table.
Runtime DB migration
src/db.rs
Added migrate_remove_token_columns(pool: &SqlitePool) that detects and drops legacy buyer_token/seller_token columns via PRAGMA and ALTER TABLE; invoked for new and existing DB initialization with error handling and cleanup.
Dispute flow (tokenless + payload arity)
src/app/dispute.rs, src/app/admin_take_dispute.rs
Removed token generation/usage; updated notify_dispute_to_users signature to omit tokens; changed Payload::Dispute usage from three fields to two; adjusted admin take-dispute payload construction and made dispute immutable.
Order constructor arity reduction
src/flow.rs, src/util.rs
Removed two trailing None args from SmallOrder::new call sites; constructor arity reduced accordingly.
DM logging
src/util.rs
send_dm log now includes recipient public key hex; other message flow unchanged.
Lightning invoice test
src/lightning/invoice.rs
Updated zero-amount invoice test to use a regtest/testnet invoice and simplified validation/assertion.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User as Initiator
  participant App as App (dispute.rs)
  participant DB as Database
  participant Notif as Notifier
  participant Nostr as Nostr Network

  User->>App: dispute_action(order_id, reason)
  App->>DB: Create Dispute (no tokens)
  DB-->>App: Dispute{id, ...}
  App->>Notif: notify_dispute_to_users(dispute, initiator_pubkey, counterpart_pubkey)
  Note over Notif: Build Payload::Dispute(dispute.id, None)
  Notif->>Nostr: Send DM to initiator
  Notif->>Nostr: Send DM to counterpart
  Nostr-->>Notif: Ack
  Notif-->>App: Ok
  App-->>User: Dispute initiated
Loading
sequenceDiagram
  autonumber
  participant FS as Filesystem
  participant DB as SqlitePool
  participant Init as db::init
  participant Mig as migrate_remove_token_columns

  Init->>FS: Check DB file exists?
  alt New DB
    Init->>DB: Create and run base migrations
    Init->>Mig: Inspect disputes schema
    Mig->>DB: PRAGMA table_info(disputes)
    alt Columns exist
      Mig->>DB: ALTER TABLE drop buyer_token/seller_token
      DB-->>Mig: Success
    else No columns
      Mig-->>Init: No-op
    end
  else Existing DB
    Init->>Mig: Inspect and drop token columns if present
  end
  Init-->>DB: Return ready pool
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • Catrya

Poem

I hopped through rows and schema fine,
Two tokens gone, the table's mine.
Payloads now lean, messages light,
Orders trimmed to fit just right.
Carrot cheers for cleaner nights! 🥕

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch remove-token

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

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

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
migrations/20230928145530_disputes.sql (1)

1-9: Do not edit historical migration files; add a new forward migration to drop columns

Changing an already-applied migration’s contents risks migration drift/checksum mismatch with sqlx, breaking environments that previously applied the original file. Keep this file immutable and introduce a new migration to remove the legacy columns.

Minimal forward migration suggestion (new file, e.g., 20250904120000_drop_dispute_tokens.sql):

+-- 20250904120000_drop_dispute_tokens.sql
+-- Prefer DROP COLUMN when available; otherwise rebuild table (SQLite < 3.35 fallback).
+PRAGMA foreign_keys=OFF;
+BEGIN;
+-- Try DROP COLUMN if supported
+-- If this fails in older SQLite, the application-level fallback in src/db.rs should rebuild (see code comment).
+ALTER TABLE disputes DROP COLUMN buyer_token;
+ALTER TABLE disputes DROP COLUMN seller_token;
+COMMIT;
+PRAGMA foreign_keys=ON;

Optional: declare a foreign key to orders and reflect SQLite semantics by using TEXT instead of varchar(10), since SQLite doesn’t enforce length.

-  order_id char(36) unique not null,
-  status varchar(10) not null,
-  order_previous_status varchar(10) not null,
+  order_id char(36) unique not null,
+  status TEXT not null,
+  order_previous_status TEXT not null,
+  -- Optionally:
+  -- FOREIGN KEY(order_id) REFERENCES orders(id) ON DELETE CASCADE
src/app/admin_take_dispute.rs (2)

151-154: Use DisputeStatus instead of Order Status

These fields/tags represent dispute state; using Status (order) is confusing and error-prone. Prefer DisputeStatus to avoid type/semantic drift.

-    dispute.status = Status::InProgress.to_string();
+    dispute.status = DisputeStatus::InProgress.to_string();
@@
-            vec![Status::InProgress.to_string()],
+            vec![DisputeStatus::InProgress.to_string()],

Also applies to: 219-233


98-101: Fix Keys API usage

Likely a compile error: Keys exposes public_key() (method), not a public field.

-            my_keys.public_key.to_string(),
+            my_keys.public_key().to_string(),
🧹 Nitpick comments (4)
src/lightning/invoice.rs (1)

288-291: Zero-amount invoice test: keep the stronger assertion too

Using regtest invoice + None is fine. To preserve the regression check from past learnings (zero-amount must pass even when an expected amount is supplied), add a second assertion that passes Some(amount) and still succeeds.

// Add alongside the existing test
#[tokio::test]
async fn test_zero_amount_invoice_with_expected_amount() {
    init_settings_test();
    let payment_request = "lnbcrt1p5tnk83pp5lqj87uf3ct7e4kluu3zcv3zvav9exwkj7chmpyt3u29g2p7uf6hqdqqcqzzsxqyz5vqsp5mrhkqtp7j8uhfzmcn6wdhj577jm87dvudnf28kefhzwwwh7zp7vq9qxpqysgq7ntan3nl38574gjrjne68740uymnc5xf39yryl9w7y2mcq9p3j53rwquhxukpjzclq4p8qmt89z7r4hmzzjkgj889ujgz0lr55c5gyqqeu4g52".to_string();
    let res = is_valid_invoice(payment_request, Some(10_000), None).await;
    assert_eq!(Ok(()), res);
}
src/db.rs (1)

449-454: Run under a transaction and guard against cross-process races

For existing DBs, consider acquiring an immediate transaction before migration to avoid TOCTOU if multiple instances start simultaneously and attempt the drop/rebuild concurrently.

-// Run legacy column migration for existing databases
-if let Err(e) = migrate_remove_token_columns(&conn).await {
+// Run legacy column migration under transactional guard
+if let Err(e) = migrate_remove_token_columns(&conn).await {
     tracing::error!("Failed to migrate token columns on existing database: {}", e);
     return Err(e);
 }

Note: with the refactor above, migrate_remove_token_columns itself begins/commits the transaction.

src/app/dispute.rs (2)

107-108: Typo in comment

Minor clarity fix.

-    // Message to discounterpart
+    // Message to counterpart

69-80: Docstring doesn’t match function signature/behavior

Function returns only a boolean (buyer initiated) or an error, not a tuple/photos of counterpart.

-/// Returns a tuple containing:
-/// - The counterparty's public key as a String
-/// - A boolean indicating if the dispute was initiated by the buyer (true) or seller (false)
+/// Returns:
+/// - Ok(true) if the dispute was initiated by the buyer
+/// - Ok(false) if initiated by the seller
+/// - Err(CantDoReason::InvalidPubkey) if the sender matches neither party
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7238b47 and fc51124.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • Cargo.toml (2 hunks)
  • migrations/20230928145530_disputes.sql (1 hunks)
  • src/app/admin_take_dispute.rs (1 hunks)
  • src/app/dispute.rs (4 hunks)
  • src/db.rs (3 hunks)
  • src/flow.rs (0 hunks)
  • src/lightning/invoice.rs (1 hunks)
  • src/util.rs (2 hunks)
💤 Files with no reviewable changes (1)
  • src/flow.rs
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-17T13:51:17.338Z
Learnt from: arkanoider
PR: MostroP2P/mostro#499
File: src/lightning/invoice.rs:108-114
Timestamp: 2025-07-17T13:51:17.338Z
Learning: In Lightning invoice validation for Mostro buy orders (src/lightning/invoice.rs), zero-amount invoices (amount_sat == 0) should always pass validation even when an expected amount is provided. This is because users can submit invoices at order creation time before knowing the exact satoshi amount they'll receive. The condition `if amount_sat != res && amount_sat != 0` correctly implements this by allowing zero-amount invoices to pass while enforcing exact amount matching for non-zero invoices.

Applied to files:

  • src/lightning/invoice.rs
🔇 Additional comments (6)
Cargo.toml (2)

65-65: mostro-core bump: no lingering token references
Only occurrences of buyer_token/seller_token are in src/db.rs migration logic (dropping deprecated columns), and all Payload::Dispute(…) calls use the updated two-argument signature. No further changes needed.


43-43: Approve Nostr SDK bump: no leftover APIs and NIP-59 usage confirmed
All old nostr-sdk APIs (Client::new, Options::, set_opts) have been replaced with ClientOptions and ClientBuilder (e.g. src/util.rs:614–617). NIP-59 feature is intentionally enabled and actively used across multiple modules (UnwrappedGift imports and nip59::extract_rumor calls).

src/db.rs (1)

356-369: Good: early runtime migration on new DB path with cleanup

Running the legacy column migration right after sqlx migrations and cleaning up the file on failure is solid. No change requested.

src/util.rs (1)

614-614: No remaining Options::new usages
A ripgrep scan (rg -nP '\bOptions::new\s*\(' -g '!**/target/**') returned no matches; migration to ClientOptions::new() is complete.

src/app/admin_take_dispute.rs (1)

173-174: Adaptation to new Payload::Dispute arity looks correct

Using Payload::Dispute(dispute.id, Some(dispute_info)) matches the tokenless, 2-field variant.

src/app/dispute.rs (1)

100-127: Tokenless notifications: LGTM

Both user-facing messages now use Payload::Dispute(dispute.id, None); aligns with removing per-party tokens.

Comment thread src/app/dispute.rs
Comment thread src/db.rs
Comment thread src/util.rs
- Update mostro-core to latest version removing buyer_token and seller_token
- Remove deprecated token columns from disputes migration
- Add automatic migration function to drop legacy columns from existing databases
- Ensure backward compatibility with existing database installations
- Update related dispute handling code to work with new schema
… SQLite compatibility

- Add transaction-based column dropping for atomic operations
- Implement fallback table rebuild strategy for older SQLite versions
- Add SQLite version detection to choose optimal migration method
- Create rebuild_disputes_table_without_tokens() helper function
- Ensure backward compatibility across all SQLite versions
- Add comprehensive error handling with proper rollback mechanisms
- Improve logging to indicate which migration strategy is used
- Update get_counterpart_info function documentation for clarity
- Fix typo in notify_dispute_to_users comment (discounterpart -> counterpart)
- Enhance code readability and maintainability
@grunch grunch merged commit ab338c5 into main Sep 4, 2025
2 checks passed
@grunch grunch deleted the remove-token branch September 4, 2025 19:20
@coderabbitai coderabbitai Bot mentioned this pull request Oct 1, 2025
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.

1 participant