mirror of
https://github.com/aljazceru/nutshell.git
synced 2025-12-20 10:34:20 +01:00
* clean up db * db: table lock * db.table_with_schema * fix encrypt.py * postgres nowait * add timeout to lock * melt quote state in db * kinda working * kinda working with postgres * remove dispose * getting there * porperly clean up db for tests * faster tests * configure connection pooling * try github with connection pool * invoice dispatcher does not lock db * fakewallet: pay_if_regtest waits * pay fakewallet invoices * add more * faster * slower * pay_if_regtest async * do not lock the invoice dispatcher * test: do I get disk I/O errors if we disable the invoice_callback_dispatcher? * fix fake so it workss without a callback dispatchert * test on github * readd tasks * refactor * increase time for lock invoice disatcher * try avoiding a race * remove task * github actions: test regtest with postgres * mint per module * no connection pool for testing * enable pool * do not resend paid event * reuse connection * close db connections * sessions * enable debug * dispose engine * disable connection pool for tests * enable connection pool for postgres only * clean up shutdown routine * remove wait for lightning fakewallet lightning invoice * cancel invoice listener tasks on shutdown * fakewallet conftest: decrease outgoing delay * delay payment and set postgres only if needed * disable fail fast for regtest * clean up regtest.yml * change order of tests_db.py * row-specific mint_quote locking * refactor * fix lock statement * refactor swap * refactor * remove psycopg2 * add connection string example to .env.example * remove unnecessary pay * shorter sleep in test_wallet_subscription_swap
128 lines
4.5 KiB
Python
128 lines
4.5 KiB
Python
import asyncio
|
|
from typing import List
|
|
|
|
import pytest
|
|
import pytest_asyncio
|
|
|
|
from cashu.core.base import Method, Proof
|
|
from cashu.mint.ledger import Ledger
|
|
from cashu.wallet.wallet import Wallet
|
|
from tests.conftest import SERVER_ENDPOINT
|
|
from tests.helpers import (
|
|
get_real_invoice,
|
|
is_fake,
|
|
pay_if_regtest,
|
|
)
|
|
|
|
|
|
@pytest_asyncio.fixture(scope="function")
|
|
async def wallet():
|
|
wallet = await Wallet.with_db(
|
|
url=SERVER_ENDPOINT,
|
|
db="test_data/wallet",
|
|
name="wallet",
|
|
)
|
|
await wallet.load_mint()
|
|
yield wallet
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.skipif(is_fake, reason="only regtest")
|
|
async def test_regtest_pay_mpp(wallet: Wallet, ledger: Ledger):
|
|
# make sure that mpp is supported by the bolt11-sat backend
|
|
if not ledger.backends[Method["bolt11"]][wallet.unit].supports_mpp:
|
|
pytest.skip("backend does not support mpp")
|
|
|
|
# make sure wallet knows the backend supports mpp
|
|
assert wallet.mint_info.supports_mpp("bolt11", wallet.unit)
|
|
|
|
# top up wallet twice so we have enough for two payments
|
|
topup_invoice = await wallet.request_mint(128)
|
|
await pay_if_regtest(topup_invoice.bolt11)
|
|
proofs1 = await wallet.mint(128, id=topup_invoice.id)
|
|
assert wallet.balance == 128
|
|
|
|
topup_invoice = await wallet.request_mint(128)
|
|
await pay_if_regtest(topup_invoice.bolt11)
|
|
proofs2 = await wallet.mint(128, id=topup_invoice.id)
|
|
assert wallet.balance == 256
|
|
|
|
# this is the invoice we want to pay in two parts
|
|
invoice_dict = get_real_invoice(64)
|
|
invoice_payment_request = invoice_dict["payment_request"]
|
|
|
|
async def pay_mpp(amount: int, proofs: List[Proof], delay: float = 0.0):
|
|
await asyncio.sleep(delay)
|
|
# wallet pays 32 sat of the invoice
|
|
quote = await wallet.melt_quote(invoice_payment_request, amount=amount)
|
|
assert quote.amount == amount
|
|
await wallet.melt(
|
|
proofs,
|
|
invoice_payment_request,
|
|
fee_reserve_sat=quote.fee_reserve,
|
|
quote_id=quote.quote,
|
|
)
|
|
|
|
# call pay_mpp twice in parallel to pay the full invoice
|
|
# we delay the second payment so that the wallet doesn't derive the same blindedmessages twice due to a race condition
|
|
await asyncio.gather(pay_mpp(32, proofs1), pay_mpp(32, proofs2, delay=0.5))
|
|
|
|
assert wallet.balance <= 256 - 64
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.skipif(is_fake, reason="only regtest")
|
|
async def test_regtest_pay_mpp_incomplete_payment(wallet: Wallet, ledger: Ledger):
|
|
# make sure that mpp is supported by the bolt11-sat backend
|
|
if not ledger.backends[Method["bolt11"]][wallet.unit].supports_mpp:
|
|
pytest.skip("backend does not support mpp")
|
|
|
|
# make sure wallet knows the backend supports mpp
|
|
assert wallet.mint_info.supports_mpp("bolt11", wallet.unit)
|
|
|
|
# top up wallet twice so we have enough for three payments
|
|
topup_invoice = await wallet.request_mint(128)
|
|
await pay_if_regtest(topup_invoice.bolt11)
|
|
proofs1 = await wallet.mint(128, id=topup_invoice.id)
|
|
assert wallet.balance == 128
|
|
|
|
topup_invoice = await wallet.request_mint(128)
|
|
await pay_if_regtest(topup_invoice.bolt11)
|
|
proofs2 = await wallet.mint(128, id=topup_invoice.id)
|
|
assert wallet.balance == 256
|
|
|
|
topup_invoice = await wallet.request_mint(128)
|
|
await pay_if_regtest(topup_invoice.bolt11)
|
|
proofs3 = await wallet.mint(128, id=topup_invoice.id)
|
|
assert wallet.balance == 384
|
|
|
|
# this is the invoice we want to pay in two parts
|
|
invoice_dict = get_real_invoice(64)
|
|
invoice_payment_request = invoice_dict["payment_request"]
|
|
|
|
async def pay_mpp(amount: int, proofs: List[Proof], delay: float = 0.0):
|
|
await asyncio.sleep(delay)
|
|
# wallet pays 32 sat of the invoice
|
|
quote = await wallet.melt_quote(invoice_payment_request, amount=amount)
|
|
assert quote.amount == amount
|
|
await wallet.melt(
|
|
proofs,
|
|
invoice_payment_request,
|
|
fee_reserve_sat=quote.fee_reserve,
|
|
quote_id=quote.quote,
|
|
)
|
|
|
|
# instead: call pay_mpp twice in the background, sleep for a bit, then check if the payment was successful (it should not be)
|
|
asyncio.create_task(pay_mpp(32, proofs1))
|
|
asyncio.create_task(pay_mpp(16, proofs2, delay=0.5))
|
|
await asyncio.sleep(2)
|
|
|
|
# payment is still pending because the full amount has not been paid
|
|
assert wallet.balance == 384
|
|
|
|
# send the remaining 16 sat to complete the payment
|
|
asyncio.create_task(pay_mpp(16, proofs3, delay=0.5))
|
|
await asyncio.sleep(2)
|
|
|
|
assert wallet.balance <= 384 - 64
|