Conversation
- when scheduler changes state of waiting-buyer-invoice or waiting-payment orders to pending or canceled users are notified with a message - refined some code to pass strict cargo clippy --all-targets --all-features -- -D warnings command in gh actions
WalkthroughConsolidates per-key pubkey DB edits into a single Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant S as Scheduler
participant DB as Database
participant MQ as MsgQueue
participant E as EventPublisher
rect rgba(230,245,255,0.5)
note over S: job_cancel_orders tick — determine orders to cancel
S->>DB: get_order_status(order_id) / get_order_kind(order_id)
alt retrieval ok
S->>S: compute maker_action, new_status, build edited_order
S->>DB: edit_pubkeys_order(pool, edited_order) %% consolidated DB update
else retrieval failed
S-->>S: warn and continue
end
end
rect rgba(240,255,240,0.5)
S->>E: update_order_event(edited_order)
alt event update ok
S->>S: notify_users_canceled_order(edited_order)
S->>MQ: enqueue_order_msg(maker, payload?)
S->>MQ: enqueue_order_msg(taker, payload)
S->>DB: persist updated order/status
else event update failed
S-->>S: warn and continue
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/app/cancel.rs (1)
176-196: Use edited order for event update and persist event_id; avoid stale dataAfter clearing pubkeys you publish using the original
order, so the Nostr event can carry stale pubkeys. Also, the returnedOrderfromupdate_order_eventisn’t persisted, leavingevent_idstale in DB.Apply:
// Reset api quotes reset_api_quotes(order); - if order.is_buy_order().is_ok() { - info!("Cancel seller data from db"); - edit_pubkeys_order(pool, order) - .await - .map_err(|e| MostroInternalErr(ServiceError::DbAccessError(e.to_string())))?; - } - if order.is_sell_order().is_ok() { - info!("Cancel buyer data from db"); - edit_pubkeys_order(pool, order) - .await - .map_err(|e| MostroInternalErr(ServiceError::DbAccessError(e.to_string())))?; - } + // Clear counterparty pubkeys (returns updated order reflecting DB state) + let edited_order = edit_pubkeys_order(pool, order) + .await + .map_err(|e| MostroInternalErr(ServiceError::DbAccessError(e.to_string())))?; update_order_to_initial_state(pool, order.id, order.amount, order.fee) .await .map_err(|e| MostroInternalErr(ServiceError::DbAccessError(e.to_string())))?; - update_order_event(my_keys, Status::Pending, order) - .await - .map_err(|e| MostroInternalErr(ServiceError::NostrError(e.to_string())))?; + // Publish using the edited order (pubkeys cleared) and persist event_id/status + let order_updated = update_order_event(my_keys, Status::Pending, &edited_order) + .await + .map_err(|e| MostroInternalErr(ServiceError::NostrError(e.to_string())))?; + order_updated + .update(pool) + .await + .map_err(|e| MostroInternalErr(ServiceError::DbAccessError(e.to_string())))?;This mirrors the persist pattern used in
cancel_order_by_makerand ensures the published event matches DB state.
🧹 Nitpick comments (9)
src/app/order.rs (2)
248-249: Avoid vacuous test: assert the structural condition
let _ = result.is_ok() || result.is_err();does nothing. Keep structural intent but assert it to prevent silent passes.Apply:
- // Structural check: ensure call does not panic - let _ = result.is_ok() || result.is_err(); + // Structural check: ensure call returns a Result without panicking + assert!(result.is_ok() || result.is_err());
271-272: Make structural test explicitPrefer asserting the condition to avoid a no-op.
- // Structural check: ensure call returns a Result without panicking - let _ = result2.is_ok() || result2.is_err(); + // Structural check: ensure call returns a Result without panicking + assert!(result2.is_ok() || result2.is_err());src/app.rs (4)
491-505: No-op tests: prefer minimal assertionsThese are pure no-ops. To keep structural scope but avoid vacuous passes, assert a benign invariant (e.g., that the function returns or branch executes).
- Replace comment-only “No-op” lines with an assert!(true) or a simple property check tied to the code path.
599-605: Structural match: assert handled arms to avoid empty branchesEmpty branches are fine for structure, but add a trivial assertion to avoid completely vacuous test code.
- Inside handled arms, add
assert!(true);orlet _: () = ();to indicate intentional no-op.
671-674: Prefer an assertion in the expected branchReplace the “No-op” with
assert!(true);so the branch is exercised explicitly; keepunreachable!()for the else as-is.
691-696: Use matches! for structural checksInstead of an empty
if let, assert the variant to keep the structural test meaningful.- // Test that we got a message of some kind - if let Message::Order(_) = message {} + // Test that we got an Order message + assert!(matches!(message, Message::Order(_)));src/scheduler.rs (3)
241-308: Optional: include trade_index in notifications (if available)Both maker/taker notifications pass
trade_index: None. If you can derive the maker’s/taker’s current trade index fromupdated_order, consider setting it to keep sequencing consistent.
- Verify whether downstream validation uses trade_index on cancel/republish notifications. If so, populate it from
updated_order.trade_index_{buyer|seller}matching the recipient role.
371-392: Don’t ignore DB reset result before republish; handle Ok(false)/ErrIgnoring
update_order_to_initial_statecan leave inconsistent state. Handle failure and short-circuit.- let _ = update_order_to_initial_state( - &pool, - order.id, - order.amount, - order.fee, - ) - .await; + match update_order_to_initial_state( + &pool, + order.id, + order.amount, + order.fee, + ) + .await { + Ok(true) => {} + Ok(false) => { + tracing::warn!( + "No rows updated resetting order {} to initial state", + order.id + ); + continue; + } + Err(e) => { + tracing::warn!( + "Failed to reset order {} to initial state: {}", + order.id, e + ); + continue; + } + }
415-423: Replace println! with tracing
println!in async jobs bypasses your logging config.- println!("Edited order: {:?}", edited_order); + tracing::debug!("Edited order: {:?}", edited_order);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
src/app.rs(6 hunks)src/app/admin_settle.rs(0 hunks)src/app/cancel.rs(2 hunks)src/app/order.rs(2 hunks)src/app/take_sell.rs(2 hunks)src/bitcoin_price.rs(1 hunks)src/cli.rs(2 hunks)src/db.rs(3 hunks)src/lightning/invoice.rs(1 hunks)src/rpc/mod.rs(2 hunks)src/scheduler.rs(3 hunks)src/util.rs(0 hunks)
💤 Files with no reviewable changes (2)
- src/app/admin_settle.rs
- src/util.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
🧬 Code graph analysis (2)
src/app/cancel.rs (1)
src/db.rs (2)
edit_pubkeys_order(649-703)update_order_to_initial_state(776-813)
src/scheduler.rs (2)
src/util.rs (2)
enqueue_order_msg(921-936)update_order_event(562-599)src/db.rs (3)
None(650-650)update_order_to_initial_state(776-813)edit_pubkeys_order(649-703)
🔇 Additional comments (2)
src/db.rs (2)
649-703: Consolidated pubkey reset looks correct; verify trade_index side-effectsThe Buy→seller_pubkey and Sell→buyer_pubkey mapping plus corresponding master key reset is sound. Dynamic SQL is reasonable here.
- Confirm that callers don’t expect
trade_index_{buyer|seller}to be reset alongside pubkeys on cancel/republish. If they do, extend this UPDATE accordingly or perform it in the caller to keep concerns separate.
9-9: Minor: alias import clarityUsing
Kind as OrderKindimproves readability where both Kind and Status are in scope. LGTM.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/app/cancel.rs (1)
178-182: Use the returned order to ensure state consistency.The
edit_pubkeys_orderfunction returns a refreshedOrderobject after updating the database, but this result is discarded. While the subsequent operations (update_order_to_initial_state,update_order_event) may work with the staleorderreference in this specific flow, it's a safer practice to use the canonical post-update state.According to the enriched summary, the scheduler now relies on the edited order object for its cancellation flow. Adopting the same pattern here ensures consistency across cancel paths and avoids potential issues if future code expects the order pubkey fields to reflect the nulled state.
Apply this diff:
// clean pubkeys from db - let _ = edit_pubkeys_order(pool, order) + *order = edit_pubkeys_order(pool, order) .await .map_err(|e| MostroInternalErr(ServiceError::DbAccessError(e.to_string())))?;This ensures that the in-memory
orderreflects the database state after pubkey nullification, maintaining consistency with the scheduler's approach described in the PR context.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/app/cancel.rs(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/app/cancel.rs (1)
src/db.rs (2)
edit_pubkeys_order(649-703)update_order_to_initial_state(776-813)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: MSRV build (1.86.0)
- GitHub Check: clippy
🔇 Additional comments (1)
src/app/cancel.rs (1)
1-1: LGTM! Clean consolidation of DB imports.The import statement correctly brings in the new unified
edit_pubkeys_orderfunction, replacing the previous individual pubkey edit functions. This aligns with the consolidation approach described in the related db.rs changes.
Catrya
left a comment
There was a problem hiding this comment.
Hi @arkanoider
It works fine for me, but I'm seeing this weird thing. I think it's from mostro-cli. Anyway, I'll leave it here just in case.
User A takes an order and doesn't respond, it's republished and returns to pending. When A tries to take the same order, I see this in mostro-cli:
error returned from database: (code: 1555) UNIQUE constraint failed: orders.id
also have an error in mostrod logs if user continues:
2025-10-03T19:43:52.036993Z WARN mostrod::app: Error checking trade index: Sending cantDo message to user for InvalidTradeIndex
|
@arkanoider well, regardless of the branch of mostrod (main or this) or mostro-cli where i am, if the user takes an order, does nothing, and then after the order returns to pending, tries to take it again, mostro always responds: And after that, the user can't create or take a new order because Mostro always responds the same way. with mobile client i have not this error |
So with Mostro-cli on my develop branch : https://github.com/MostroP2P/mostro-cli/tree/aligning-message you are not able to take an order? Did I understand right? |
There was a problem hiding this comment.
Actionable comments posted: 7
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/app.rs(6 hunks)src/app/order.rs(2 hunks)src/util.rs(0 hunks)
💤 Files with no reviewable changes (1)
- src/util.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: MSRV build (1.86.0)
- GitHub Check: clippy
🔇 Additional comments (1)
src/app.rs (1)
676-679: Inconsistent test logic.The test uses
unreachable!for non-GiftWrap kinds, but this contradicts the stated purpose of a structural test. If only GiftWrap events are being tested, the match should verify this, not panic.Consider refactoring to clarify intent:
match kind { NostrKind::GiftWrap => { - // This is the expected path for gift wrap events - // No-op + // Verify this is the GiftWrap kind + assert_eq!(kind, NostrKind::GiftWrap); } - _ => unreachable!("Only GiftWrap events are considered in this test scope"), + _ => { + // This test only covers GiftWrap + } }Likely an incorrect or invalid review comment.
|
Ok! Rabbit rants were all about nipticks in tests, we are testing correctly our needings. |
|
@coderabbitai take a look at last commit if is ok removing tautological result on tests... |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/app/order.rs (1)
219-231: Consider aligning test names with actual scope.Tests like
test_order_action_with_valid_order,test_order_action_range_order_validation, andtest_order_action_zero_amount_with_premiumhave names suggesting they validate specific business logic, but they don't include order payloads (line 176), so they only test the early-return path and message construction without panics. While this aligns with the structural testing approach, the names might mislead future maintainers.Consider either:
- Renaming to reflect structural scope (e.g.,
test_order_action_message_construction_no_panic)- Adding comments explaining the limited scope
- Leaving as-is if the naming convention is understood across the project
Based on learnings.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/app.rs(5 hunks)src/app/order.rs(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/app.rs
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-09T14:06:50.026Z
Learnt from: arkanoider
PR: MostroP2P/mostro#530
File: src/app/order.rs:278-279
Timestamp: 2025-10-09T14:06:50.026Z
Learning: In the Mostro project, tests in files like `src/app/order.rs` may use structural checks to ensure functions like `order_action` do not panic during message construction, rather than validating specific error variants.
Applied to files:
src/app/order.rs
🧬 Code graph analysis (1)
src/app/order.rs (1)
src/app.rs (2)
create_test_unwrapped_gift(428-444)create_test_message(417-425)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: test
- GitHub Check: MSRV build (1.86.0)
🔇 Additional comments (6)
src/app/order.rs (6)
230-230: LGTM! Structural test aligns with project approach.The change to discard the result with
let _ = ...correctly implements a structural check that ensures the function doesn't panic, which aligns with the project's testing approach. Based on learnings.
241-241: LGTM! Structural test aligns with project approach.The structural check is appropriate for ensuring no panics occur during message construction. Based on learnings.
251-252: LGTM! Clear intent with explanatory comment.The comment clearly documents the structural test intent, and the implementation correctly checks for panics without asserting on specific Result variants. Based on learnings.
265-265: LGTM! Structural test for trade index logic.The test correctly implements a structural check for the trade index fallback case where
sender == rumor.pubkey. Based on learnings.
272-273: LGTM! Structural test with clear documentation.The comment and implementation correctly express the intent to check for non-panicking execution rather than behavioral validation. Based on learnings.
277-277: LGTM! Structural test for trade index presence.The test appropriately checks that the function doesn't panic when a trade_index is provided. Based on learnings.
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 584 🏁 Script executed: Length of output: 3520 @arkanoider, yes, the last commit looks good! You're correctly removing tautological assertions from the tests. Here's why these changes are appropriate: What was removed:
What remains:
Summary: These are good cleanups from the CodeRabbit suggestions! 🎉 |
Hi @grunch , @Catrya ,
this is the PR for #528 , i tested the cases and seems working, but it was a bit tricky and I also reorganize the code in the scheduler to make it work correctly.
I will check conflicts and rabbit suggestion, @Catrya double check when you can if it's all ok also on your side!
Summary by CodeRabbit
New Features
Refactor
Tests
Chores