|
3 | 3 | import pytest |
4 | 4 | import pytest_asyncio |
5 | 5 |
|
6 | | -from cashu.core.base import MeltQuoteState, MintQuoteState |
| 6 | +from cashu.core.base import MeltQuoteState, Method, MintQuoteState, Unit |
7 | 7 | from cashu.core.models import ( |
8 | 8 | GetInfoResponse, |
9 | 9 | MintMethodSetting, |
|
21 | 21 | from cashu.wallet.wallet import Wallet |
22 | 22 | from tests.helpers import ( |
23 | 23 | get_real_invoice, |
| 24 | + get_real_invoice_fee_leaf, |
24 | 25 | get_real_invoice_routed, |
25 | 26 | is_cln_backend, |
26 | 27 | is_fake, |
@@ -89,7 +90,11 @@ async def test_api_keys(ledger: Ledger): |
89 | 90 | for keyset in ledger.keysets.values() |
90 | 91 | ] |
91 | 92 | } |
92 | | - assert response.json() == expected |
| 93 | + result = response.json() |
| 94 | + # PostgreSQL can return the same keysets in a different order. |
| 95 | + result["keysets"].sort(key=lambda keyset: keyset["id"]) |
| 96 | + expected["keysets"].sort(key=lambda keyset: keyset["id"]) |
| 97 | + assert result == expected |
93 | 98 |
|
94 | 99 |
|
95 | 100 | @pytest.mark.asyncio |
@@ -569,8 +574,8 @@ async def test_melt_external_routing_fee_rounding(ledger: Ledger, wallet: Wallet |
569 | 574 | await wallet.mint(1024, quote_id=mint_quote.quote) |
570 | 575 | assert wallet.balance == 1024 |
571 | 576 |
|
572 | | - # external invoice that the mint can only pay through a routing node |
573 | | - invoice_payment_request = get_real_invoice_routed(1000) |
| 577 | + # The isolated fee leaf prevents LDK from offering a cheaper, whole-sat route. |
| 578 | + invoice_payment_request = get_real_invoice_fee_leaf(1000) |
574 | 579 |
|
575 | 580 | quote = await wallet.melt_quote(invoice_payment_request) |
576 | 581 | assert quote.amount == 1000 |
@@ -599,15 +604,23 @@ async def test_melt_external_routing_fee_rounding(ledger: Ledger, wallet: Wallet |
599 | 604 | resp_quote = PostMeltQuoteResponse(**response.json()) |
600 | 605 | assert resp_quote.state == MeltQuoteState.paid.value |
601 | 606 |
|
602 | | - # the routing fee for 1000 sat is 1001 msat (1000 msat base fee + 1 ppm) |
603 | | - # which the mint must round up to 2 sat when it accounts the fee |
604 | 607 | melt_quote = await ledger.crud.get_melt_quote(quote_id=quote.quote, db=ledger.db) |
605 | 608 | assert melt_quote, "No melt quote in db" |
606 | | - assert melt_quote.fee_paid == 2, "Fee not rounded up to the next sat" |
| 609 | + |
| 610 | + # Verify rounding against LND's settled fee, independently of path selection. |
| 611 | + payment = await ledger.backends[Method.bolt11][Unit.sat].get_payment_status( |
| 612 | + melt_quote.checking_id |
| 613 | + ) |
| 614 | + assert payment.settled |
| 615 | + assert payment.fee is not None and payment.fee.unit == Unit.msat |
| 616 | + whole_sats, remainder_msat = divmod(payment.fee.amount, 1000) |
| 617 | + assert remainder_msat > 0, "Route must charge a fractional sat to test rounding" |
| 618 | + rounded_fee = whole_sats + 1 |
| 619 | + assert melt_quote.fee_paid == rounded_fee, "Fee not rounded up to the next sat" |
607 | 620 |
|
608 | 621 | # we get back the fee reserve minus the rounded up fee |
609 | 622 | change_sat = sum([c.amount for c in resp_quote.change or []]) |
610 | | - assert change_sat == 18, "Wrong change returned" |
| 623 | + assert change_sat == quote.fee_reserve - rounded_fee, "Wrong change returned" |
611 | 624 |
|
612 | 625 |
|
613 | 626 | @pytest.mark.asyncio |
|
0 commit comments