From 1e4fa71df8080fb264dc50a23910b4fdb09b2766 Mon Sep 17 00:00:00 2001 From: Parham Saremi Date: Tue, 8 Nov 2022 12:03:20 +0330 Subject: [PATCH] Backend(LN): catch NOnionException TorOperations Catch the NOnionException after Retrys have finished and the problem still exists. We catch the exception and return an error. Fixes https://github.com/nblockchain/geewallet/issues/181 Fixes https://github.com/nblockchain/geewallet/issues/182 --- .../UtxoCoin/Lightning/Network.fs | 37 ++++++++++++++----- src/GWallet.Backend/UtxoCoin/TorOperations.fs | 17 +++++++-- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/GWallet.Backend/UtxoCoin/Lightning/Network.fs b/src/GWallet.Backend/UtxoCoin/Lightning/Network.fs index 7f7ecc29d..a32fd2704 100644 --- a/src/GWallet.Backend/UtxoCoin/Lightning/Network.fs +++ b/src/GWallet.Backend/UtxoCoin/Lightning/Network.fs @@ -10,6 +10,7 @@ open NBitcoin open DotNetLightning.Peer open DotNetLightning.Utils open ResultUtils.Portability +open NOnion open NOnion.Network open NOnion.Directory open NOnion.Services @@ -36,7 +37,7 @@ type PeerDisconnectedError = not self.Abruptly type HandshakeError = - | TcpConnect of seq + | TcpConnect of seq | TcpAccept of seq | DisconnectedOnAct1 of PeerDisconnectedError | InvalidAct1 of PeerError @@ -48,7 +49,7 @@ type HandshakeError = member self.Message = match self with | TcpConnect errs -> - let messages = Seq.map (fun (err: SocketException) -> err.Message) errs + let messages = Seq.map (fun (err: Exception) -> err.Message) errs SPrintF1 "TCP connection failed: %s" (String.concat "; " messages) | TcpAccept errs -> let messages = Seq.map (fun (err: SocketException) -> err.Message) errs @@ -331,7 +332,7 @@ type internal TransportStream = static member private TcpTransportConnect (localEndPointOpt: Option) (remoteEndPoint: IPEndPoint) - : Async>> = async { + : Async>> = async { let client = new TcpClient (remoteEndPoint.AddressFamily) match localEndPointOpt with | Some localEndPoint -> @@ -352,7 +353,13 @@ type internal TransportStream = | ex -> client.Close() let socketExceptions = FindSingleException ex - return Error socketExceptions + let exceptions = + seq { + for socketException in socketExceptions do + yield socketException :> Exception + } + + return Error exceptions } static member private AcceptAny (listener: IncomingConnectionMethod) @@ -419,23 +426,33 @@ type internal TransportStream = static member private TorTransportConnect (nonionEndPoint: NOnionEndPoint) - : Async>> = + : Async>> = async { let! directory = TorOperations.GetTorDirectory() try - let! torClient = TorOperations.TorConnect directory nonionEndPoint.Url - Infrastructure.LogDebug <| SPrintF1 "Connected %s" nonionEndPoint.Url - return Ok torClient + let! maybeTorClient = TorOperations.TorConnect directory nonionEndPoint.Url + match maybeTorClient with + | Ok torClient -> + Infrastructure.LogDebug <| SPrintF1 "Connected %s" nonionEndPoint.Url + return Ok torClient + | Error ex -> + return Error (ex :> Exception |> Seq.singleton) with | ex -> let socketExceptions = FindSingleException ex - return Error socketExceptions + let exceptions = + seq { + for socketException in socketExceptions do + yield socketException :> Exception + } + + return Error exceptions } static member private TransportConnect (localEndPointOpt: Option) (node: NodeIdentifier) - : Async>> = + : Async>> = async { match node with | NodeIdentifier.TcpEndPoint remoteEndPoint -> diff --git a/src/GWallet.Backend/UtxoCoin/TorOperations.fs b/src/GWallet.Backend/UtxoCoin/TorOperations.fs index 91d0dc516..1b13cf0a7 100644 --- a/src/GWallet.Backend/UtxoCoin/TorOperations.fs +++ b/src/GWallet.Backend/UtxoCoin/TorOperations.fs @@ -6,6 +6,7 @@ open System.Net open System.Text.RegularExpressions open System.Diagnostics +open ResultUtils.Portability open NOnion open NOnion.Directory open NOnion.Services @@ -110,13 +111,21 @@ module internal TorOperations = Config.TOR_CONNECTION_RETRY_COUNT } - let internal TorConnect directory url = + let internal TorConnect directory url: + Async> = async { - return! FSharpUtil.Retry - (fun _ -> TorServiceClient.Connect directory url) - Config.TOR_CONNECTION_RETRY_COUNT + try + let! connectedServiceClient = + FSharpUtil.Retry + (fun _ -> TorServiceClient.Connect directory url) + Config.TOR_CONNECTION_RETRY_COUNT + return Ok connectedServiceClient + with + | :? NOnionException as ex -> + return Error ex } + let internal ExtractServerListFromGithub() : List<(string*string)> = let urlToTorServerList = "https://raw.githubusercontent.com/torproject/tor/main/src/app/config/fallback_dirs.inc" use webClient = new WebClient()