test blink failed payment (#446)

This commit is contained in:
callebtc
2024-02-19 19:42:06 +01:00
committed by GitHub
parent 2189728771
commit 1c2c01ccfa
3 changed files with 77 additions and 18 deletions

View File

@@ -2,7 +2,7 @@
import asyncio
import json
import math
from typing import Dict, Optional
from typing import Dict, Optional, Union
import bolt11
import httpx
@@ -201,23 +201,36 @@ class BlinkWallet(LightningBackend):
return PaymentResponse(ok=False, error_message=str(e))
resp: dict = r.json()
error_message: Union[None, str] = None
fee: Union[None, int] = None
if resp.get("data", {}).get("lnInvoicePaymentSend", {}).get("errors"):
error_message = (
resp["data"]["lnInvoicePaymentSend"]["errors"][0].get("message")
or "Unknown error"
)
paid = self.payment_execution_statuses[
resp.get("data", {}).get("lnInvoicePaymentSend", {}).get("status")
]
fee = (
resp.get("data", {})
.get("lnInvoicePaymentSend", {})
.get("transaction", {})
.get("settlementFee")
)
if paid is None:
error_message = "Invoice already paid."
if resp.get("data", {}).get("lnInvoicePaymentSend", {}).get("transaction", {}):
fee = (
resp.get("data", {})
.get("lnInvoicePaymentSend", {})
.get("transaction", {})
.get("settlementFee")
)
checking_id = quote.request
return PaymentResponse(
ok=paid,
checking_id=checking_id,
fee=Amount(Unit.sat, fee),
fee=Amount(Unit.sat, fee) if fee else None,
preimage=None,
error_message="Invoice already paid." if paid is None else None,
error_message=error_message,
)
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
@@ -373,15 +386,17 @@ class BlinkWallet(LightningBackend):
r.raise_for_status()
resp: dict = r.json()
if resp.get("data", {}).get("lnInvoiceFeeProbe", {}).get("errors"):
raise Exception(
resp["data"]["lnInvoiceFeeProbe"]["errors"][0].get("message")
or "Unknown error"
# if there was an error, we simply ignore the response and decide the fees ourselves
fees_response_msat = 0
logger.debug(
f"Blink probe error: {resp['data']['lnInvoiceFeeProbe']['errors'][0].get('message')}"
)
fees_response_msat = (
int(resp.get("data", {}).get("lnInvoiceFeeProbe", {}).get("amount"))
* 1000
)
else:
fees_response_msat = (
int(resp.get("data", {}).get("lnInvoiceFeeProbe", {}).get("amount"))
* 1000
)
except httpx.ReadTimeout:
pass
except Exception as e:

View File

@@ -692,8 +692,8 @@ class Ledger(LedgerVerification, LedgerSpendingConditions):
melt_quote, melt_quote.fee_reserve * 1000
)
logger.debug(
f"Melt status: {payment.ok}: preimage: {payment.preimage},"
f" fee: {payment.fee.str() if payment.fee else 0}"
f"Melt Ok: {payment.ok}: preimage: {payment.preimage},"
f" fee: {payment.fee.str() if payment.fee is not None else 'None'}"
)
if not payment.ok:
raise LightningError(

View File

@@ -102,6 +102,38 @@ async def test_blink_pay_invoice():
assert payment.checking_id == payment_request
@respx.mock
@pytest.mark.asyncio
async def test_blink_pay_invoice_failure():
mock_response = {
"data": {
"lnInvoicePaymentSend": {
"status": "FAILURE",
"errors": [
{"message": "This is the error", "codee": "ROUTE_FINDING_ERROR"},
],
}
}
}
respx.post(blink.endpoint).mock(return_value=Response(200, json=mock_response))
quote = MeltQuote(
request=payment_request,
quote="asd",
method="bolt11",
checking_id=payment_request,
unit="sat",
amount=100,
fee_reserve=12,
paid=False,
)
payment = await blink.pay_invoice(quote, 1000)
assert not payment.ok
assert payment.fee is None
assert payment.error_message
assert "This is the error" in payment.error_message
assert payment.checking_id == payment_request
@respx.mock
@pytest.mark.asyncio
async def test_blink_get_invoice_status():
@@ -180,3 +212,15 @@ async def test_blink_get_payment_quote():
assert quote.checking_id == payment_request_1
assert quote.amount == Amount(Unit.msat, 1000) # msat
assert quote.fee == Amount(Unit.msat, MINIMUM_FEE_MSAT) # msat
@respx.mock
@pytest.mark.asyncio
async def test_blink_get_payment_quote_backend_error():
# response says error but invoice (1000 sat) * 0.5% is 5 sat so we expect 10 sat
mock_response = {"data": {"lnInvoiceFeeProbe": {"errors": [{"message": "error"}]}}}
respx.post(blink.endpoint).mock(return_value=Response(200, json=mock_response))
quote = await blink.get_payment_quote(payment_request)
assert quote.checking_id == payment_request
assert quote.amount == Amount(Unit.msat, 1000000) # msat
assert quote.fee == Amount(Unit.msat, 5000) # msat