From 028cfc866e32e3c43dd71e5f33f367d030fe20a9 Mon Sep 17 00:00:00 2001 From: fusion44 Date: Sun, 20 Mar 2022 10:04:00 +0100 Subject: [PATCH] feat: improve error messages on startup failures --- app/repositories/bitcoin.py | 7 ++++--- app/repositories/lightning.py | 21 ++++++++++++++++++++- app/utils.py | 24 +++++++++++++++++++++--- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/app/repositories/bitcoin.py b/app/repositories/bitcoin.py index 56251d5..fe43218 100644 --- a/app/repositories/bitcoin.py +++ b/app/repositories/bitcoin.py @@ -1,6 +1,7 @@ import asyncio import binascii import json +import logging import zmq import zmq.asyncio @@ -85,8 +86,8 @@ async def handle_block_sub_redis(verbosity: int = 1) -> str: while True: _, body, _ = await zmq_socket.recv_multipart() - hash = binascii.hexlify(body).decode('utf-8') - r = await bitcoin_rpc_async('getblock', [hash, verbosity]) + hash = binascii.hexlify(body).decode("utf-8") + r = await bitcoin_rpc_async("getblock", [hash, verbosity]) await send_sse_message(SSE.BTC_NEW_BLOC, r["result"]) @@ -102,7 +103,7 @@ async def _handle_gather_bitcoin_status(): info = await get_btc_info() info.verification_progress = round(info.verification_progress, 2) except HTTPException as e: - print(e) + logging.error(e.detail) await asyncio.sleep(2) continue diff --git a/app/repositories/lightning.py b/app/repositories/lightning.py index bfc1d9d..662a8da 100644 --- a/app/repositories/lightning.py +++ b/app/repositories/lightning.py @@ -1,5 +1,6 @@ import asyncio from typing import List, Optional +import logging from app.models.lightning import ( FeeRevenue, @@ -173,7 +174,25 @@ async def register_lightning_listener(): loop.create_task(_handle_invoice_listener()) loop.create_task(_handle_forward_event_listener()) except HTTPException as r: - raise + if r.detail == "failed to connect to all addresses": + logging.error( + """ +Unable to connect to LND. Possible reasons: +* Node is not reachable (ports, network down, ...) +* Maccaroon is not correct +* IP is not included in LND tls certificate + Add tlsextraip=192.168.1.xxx to lnd.conf and restart LND. + This will recreate the TLS certificate. The .env must be adpted accordingly. +* TLS certificate is wrong. (settings changed, ...) + +To Debug gRPC problems uncomment the following line in app.utils.LightningConfig._init(): +# os.environ["GRPC_VERBOSITY"] = "DEBUG" +This will show more debug information. +""" + ) + exit(1) + else: + raise except NotImplementedError as r: raise HTTPException(status.HTTP_501_NOT_IMPLEMENTED, detail=r.args[0]) diff --git a/app/utils.py b/app/utils.py index 39be402..9fb1971 100644 --- a/app/utils.py +++ b/app/utils.py @@ -10,6 +10,7 @@ import requests from decouple import config from fastapi.encoders import jsonable_encoder from fastapi_plugins import redis_plugin +from starlette import status import app.repositories.ln_impl.protos.lightning_pb2_grpc as lnrpc import app.repositories.ln_impl.protos.router_pb2_grpc as routerrpc @@ -51,8 +52,8 @@ class LightningConfig: os.environ["GRPC_SSL_CIPHER_SUITES"] = "HIGH+ECDSA" # Uncomment to see full gRPC logs - # os.environ["GRPC_TRACE"] = 'all' - # os.environ["GRPC_VERBOSITY"] = 'DEBUG' + # os.environ["GRPC_TRACE"] = "all" + # os.environ["GRPC_VERBOSITY"] = "DEBUG" self.lnd_macaroon = config("lnd_macaroon") self._lnd_cert = bytes.fromhex(config("lnd_cert")) @@ -122,7 +123,23 @@ async def bitcoin_rpc_async(method: str, params: list = []) -> coroutine: async with aiohttp.ClientSession(auth=auth, headers=headers) as session: async with session.post(bitcoin_config.rpc_url, data=data) as resp: - return await resp.json() + if resp.status == status.HTTP_200_OK: + return await resp.json() + elif resp.status == status.HTTP_401_UNAUTHORIZED: + return { + "error": "Access denied to Bitcoin Core RPC. Check if username and password is correct", + "status": status.HTTP_403_FORBIDDEN, + } + elif resp.status == status.HTTP_403_FORBIDDEN: + return { + "error": "Access denied to Bitcoin Core RPC. If this is a remote node, check if 'network.rpcallowip=0.0.0.0/0' is set.", + "status": status.HTTP_403_FORBIDDEN, + } + else: + return { + "error": f"Unknown answer from Bitcoin Core. Reason: {resp.reason}", + "status": resp.status, + } async def send_sse_message(id: str, json_data: Dict): @@ -156,6 +173,7 @@ async def redis_get(key: str) -> str: # the 'state' value gets changed by the _cache.sh script, it should publish this to this channel # so the API can forward the change to thru the SSE to the WebUI + class SSE: SYSTEM_INFO = "system_info" HARDWARE_INFO = "hardware_info"