Skip to content

Commit 6c38f5d

Browse files
committed
test: stabilize LND regtests for expanded topology
1 parent 6033482 commit 6c38f5d

3 files changed

Lines changed: 41 additions & 10 deletions

File tree

.github/workflows/regtest-mint.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
regtest-mint:
2727
runs-on: ${{ inputs.os-version }}
2828
# Spark's cold source build can take 90 minutes before the suite starts.
29-
timeout-minutes: ${{ inputs.backend-wallet-class == 'SparkL2Wallet' && 150 || 30 }}
29+
timeout-minutes: ${{ inputs.backend-wallet-class == 'SparkL2Wallet' && 150 || 45 }}
3030
env:
3131
CASHU_REGTEST_DIR: ${{ github.workspace }}/regtest
3232
steps:
@@ -55,7 +55,7 @@ jobs:
5555
run: make test-spark-backend-regtest
5656

5757
- name: Run Tests
58-
timeout-minutes: ${{ inputs.backend-wallet-class == 'SparkL2Wallet' && 45 || 10 }}
58+
timeout-minutes: ${{ inputs.backend-wallet-class == 'SparkL2Wallet' && 45 || 20 }}
5959
env:
6060
WALLET_NAME: test_wallet
6161
MINT_HOST: localhost

tests/helpers.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,24 @@ def get_real_invoice_routed(sats: int) -> str:
264264
return run_cmd_json(cmd)["payment_request"]
265265

266266

267+
def get_real_invoice_fee_leaf(sats: int) -> str:
268+
"""Invoice from isolated lnd-4, reachable only through the fee hub."""
269+
cmd = [
270+
"docker",
271+
"exec",
272+
"cashu-lnd-4-1",
273+
"lncli",
274+
"--network=regtest",
275+
"--rpcserver=lnd-4:10009",
276+
]
277+
destination = run_cmd_json([*cmd, "getinfo"])["identity_pubkey"]
278+
_wait_for_route(
279+
[*docker_lightning_mint_cli, "queryroutes", "--dest", destination, "--amt", str(sats)],
280+
"routes",
281+
)
282+
return run_cmd_json([*cmd, "addinvoice", str(sats)])["payment_request"]
283+
284+
267285
async def pay_if_regtest(bolt11: str) -> None:
268286
if is_spark_backend and os.getenv("CASHU_SPARK_REGTEST", "").lower() == "true":
269287
from tests.spark_regtest import pay_regtest_invoice

tests/mint/test_mint_api.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import pytest
44
import pytest_asyncio
55

6-
from cashu.core.base import MeltQuoteState, MintQuoteState
6+
from cashu.core.base import MeltQuoteState, Method, MintQuoteState, Unit
77
from cashu.core.models import (
88
GetInfoResponse,
99
MintMethodSetting,
@@ -21,6 +21,7 @@
2121
from cashu.wallet.wallet import Wallet
2222
from tests.helpers import (
2323
get_real_invoice,
24+
get_real_invoice_fee_leaf,
2425
get_real_invoice_routed,
2526
is_cln_backend,
2627
is_fake,
@@ -89,7 +90,11 @@ async def test_api_keys(ledger: Ledger):
8990
for keyset in ledger.keysets.values()
9091
]
9192
}
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
9398

9499

95100
@pytest.mark.asyncio
@@ -569,8 +574,8 @@ async def test_melt_external_routing_fee_rounding(ledger: Ledger, wallet: Wallet
569574
await wallet.mint(1024, quote_id=mint_quote.quote)
570575
assert wallet.balance == 1024
571576

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)
574579

575580
quote = await wallet.melt_quote(invoice_payment_request)
576581
assert quote.amount == 1000
@@ -599,15 +604,23 @@ async def test_melt_external_routing_fee_rounding(ledger: Ledger, wallet: Wallet
599604
resp_quote = PostMeltQuoteResponse(**response.json())
600605
assert resp_quote.state == MeltQuoteState.paid.value
601606

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
604607
melt_quote = await ledger.crud.get_melt_quote(quote_id=quote.quote, db=ledger.db)
605608
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"
607620

608621
# we get back the fee reserve minus the rounded up fee
609622
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"
611624

612625

613626
@pytest.mark.asyncio

0 commit comments

Comments
 (0)