Skip to content

Conversation

@grunch
Copy link
Member

@grunch grunch commented Jan 2, 2026

Fix #560

Summary by CodeRabbit

  • New Features

    • Added asynchronous development fee payment system with automatic scheduling and retry capability.
    • Simplified fee structure where development fees are tracked and paid separately, not deducted from buyer or seller transactions.
  • Changes

    • Development fee calculations now unified at order acceptance time; buyers and sellers no longer bear direct development fee costs.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 2, 2026

Walkthrough

The changes refactor the development fee model to eliminate per-party fee splits. A new calculate_dev_fee() function centralizes fee computation based on the Mostro fee percentage. Dev fees are no longer deducted from buyer and seller amounts; instead, they are tracked separately and asynchronously paid by Mostrod through a scheduler job. All amount calculations across order flows are updated to remove per-user dev fee components.

Changes

Cohort / File(s) Summary
Core dev_fee calculation
src/util.rs, docs/DEV_FEE.md
Added public calculate_dev_fee(total_mostro_fee: i64, percentage: f64) -> i64 function for deterministic fee computation. Wrapper get_dev_fee() remains for backwards compatibility. Documentation reflects new payment model.
Order amount calculations
src/flow.rs, src/app/add_invoice.rs
Removed dev_fee split logic. Seller amounts now computed as order.amount + order.fee; buyer amounts as order.amount - order.fee. Hold invoice and order state updates simplified to exclude per-party dev_fee deductions.
Payment/refund flow
src/app/release.rs
Updated retry failure and payment completion logic to deduct only order.fee (not dev_fee split) when computing buyer refund amounts. Simplified fee subtraction in both check_failure_retries() and do_payment() paths.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    
    participant User as User/Buyer
    participant Mostrod as Mostrod
    participant DB as Database
    participant LND as LND/LNURL

    rect rgb(220, 240, 255)
    Note over Mostrod,DB: Order Take & Dev Fee Calculation
    Mostrod->>Mostrod: Take order & calculate<br/>dev_fee from Mostro fee %
    Mostrod->>DB: Store order with dev_fee<br/>(unpaid status)
    DB-->>Mostrod: Order persisted
    end

    rect rgb(240, 220, 255)
    Note over Mostrod,LND: Async Dev Fee Payment (Scheduler Job)
    par Every 60 seconds
        Mostrod->>DB: Query unpaid dev_fees<br/>(settled-hold-invoice/<br/>success statuses)
        DB-->>Mostrod: List of dev_fees
    end
    
    opt Dev fee amount valid
        Mostrod->>LND: Request payment via LNURL
        LND-->>Mostrod: Payment hash
        Mostrod->>DB: Update dev_fee_paid=true<br/>& dev_fee_payment_hash
        DB-->>Mostrod: Success
        Mostrod->>Mostrod: Log verification complete
    end
    
    opt Payment fails
        Mostrod->>Mostrod: Log retry attempt
    end
    end
    
    rect rgb(220, 255, 220)
    Note over User,DB: Seller/Buyer Amount Flows (No Dev Fee Split)
    Mostrod->>DB: Seller receives:<br/>order.amount + order.fee
    Mostrod->>DB: Buyer pays:<br/>order.amount - order.fee
    DB-->>User: Amounts exclude dev_fee
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • Catrya
  • arkanoider

Poem

🐰 A fee so clean, no split in sight,
Mostro hops in, pays the dev's delight!
Amounts ring true, no more subtraction,
Async magic—scheduler in action! 💫

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Change development fund to be paid by mostrod' directly and clearly summarizes the main change: shifting dev fee payment responsibility from users to Mostrod. It is concise, specific, and accurately reflects the core modification across all modified files.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 12f9600 and da7aa23.

📒 Files selected for processing (5)
  • docs/DEV_FEE.md
  • src/app/add_invoice.rs
  • src/app/release.rs
  • src/flow.rs
  • src/util.rs
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

Runtime code lives in src/ directory with subdirectories: src/app/ for order flows and business logic, src/lightning/ for LND bindings and Lightning helpers, src/rpc/ for gRPC service and types, and src/config/ for settings and loaders

Files:

  • src/app/add_invoice.rs
  • src/app/release.rs
  • src/flow.rs
  • src/util.rs
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Use 4-space indent, snake_case for functions, PascalCase for types, and SCREAMING_SNAKE_CASE for constants in Rust code (Rust 2021 edition)
Document non-obvious public APIs with triple-slash /// documentation comments
Prefer tracing spans over ad-hoc logging in Rust code
Co-locate tests in their modules under mod tests blocks and name tests descriptively

Files:

  • src/app/add_invoice.rs
  • src/app/release.rs
  • src/flow.rs
  • src/util.rs
src/app/**

📄 CodeRabbit inference engine (AGENTS.md)

Mirror test fixtures under src/app/ directory where applicable

Files:

  • src/app/add_invoice.rs
  • src/app/release.rs
🧠 Learnings (7)
📓 Common learnings
Learnt from: grunch
Repo: MostroP2P/mostro PR: 554
File: docs/DEV_FEE_TECHNICAL_SPEC.md:1-434
Timestamp: 2025-12-17T13:04:13.036Z
Learning: In the Mostro development fee implementation, the Lightning address `mostro_p2psats.mobi` in src/config/constants.rs is temporary for testing purposes. The production address will be `developmentmostro.network` as documented in docs/DEV_FEE_TECHNICAL_SPEC.md. This intentional mismatch is planned to be resolved before production deployment.
📚 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
  • src/app/release.rs
  • src/flow.rs
  • docs/DEV_FEE.md
  • src/util.rs
📚 Learning: 2025-06-25T22:48:44.741Z
Learnt from: Catrya
Repo: MostroP2P/mostro PR: 502
File: src/app/release.rs:52-55
Timestamp: 2025-06-25T22:48:44.741Z
Learning: The PaymentFailedInfo struct used in src/app/release.rs is defined in mostro-core PR #111, creating a cross-repository dependency that causes compilation errors until the dependency is resolved.

Applied to files:

  • src/app/release.rs
  • src/util.rs
📚 Learning: 2025-06-25T22:48:44.741Z
Learnt from: Catrya
Repo: MostroP2P/mostro PR: 502
File: src/app/release.rs:52-55
Timestamp: 2025-06-25T22:48:44.741Z
Learning: PaymentFailedInfo struct and Payload::PaymentFailed variant are defined in mostro-core PR #111, creating a cross-repository dependency with the Mostro repository that requires careful coordination of merging and version updates.

Applied to files:

  • src/app/release.rs
  • src/util.rs
📚 Learning: 2025-04-27T20:07:24.558Z
Learnt from: arkanoider
Repo: MostroP2P/mostro PR: 475
File: src/db.rs:792-802
Timestamp: 2025-04-27T20:07:24.558Z
Learning: The decrypt_data function from mostro_core::order returns a type that needs to be wrapped with MostroInternalErr to convert it to MostroError, so calls should keep the .map_err(MostroInternalErr) conversion.

Applied to files:

  • src/app/release.rs
  • src/util.rs
📚 Learning: 2025-12-17T13:04:13.036Z
Learnt from: grunch
Repo: MostroP2P/mostro PR: 554
File: docs/DEV_FEE_TECHNICAL_SPEC.md:1-434
Timestamp: 2025-12-17T13:04:13.036Z
Learning: In the Mostro development fee implementation, the Lightning address `mostro_p2psats.mobi` in src/config/constants.rs is temporary for testing purposes. The production address will be `developmentmostro.network` as documented in docs/DEV_FEE_TECHNICAL_SPEC.md. This intentional mismatch is planned to be resolved before production deployment.

Applied to files:

  • src/app/release.rs
  • docs/DEV_FEE.md
  • src/util.rs
📚 Learning: 2025-06-13T12:50:53.424Z
Learnt from: arkanoider
Repo: MostroP2P/mostro PR: 499
File: src/lightning/invoice.rs:21-27
Timestamp: 2025-06-13T12:50:53.424Z
Learning: `ln_exists(address: &str)` returns `Result<(), MostroError>`: `Ok(())` means the Lightning address exists (`tag == "payRequest"`), and `Err(_)` represents any invalid or unreachable address scenario.

Applied to files:

  • src/app/release.rs
  • src/util.rs
🪛 LanguageTool
docs/DEV_FEE.md

[grammar] ~11-~11: Ensure spelling is correct
Context: ...ity - Node operator contribution model (mostrod pays from its earnings, not users) ## ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~210-~210: Ensure spelling is correct
Context: ...rcentage calculation of total Mostro fee - Mostrod pays this amount from its earnings to t...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~493-~493: This adverb was used twice in the sentence. Consider removing one of them or replacing them with a synonym.
Context: ...or tracking purposes only - Seller pays only order.amount + order.fee (no dev_fee ...

(ADVERB_REPETITION_PREMIUM)


[grammar] ~591-~591: Ensure spelling is correct
Context: ...:** The dev fee payment is executed by mostrod from its earnings, not from users. ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~610-~610: Ensure spelling is correct
Context: ...Earned:** Seller has released funds, so mostrod has earned the Mostro fee - **Contribut...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~702-~702: Ensure spelling is correct
Context: ...age` Purpose: Tracking amount that mostrod will pay to the development fund from i...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~1547-~1547: Ensure spelling is correct
Context: ...Verify total dev fee: 300 sats (paid by mostrod from its earnings) 3. **Payment Flow:*...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

⏰ 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 (10)
docs/DEV_FEE.md (1)

1-1593: Excellent comprehensive documentation for the dev fee refactoring.

This documentation thoroughly describes the new development fee model where mostrod (the platform operator) pays dev fees from its earnings rather than charging users directly. The documentation covers:

  • Clear architecture and flow diagrams
  • Implementation status across all phases
  • Database schema and field lifecycle
  • Technical specifications with examples
  • Troubleshooting guidance
  • Testing specifications

The static analysis warnings about "mostrod" are false positives - this is the correct terminology for the Mostro daemon/operator.

src/app/add_invoice.rs (1)

88-101: LGTM! Simplified amount calculations align with the new dev fee model.

The changes correctly remove dev_fee components from buyer and seller amounts:

  • Seller amount: order.amount + order.fee (transparent, as advertised)
  • Buyer amount: order.amount - order.fee (transparent, as advertised)

The use of saturating arithmetic (saturating_add, saturating_sub) properly prevents overflow/underflow issues.

src/util.rs (5)

167-179: Well-designed pure function for dev fee calculation.

The two-function approach is excellent:

  • calculate_dev_fee() is pure and easily testable without global state
  • get_dev_fee() provides convenient access via Settings
  • Simple rounding ensures whole satoshi amounts
  • Clear documentation explains the purpose and usage

This design enables deterministic unit testing as demonstrated in the test suite below.


752-754: Correct hold invoice calculation excluding dev fee.

The seller's hold invoice now includes only the order amount plus the Mostro fee, which is transparent and matches user expectations. Dev fee is no longer charged to the seller at this stage - it will be paid by mostrod from its earnings after the Mostro fee is collected.


899-901: Correct buyer amount calculation excluding dev fee.

The buyer receives the order amount minus only the Mostro fee. Dev fee is not deducted from the buyer's payment, aligning with the new model where mostrod pays the dev fee from its earnings.


1192-1194: Simplified buyer fee validation.

The invoice validation now correctly checks against only the Mostro fee, not including dev fee components. This ensures buyer invoices reflect the actual amount the buyer will receive.


1534-1558: Comprehensive unit tests for dev fee calculation.

The test suite covers:

  • Standard calculation (1000 @ 30% = 300) ✓
  • Rounding behavior (333 @ 30% = 100) ✓
  • Zero fee edge case ✓
  • Tiny amounts that round to zero ✓

All tests directly use calculate_dev_fee() with explicit percentages, avoiding dependency on global Settings. This is the correct approach for unit testing.

src/flow.rs (1)

54-114: Correct flow implementation with simplified amount calculations.

The hold invoice payment flow now correctly excludes dev fee from user-facing amounts:

  • When buyer invoice exists (lines 55-81):

    • Seller sees: amount + fee
    • Buyer sees: amount - fee
  • When buyer invoice is missing (lines 82-114):

    • Buyer is asked to provide invoice for: amount - fee

The comment at line 54 clearly documents the design decision. All calculations use safe saturating arithmetic and are consistent with the new dev fee model.

src/app/release.rs (2)

70-74: Correct retry failure amount calculation.

When payment retries are exhausted, the buyer is notified with the correct amount (order amount minus only the Mostro fee). The validation at line 72-74 properly catches edge cases where the fee might equal or exceed the order amount, returning InvalidAmount error.


440-445: Critical: Correct Lightning payment amount calculation.

This is the actual Lightning payment to the buyer, so correctness is critical. The calculation properly excludes dev fee:

  • Buyer receives: order.amount - order.fee
  • Dev fee is NOT deducted from buyer's payment
  • Validation at line 443-445 ensures amount is valid before payment

The comment clearly documents the design. ✓


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 and usage tips.

@grunch grunch requested a review from Catrya January 2, 2026 17:55
@grunch grunch merged commit 7516ebe into main Jan 2, 2026
6 checks passed
@grunch grunch deleted the development-fund-paid-by-mostrod branch January 2, 2026 18:45
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.

Change development fund to be paid by mostrod instead of users

2 participants