feat: update CLN_GRPC where gRPC are available

refs #99
This commit is contained in:
fusion44 2023-03-13 21:51:38 +01:00
parent c03cd6c5d1
commit bb0dcd69d2
No known key found for this signature in database

View file

@ -83,6 +83,10 @@ async def _make_local_call(cmd: str):
return stdout, stderr
def _extract_message(details):
return details.split('message: "')[1].replace('" }', ".")
class LnNodeCLNgRPC(LightningNodeBase):
_initialized = False
_channel = None
@ -749,31 +753,46 @@ class LnNodeCLNgRPC(LightningNodeBase):
num_fwd_last_poll = len(res.forwards)
await asyncio.sleep(interval - 0.1)
async def connect_peer(self, node_URI: str) -> bool:
logger.debug(f"CLN_GRPC: connect_peer(node_URI={node_URI})")
async def connect_peer(self, uri: str) -> bool:
logger.debug(f"CLN_GRPC: connect_peer(node_URI={uri})")
try:
id = node_URI.split("@")[0]
stdout, stderr = await _make_local_call(f"connect id={node_URI}")
if stdout:
if id in stdout.decode():
return True
if "Connection timed out" in stdout.decode():
raise HTTPException(
status.HTTP_504_GATEWAY_TIMEOUT,
detail="Connection establishment: Connection timed out.",
)
if "Connection refused" in stdout.decode():
raise HTTPException(
status.HTTP_504_GATEWAY_TIMEOUT,
detail="Connection establishment: Connection refused.",
)
if stderr:
logger.error(f"CLN_GRPC: {stderr.decode()}")
return False
req = ln.ConnectRequest(id=uri)
res = await self._cln_stub.ConnectPeer(req)
return True
except grpc.aio._call.AioRpcError as error:
details = error.details()
logger.warning(details)
if "All addresses failed" in details:
m = details.split('message: "')[1]
raise HTTPException(
status.HTTP_400_BAD_REQUEST,
detail=m,
)
if "no address known for peer" in details:
raise HTTPException(
status.HTTP_400_BAD_REQUEST,
detail="Connection establishment: No address known for peer",
)
if "Connection timed out" in details:
raise HTTPException(
status.HTTP_504_GATEWAY_TIMEOUT,
detail="Connection establishment: Connection timed out.",
)
if "Connection refused" in details:
raise HTTPException(
status.HTTP_504_GATEWAY_TIMEOUT,
detail="Connection establishment: Connection refused.",
)
logger.exception(details)
raise HTTPException(
status.HTTP_500_INTERNAL_SERVER_ERROR, detail=error.details()
)
@ -795,6 +814,7 @@ class LnNodeCLNgRPC(LightningNodeBase):
status.HTTP_500_INTERNAL_SERVER_ERROR, detail=error.details()
)
# @logger.catch(reraise=True, exclude=HTTPException)
async def channel_open(
self, local_funding_amount: int, node_URI: str, target_confs: int
) -> str:
@ -802,60 +822,73 @@ class LnNodeCLNgRPC(LightningNodeBase):
f"CLN_GRPC: channel_open(local_funding_amount={local_funding_amount}, node_URI={node_URI}, target_confs={target_confs})"
)
fee_rate = None
await self.connect_peer(node_URI)
fee_rate: lnp.Feerate = None
if target_confs == 1:
fee_rate = "urgent"
fee_rate = lnp.Feerate(urgent=True)
elif target_confs >= 2 and target_confs <= 9:
fee_rate = "normal"
fee_rate = lnp.Feerate(normal=True)
elif target_confs >= 10:
fee_rate = "slow"
fee_rate = lnp.Feerate(slow=True)
try:
res = await self.connect_peer(node_URI)
if not res:
raise HTTPException(
status.HTTP_408_REQUEST_TIMEOUT,
detail="Unknown error while trying to connect to peer",
)
cmd = f"fundchannel id={node_URI} amount={local_funding_amount} feerate={fee_rate}"
stdout, stderr = await _make_local_call(cmd)
if stdout:
o = stdout.decode()
j = json.loads(o)
if "txid" in o and "channel_id" in o:
return j["txid"]
if "Unknown peer" in o:
raise HTTPException(
status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="We where able to connect to the peer but CLN can't find it when opening a channel.",
)
if "Owning subdaemon openingd died" in o:
# https://github.com/ElementsProject/lightning/issues/2798#issuecomment-511205719
raise HTTPException(
status.HTTP_400_BAD_REQUEST,
detail="Likely the peer didn't like our channel opening proposal and disconnected from us.",
)
if "Could not afford " in o:
raise HTTPException(
status.HTTP_400_BAD_REQUEST, detail=j["message"]
)
if "Number of pending channels exceed maximum" in o:
raise HTTPException(
status.HTTP_400_BAD_REQUEST, detail=j["message"]
)
raise HTTPException(
status.HTTP_500_INTERNAL_SERVER_ERROR, detail=j["message"]
)
if stderr:
logger.error(f"CLN_GRPC: {stderr.decode()}")
return False
except grpc.aio._call.AioRpcError as error:
raise HTTPException(
status.HTTP_500_INTERNAL_SERVER_ERROR, detail=error.details()
h = bytes.fromhex(node_URI.split("@")[0])
req = ln.FundchannelRequest(
id=h,
amount=lnp.AmountOrAll(
amount=lnp.Amount(msat=local_funding_amount),
all=False,
),
feerate=fee_rate,
)
except TypeError as e:
logger.error(
f"CLN_GRPC: channel_open() failed at ln.FundchannelRequest(): {e}"
)
raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
try:
res = await self._cln_stub.FundChannel(req)
res = res.decode("utf-8")
if "txid" in res and "channel_id" in res:
return res["txid"]
except grpc.aio._call.AioRpcError as error:
details = error.details()
logger.debug(details)
if "amount: should be a satoshi amount" in details:
raise HTTPException(
status.HTTP_400_BAD_REQUEST,
detail="The amount is not a valid satoshi amount.",
)
if "Unknown peer" in details:
raise HTTPException(
status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="We where able to connect to the peer but CLN can't find it when opening a channel.",
)
if "Owning subdaemon openingd died" in details:
# https://github.com/ElementsProject/lightning/issues/2798#issuecomment-511205719
raise HTTPException(
status.HTTP_400_BAD_REQUEST,
detail="Likely the peer didn't like our channel opening proposal and disconnected from us.",
)
if (
"Number of pending channels exceed maximum" in details
or "exceeds maximum chan size of 10 BTC" in details
or "Could not afford all using all " in details
):
raise HTTPException(
status.HTTP_400_BAD_REQUEST, detail=_extract_message(details)
)
logger.warning(f"UNHANDLED ERROR: {details}")
raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR, detail=details)
async def channel_list(self) -> List[Channel]:
logger.debug(f"CLN_GRPC: channel_list()")