-
Notifications
You must be signed in to change notification settings - Fork 42
fix: correct amount calculations in seller/buyer messages #552
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- pay-invoice: Show seller amount + fee - buyer-took-order: Show seller amount + fee - hold-invoice-payment-accepted: Show buyer amount - fee
WalkthroughPayload construction for hold/order-related messages now sends fee-adjusted amounts: seller-facing payloads use Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/app/add_invoice.rs (1)
88-107: Fee‑adjusted seller/buyer order views look correct; considersaturating_subfor buyerUsing two
SmallOrderviews with different amounts:
- Seller (
BuyerTookOrder):amount + fee– matches the hold‑invoice amount the seller actually paid.- Buyer (
HoldInvoicePaymentAccepted):amount - fee– matches the buyer’s net receive amount.This aligns the messages with the economic model and with the updated flow in
hold_invoice_paid.If you want extra robustness against misconfigured fees and to mirror
set_waiting_invoice_status, you could make the buyer side saturating:- let mut buyer_order = SmallOrder::from(active_order.clone()); - buyer_order.amount = active_order.amount - active_order.fee; + let mut buyer_order = SmallOrder::from(active_order.clone()); + buyer_order.amount = active_order.amount.saturating_sub(active_order.fee);This is defensive rather than strictly necessary given normal fee settings.
src/flow.rs (1)
58-77: Consistent fee‑adjusted payloads inhold_invoice_paid; optionally harden buyer amount and add a targeted testThe new seller/buyer
SmallOrderviews here:
seller_order_data.amount = order.amount + order.feeforBuyerTookOrder.buyer_order_data.amount = order.amount - order.feeforHoldInvoicePaymentAccepted.correctly mirror the economic model (seller pays
amount + fee, buyer receivesamount - fee) and are consistent withadd_invoice_actionandset_waiting_invoice_status.For extra safety and consistency with
set_waiting_invoice_status, you might make the buyer side saturating:- let mut buyer_order_data = order_data.clone(); - buyer_order_data.amount = order.amount - order.fee; + let mut buyer_order_data = order_data.clone(); + buyer_order_data.amount = order.amount.saturating_sub(order.fee);Given this logic is the crux of issue #551, it may also be worth adding a small test that constructs an
Order { amount, fee, .. }and asserts that the enqueuedPayload::OrderforBuyerTookOrderandHoldInvoicePaymentAcceptedcarriesamount + feeandamount - feerespectively (possibly by factoring the construction into a helper so it’s testable without a real DB/LND).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/app/add_invoice.rs(1 hunks)src/flow.rs(1 hunks)src/util.rs(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: arkanoider
Repo: MostroP2P/mostro PR: 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.
📚 Learning: 2025-07-17T13:51:17.338Z
Learnt from: arkanoider
Repo: MostroP2P/mostro PR: 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/util.rssrc/app/add_invoice.rssrc/flow.rs
🧬 Code graph analysis (2)
src/app/add_invoice.rs (1)
src/util.rs (1)
enqueue_order_msg(924-939)
src/flow.rs (1)
src/util.rs (1)
enqueue_order_msg(924-939)
⏰ 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). (1)
- GitHub Check: test
🔇 Additional comments (1)
src/util.rs (1)
677-680: Pay‑invoice payload now matches seller’s fee‑inclusive hold amountSetting
new_order.amount = order.amount + order.feemakes thePayInvoicePaymentRequestpayload consistent with the hold invoice amount the seller actually pays, and with the fee‑adjusted views used elsewhere. This is a clean, localized fix to the display amount.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/app/add_invoice.rs (1)
88-94: Use saturating arithmetic for consistency and safety.Line 89 uses direct addition which could theoretically overflow. For consistency with the buyer-side calculation (line 101) that uses
saturating_sub, consider usingsaturating_addhere.Apply this diff:
- seller_order.amount = active_order.amount + active_order.fee; + seller_order.amount = active_order.amount.saturating_add(active_order.fee);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/app/add_invoice.rs(1 hunks)src/flow.rs(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/flow.rs
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: arkanoider
Repo: MostroP2P/mostro PR: 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.
📚 Learning: 2025-07-17T13:51:17.338Z
Learnt from: arkanoider
Repo: MostroP2P/mostro PR: 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/app/add_invoice.rs
🧬 Code graph analysis (1)
src/app/add_invoice.rs (1)
src/util.rs (1)
enqueue_order_msg(924-939)
⏰ 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). (1)
- GitHub Check: clippy
🔇 Additional comments (1)
src/app/add_invoice.rs (1)
100-107: saturating_sub is appropriate here; fee constraints are implicitly enforced by configuration.The
saturating_subon line 101 is correct and necessary. The fee calculation inget_fee()(src/util.rs:149-154) computes(fee_percentage * amount) / 2.0, which mathematically guaranteesfee < amountas long as the fee percentage setting is below 200%—a reasonable operational constraint. This implicit validation through configuration is reinforced by the test assertion at src/take_sell.rs:359 that confirmsexpected_fee < amount. The saturating_sub serves as defensive programming to handle the result safely even if unexpected values occur.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/app/add_invoice.rs (1)
88-107: Fee-adjusted SmallOrder payloads for seller/buyerThe new seller/buyer payload amounts look conceptually right: seller’s
BuyerTookOrdernow usesamount + fee, buyer’sHoldInvoicePaymentAcceptedusesamount - fee, andsaturating_add/saturating_subavoid integer overflow in extreme cases.One thing to verify carefully: with the related
show_hold_invoice/new_orderchange insrc/util.rs(wherenew_order.amount = order.amount + order.fee), isactive_order.amounthere still the pre-fee trade amount, or has it already been adjusted to include the fee? If it already includes the fee, these lines will effectively:
- show
amount + 2 * feeto the seller, and- show the original
amount(notamount - fee) to the buyer.Might be worth tracing
amountthrough the full flow (order creation → show_hold_invoice → update_order_event → add_invoice_action) to confirm we’re not double-applying the fee in any path. Ifamountis already seller-side at this stage, the formulas likely need to be based on the original pre-fee amount instead.Also, if you keep touching this logic, consider a small helper that, given
(amount, fee), returns(seller_amount, buyer_amount)so both call sites (here and inhold_invoice_paid) can’t drift apart.src/flow.rs (1)
58-77: Fee-adjustedSmallOrderamounts inhold_invoice_paidUsing separate clones for seller and buyer and setting:
- seller:
amount = order.amount.saturating_add(order.fee)forBuyerTookOrder- buyer:
amount = order.amount.saturating_sub(order.fee)forHoldInvoicePaymentAcceptedmatches the intended “seller sees amount+fee, buyer sees amount-fee” behaviour, assuming
order.amountis still the pre-fee trade amount at this point.Given the related change in
src/util.rs(wherenew_order.amount = order.amount + order.feeduring the hold-invoice flow), can you double-check whatorder.amountrepresents here whenhold_invoice_paidruns? If it’s already been updated toamount + fee, this new logic would:
- report
amount + 2 * feeto the seller, and- report just
amount(no fee discount) to the buyer,which would contradict the PR’s goal. Tracing
amount/feethroughshow_hold_invoice→ DB update →hold_invoice_paidwould clarify whether the base amount is being used consistently.As a minor follow-up, you might also want to use
saturating_subin theWaitingBuyerInvoicebranch (let new_amount = order_data.amount - order.fee;) for consistency with the buyer-facing path here, although realistic values shouldn’t come close to overflowing i64.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/app/add_invoice.rs(1 hunks)src/flow.rs(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: arkanoider
Repo: MostroP2P/mostro PR: 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.
📚 Learning: 2025-07-17T13:51:17.338Z
Learnt from: arkanoider
Repo: MostroP2P/mostro PR: 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/app/add_invoice.rssrc/flow.rs
🧬 Code graph analysis (2)
src/app/add_invoice.rs (1)
src/util.rs (1)
enqueue_order_msg(924-939)
src/flow.rs (1)
src/util.rs (1)
enqueue_order_msg(924-939)
⏰ 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). (1)
- GitHub Check: test
grunch
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
arkanoider
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix #551
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.