Skip to content

chore: upgrade sqlx to 0.9 and drop sqlx-crud#791

Merged
grunch merged 6 commits into
mainfrom
chore/sqlx-0.9
Jul 1, 2026
Merged

chore: upgrade sqlx to 0.9 and drop sqlx-crud#791
grunch merged 6 commits into
mainfrom
chore/sqlx-0.9

Conversation

@arkanoider

@arkanoider arkanoider commented Jun 27, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Drop sqlx-crud; use mostro_core::db::Crud for Order/Dispute and local Bond CRUD
  • Upgrade sqlx 0.6.20.9.0 (runtime-tokio, tls-rustls-ring, macros)
  • Bump mostro-core to 0.14 (sqlx 0.9 + local Crud trait)
  • Raise MSRV to Rust 1.94.0 (toolchain + CI)
  • Replace 5 query! macros with runtime sqlx::query() — removes .sqlx/ offline cache workflow
  • Remove init_db.sh and legacy sqlx-data.json; update docs (migrations run on mostrod connect)
  • sqlx 0.9 API fixes: Separated lifetimes, AssertSqlSafe for dynamic SQL, migration.sql.as_str()

query! removal trade-off

Only five static UPDATE helpers in src/db.rs used query!; the rest of the daemon already uses runtime SQL (query, query_as, QueryBuilder, Crud).

We give up: compile-time checks on those five statements (column names, bind count, SQL syntax via .sqlx/ / cargo sqlx prepare).

We gain: no offline cache workflow (init_db.sh, .sqlx/, CI DATABASE_URL), simpler sqlx 0.9 upgrade, and consistency with the rest of db.rs.

Risk is limited: all five are fixed SQL on orders / users primary keys; no generated row types were lost. Schema/query drift is still covered by migrations, integration tests, and runtime SQLite errors — same model as the other ~95% of DB code.

Test plan

  • cargo fmt --all
  • cargo clippy --all-targets --all-features -- -D warnings
  • cargo test (496 tests passed)
  • cargo build with mostro-core 0.14 from crates.io

Notes

  • Requires mostro-core 0.14 published on crates.io
  • No cargo sqlx prepare or DATABASE_URL needed for CI builds after this change

Summary by CodeRabbit

  • New Features

    • Added bond-related database support and improved handling for bond updates.
  • Bug Fixes

    • Hardened database queries to improve safety and reliability across multiple workflows.
    • Ensured bond updates preserve created_at.
  • Documentation

    • Updated installation/development guides for Rust 1.94+ and sqlx-cli 0.9.0.
    • Switched setup guidance to migration-based initialization, with migrations applied automatically on first connect.
  • Chores

    • Updated CI MSRV build job to Rust 1.94.0.
    • Updated SQLx dependency to 0.9.0 and removed offline SQLx metadata artifacts.

arkanoider and others added 2 commits June 25, 2026 21:20
Replace the unmaintained sqlx-crud dependency with the in-tree Crud trait
from mostro-core 0.13.2. Add hand-written Bond persistence in bond/crud.rs
and switch all Order, Dispute, and Bond call sites to mostro_core::db::Crud.

Co-authored-by: Cursor <cursoragent@cursor.com>
Bump mostro-core to 0.14, sqlx 0.9, and MSRV 1.94; replace query!
macros with runtime SQL; remove init_db.sh and offline cache files.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ec22d5ef-d9d1-4b4e-8eaa-174440d9a69a

📥 Commits

Reviewing files that changed from the base of the PR and between 49dc92e and f93e255.

📒 Files selected for processing (1)
  • src/app/bond/crud.rs

Walkthrough

Updates the project to Rust 1.94.0 and sqlx 0.9.0, removes offline SQLx workflows, and shifts database access toward runtime SQL with AssertSqlSafe plus migration-based schema handling. Bond CRUD/db helpers and tests are updated to match.

Changes

SQLx 0.9 Migration Refresh

Layer / File(s) Summary
Toolchain and dependency versions
.github/workflows/ci.yml, rust-toolchain.toml, Cargo.toml
Rust toolchain and CI MSRV move to 1.94.0; sqlx updates to 0.9.0; mostro-core bumps to 0.14.
Migration workflow docs and deleted artifacts
AGENTS.md, INSTALL.md, README.md, docs/ANTI_ABUSE_BOND.md, docs/ARCHITECTURE.md, docs/README.md, docs/STARTUP_AND_CONFIG.md
Docs replace SQLx offline metadata and init_db.sh flows with migrations under migrations/ and mostrod applying them on connect; init_db.sh and sqlx-data.json are removed.
Database query hardening
src/db.rs
Dynamic SQL is wrapped with AssertSqlSafe or replaced with fixed query branches and bound parameters; several sqlx::query! calls become runtime sqlx::query.
Bond CRUD and db hardening
src/app/bond/crud.rs, src/app/bond/db.rs
Bond updates keep created_at insert-only, by-id lookup delegates through Bond::by_id, recursive SQL is wrapped with AssertSqlSafe, and tests cover bind alignment plus created_at preservation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers: ermeme, Catrya

Poem

A bunny hopped through migrations new,
With SQLx 0.9 shining through.
No offline crumbs, no JSON trail,
Just bound params and a sturdy rail.
Rust 1.94, wee ears aflame—
Hop hop, the database kept its name 🐇

🚥 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 accurately summarizes the main change: upgrading sqlx to 0.9 and removing sqlx-crud.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/sqlx-0.9

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

🤖 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 @.github/workflows/ci.yml:
- Line 69: The checkout step in the CI job is keeping GitHub credentials
persisted in git config unnecessarily. Update the workflow’s actions/checkout
usage to disable persisted credentials by setting persist-credentials to false,
and only keep them enabled if a later step in this same job actually needs to
push changes. Locate the change in the checkout action entry within the CI
workflow.
- Around line 69-70: Both actions in the CI workflow are still referenced by
mutable version tags, so update the `uses:` entries in the MSRV job to immutable
commit SHAs instead of `actions/checkout@v6` and
`dtolnay/rust-toolchain@stable`. Keep the same workflow behavior, but pin these
dependencies to specific revisions so the `ci.yml` job no longer relies on
drifting upstream tags.
🪄 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: 61e3b7f5-2a20-4434-8207-f79f7ae968e3

📥 Commits

Reviewing files that changed from the base of the PR and between 170f087 and d87ddd9.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (35)
  • .github/workflows/ci.yml
  • AGENTS.md
  • Cargo.toml
  • INSTALL.md
  • README.md
  • docs/ANTI_ABUSE_BOND.md
  • docs/ARCHITECTURE.md
  • docs/ORDERS_AND_ACTIONS.md
  • docs/README.md
  • docs/STARTUP_AND_CONFIG.md
  • init_db.sh
  • rust-toolchain.toml
  • sqlx-data.json
  • src/app/add_invoice.rs
  • src/app/admin_cancel.rs
  • src/app/admin_settle.rs
  • src/app/admin_take_dispute.rs
  • src/app/bond/crud.rs
  • src/app/bond/db.rs
  • src/app/bond/flow.rs
  • src/app/bond/mod.rs
  • src/app/bond/model.rs
  • src/app/bond/payout.rs
  • src/app/bond/slash.rs
  • src/app/cancel.rs
  • src/app/dispute.rs
  • src/app/fiat_sent.rs
  • src/app/rate_user.rs
  • src/app/release.rs
  • src/app/take_sell.rs
  • src/app/trade_pubkey.rs
  • src/db.rs
  • src/flow.rs
  • src/scheduler.rs
  • src/util.rs
💤 Files with no reviewable changes (2)
  • init_db.sh
  • sqlx-data.json

Comment thread .github/workflows/ci.yml
Comment thread .github/workflows/ci.yml
Keep sqlx 0.9 / mostro-core 0.14 changes on top of merged #789.

Co-authored-by: Cursor <cursoragent@cursor.com>

@ermeme ermeme 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.

Strict review

Request changes: the CI workflow still uses mutable action refs and keeps checkout credentials persisted unnecessarily. Please pin actions/checkout and dtolnay/rust-toolchain to immutable SHAs, and set persist-credentials: false unless a later step in this job actually needs to push.

Comment thread .github/workflows/ci.yml
Comment thread .github/workflows/ci.yml
@mostronatorcoder

Copy link
Copy Markdown
Contributor

I did a strict pass on this PR and I do not currently see a correctness blocker.

What I specifically checked:

  • the sqlx bump to 0.9.0 and the MSRV bump to 1.94.0
  • the migration from sqlx_crud::Crud to mostro_core::db::Crud
  • the removal of query! / offline metadata in favor of runtime sqlx::query() for the remaining fixed UPDATE helpers
  • the dynamic-SQL callsites now wrapped with AssertSqlSafe
  • whether the changes in src/db.rs, src/app/bond/crud.rs, and src/app/bond/db.rs accidentally changed persistence semantics

My read is that this is a reasonable daemon-side follow-up to the earlier mostro-core and bond CRUD cleanup.

The important part for me was making sure the PR did not reintroduce the unsafe string-dispatch pattern we already pushed back on elsewhere, and it does not. The places that moved away from query! are still fixed statements with explicit bind order, and the spots that remain dynamic were already dynamic in shape and now use AssertSqlSafe as required by sqlx 0.9.

I also ran cargo test locally on this branch, and it passed (496 tests).

So from my side, although this does trade away compile-time SQL checking for the last few query! callsites, I do not see a functional regression or a correctness blocker in the current patch.

Delegate find_bond_by_id to Crud::by_id, omit created_at from UPDATE,
and add sentinel-based INSERT column/bind alignment tests.

Closes #790

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{}

ermeme[bot]
ermeme Bot previously approved these changes Jun 30, 2026

@ermeme ermeme 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.

Reviewed the latest head again. The sqlx 0.9 / MSRV 1.94 bump looks sound, and the earlier CI hardening comments were already addressed or correctly treated as non-blocking for this PR. No blockers remain.

@codaMW

codaMW commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Tested on regtest with mostro-core 0.14.0 from crates.io. ACK, verified the specific hardening claims.
Build + lint + suite
• Builds clean on Rust 1.94.0 (toolchain auto-synced from rust-toolchain. toml, no friction) against mostro-core 0.14.0 from crates.io.
• cargo clippy --all-targets --all-features -- -D warnings: clean.
• cargo test: 497 passes. The one failure is test_lnurl_validation_with_test_server (AddrInUse) a pre-existing port-bind flake in the Lightning subsystem this PR doesn't touch; fails identically on main, not from this PR.
#790 hardening tasks, each verified individually
• created_at immutability (LOW): push_bond_update_set omits created_at (insert-only, with an explanatory comment); update_preserves_created_at passes.
• find_bond_by_id delegation (MED): now delegates to Bond::by_id (the Crud impl) instead of reimplementing the SELECT, so the trait path is exercised in production with no duplicate to diverge.
• column/bind drift (MED): the overselling comment is gone; BOND_INSERT_COLUMNS now references bond_insert_column_bind_alignment, which inserts a per-field sentinel bond and asserts each column's persisted value matches, catching a misaligned bind that value-round-trip tests would miss (the positional check #790 called the ideal option).
Runtime, migration-on-connect (the init_db.sh removal)
• Removed ~/.mostro/mostro.db and started mostrod against a fresh DB: it created the file and applied migrations on connect, coming up clean through Scheduler Started with no no such table/schema errors. Confirmed the bonds table exists in the migrated DB (sqlite3 .tables), so the bond migrations applied correctly on connect.
Live bond persistence: enabled anti_abuse_bond, created an order via mostro-cli. The maker-bond flow fired and persisted a real bond through the new Crud path, daemon logged Maker bond requested: bond_id=5706044e-… amount_sats=1000, and the DB showed that exact bond id in requested state with correct amount_sats/created_at. Confirms the create_bond INSERT via mostro_core::db::Crud works end-to-end through the live daemon, not just in unit tests. (Didn't pay the hold invoice, so the requested→locked UPDATE transition wasn't exercised live that path is covered by update_preserves_created_at.)

Scope (honest): verified build/lint/suite, the three hardening fixes via their specific tests + code paths, migration-on-connect from a fresh DB, and live bond INSERT through the daemon. Did not exercise a full multi-party dispute → slash → payout flow (needs funded LN channels + admin resolution); the bond CRUD paths it would exercise are covered by the unit tests above.

@codaMW codaMW 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.

Tested on regtest with mostro-core 0.14.0 from crates.io. ACK, verified the specific hardening claims.
Build + lint + suite
• Builds clean on Rust 1.94.0 (toolchain auto-synced from rust-toolchain. toml, no friction) against mostro-core 0.14.0 from crates.io.
• cargo clippy --all-targets --all-features -- -D warnings: clean.
• cargo test: 497 passes. The one failure is test_lnurl_validation_with_test_server (AddrInUse) a pre-existing port-bind flake in the Lightning subsystem this PR doesn't touch; fails identically on main, not from this PR.
#790 hardening tasks, each verified individually
• created_at immutability (LOW): push_bond_update_set omits created_at (insert-only, with an explanatory comment); update_preserves_created_at passes.
• find_bond_by_id delegation (MED): now delegates to Bond::by_id (the Crud impl) instead of reimplementing the SELECT, so the trait path is exercised in production with no duplicate to diverge.
• column/bind drift (MED): the overselling comment is gone; BOND_INSERT_COLUMNS now references bond_insert_column_bind_alignment, which inserts a per-field sentinel bond and asserts each column's persisted value matches, catching a misaligned bind that value-round-trip tests would miss (the positional check #790 called the ideal option).
Runtime, migration-on-connect (the init_db.sh removal)
• Removed ~/.mostro/mostro.db and started mostrod against a fresh DB: it created the file and applied migrations on connect, coming up clean through Scheduler Started with no no such table/schema errors. Confirmed the bonds table exists in the migrated DB (sqlite3 .tables), so the bond migrations applied correctly on connect.
Live bond persistence: enabled anti_abuse_bond, created an order via mostro-cli. The maker-bond flow fired and persisted a real bond through the new Crud path, daemon logged Maker bond requested: bond_id=5706044e-… amount_sats=1000, and the DB showed that exact bond id in requested state with correct amount_sats/created_at. Confirms the create_bond INSERT via mostro_core::db::Crud works end-to-end through the live daemon, not just in unit tests. (Didn't pay the hold invoice, so the requested→locked UPDATE transition wasn't exercised live that path is covered by update_preserves_created_at.)

Scope (honest): verified build/lint/suite, the three hardening fixes via their specific tests + code paths, migration-on-connect from a fresh DB, and live bond INSERT through the daemon. Did not exercise a full multi-party dispute → slash → payout flow (needs funded LN channels + admin resolution); the bond CRUD paths it would exercise are covered by the unit tests above.

The BOND_INSERT_COLUMNS doc pointed to db.rs, but the
bond_insert_column_bind_alignment test lives in bond/db.rs.
Disambiguate from the top-level src/db.rs.

@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.

tACK

@grunch grunch merged commit 2b8e45c into main Jul 1, 2026
5 checks passed
@grunch grunch deleted the chore/sqlx-0.9 branch July 1, 2026 19:57
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.

3 participants