From 0dc60d4795e0540d0e98ea60ceab294b7a0c8d7f Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Tue, 13 Oct 2020 20:37:39 -0300 Subject: [PATCH] increase timeouts for http wallets when stuff may take more than 5 seconds. before we were using requests which had no default timeouts, but httpx has a default timeout of 5 seconds. should have noticed that earlier. when the timeout expires we are left with a pending payment on the db with a temporary checking_id so we can never know if it was completed or not. this is still an issue, because technically a lightning payment may take 2 weeks or more, and we must have a way to dispatch a payment and check for it later. that should be the default (and we already do check for the payment status later, so half of the work is done), but on the other hand backends like lnpay and opennode do not give us a checking_id before the thing is already settled. --- lnbits/wallets/lndrest.py | 1 + lnbits/wallets/lnpay.py | 6 ++++-- lnbits/wallets/lntxbot.py | 14 ++++++++++++-- lnbits/wallets/opennode.py | 14 ++++++++++++-- lnbits/wallets/spark.py | 7 ++++++- 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/lnbits/wallets/lndrest.py b/lnbits/wallets/lndrest.py index 6257dde..4ee42aa 100644 --- a/lnbits/wallets/lndrest.py +++ b/lnbits/wallets/lndrest.py @@ -86,6 +86,7 @@ class LndRestWallet(Wallet): headers=self.auth, verify=self.cert, json={"payment_request": bolt11}, + timeout=180, ) if r.is_error: diff --git a/lnbits/wallets/lnpay.py b/lnbits/wallets/lnpay.py index e1b6d44..e7d02b1 100644 --- a/lnbits/wallets/lnpay.py +++ b/lnbits/wallets/lnpay.py @@ -21,7 +21,7 @@ class LNPayWallet(Wallet): def status(self) -> StatusResponse: url = f"{self.endpoint}/wallet/{self.wallet_key}" try: - r = httpx.get(url, headers=self.auth) + r = httpx.get(url, headers=self.auth, timeout=60) except (httpx.ConnectError, httpx.RequestError): return StatusResponse(f"Unable to connect to '{url}'", 0) @@ -52,6 +52,7 @@ class LNPayWallet(Wallet): f"{self.endpoint}/wallet/{self.wallet_key}/invoice", headers=self.auth, json=data, + timeout=60, ) ok, checking_id, payment_request, error_message = ( r.status_code == 201, @@ -68,9 +69,10 @@ class LNPayWallet(Wallet): def pay_invoice(self, bolt11: str) -> PaymentResponse: r = httpx.post( - url=f"{self.endpoint}/wallet/{self.wallet_key}/withdraw", + f"{self.endpoint}/wallet/{self.wallet_key}/withdraw", headers=self.auth, json={"payment_request": bolt11}, + timeout=180, ) try: diff --git a/lnbits/wallets/lntxbot.py b/lnbits/wallets/lntxbot.py index eec5e02..039be02 100644 --- a/lnbits/wallets/lntxbot.py +++ b/lnbits/wallets/lntxbot.py @@ -17,7 +17,11 @@ class LntxbotWallet(Wallet): self.auth = {"Authorization": f"Basic {key}"} def status(self) -> StatusResponse: - r = httpx.get(f"{self.endpoint}/balance", headers=self.auth) + r = httpx.get( + f"{self.endpoint}/balance", + headers=self.auth, + timeout=40, + ) try: data = r.json() except: @@ -41,6 +45,7 @@ class LntxbotWallet(Wallet): url=f"{self.endpoint}/addinvoice", headers=self.auth, json=data, + timeout=40, ) if r.is_error: @@ -57,7 +62,12 @@ class LntxbotWallet(Wallet): return InvoiceResponse(True, data["payment_hash"], data["pay_req"], None) def pay_invoice(self, bolt11: str) -> PaymentResponse: - r = httpx.post(url=f"{self.endpoint}/payinvoice", headers=self.auth, json={"invoice": bolt11}) + r = httpx.post( + url=f"{self.endpoint}/payinvoice", + headers=self.auth, + json={"invoice": bolt11}, + timeout=40, + ) if r.is_error: try: diff --git a/lnbits/wallets/opennode.py b/lnbits/wallets/opennode.py index 4510e0d..131bcf3 100644 --- a/lnbits/wallets/opennode.py +++ b/lnbits/wallets/opennode.py @@ -22,7 +22,11 @@ class OpenNodeWallet(Wallet): def status(self) -> StatusResponse: try: - r = httpx.get(f"{self.endpoint}/v1/account/balance", headers=self.auth) + r = httpx.get( + f"{self.endpoint}/v1/account/balance", + headers=self.auth, + timeout=40, + ) except (httpx.ConnectError, httpx.RequestError): return StatusResponse(f"Unable to connect to '{self.endpoint}'", 0) @@ -46,6 +50,7 @@ class OpenNodeWallet(Wallet): "description": memo or "", "callback_url": url_for("webhook_listener", _external=True), }, + timeout=40, ) if r.is_error: @@ -58,7 +63,12 @@ class OpenNodeWallet(Wallet): return InvoiceResponse(True, checking_id, payment_request, None) def pay_invoice(self, bolt11: str) -> PaymentResponse: - r = httpx.post(f"{self.endpoint}/v2/withdrawals", headers=self.auth, json={"type": "ln", "address": bolt11}) + r = httpx.post( + f"{self.endpoint}/v2/withdrawals", + headers=self.auth, + json={"type": "ln", "address": bolt11}, + timeout=180, + ) if r.is_error: error_message = r.json()["message"] diff --git a/lnbits/wallets/spark.py b/lnbits/wallets/spark.py index d9f3c4f..5ab40dd 100644 --- a/lnbits/wallets/spark.py +++ b/lnbits/wallets/spark.py @@ -32,7 +32,12 @@ class SparkWallet(Wallet): else: params = {} - r = httpx.post(self.url + "/rpc", headers={"X-Access": self.token}, json={"method": key, "params": params}) + r = httpx.post( + self.url + "/rpc", + headers={"X-Access": self.token}, + json={"method": key, "params": params}, + timeout=40, + ) try: data = r.json() except: