Handle Tor failures better
MODIFY
.gitignore
.gitignore
@@ -246,3 +246,4 @@ FullBlockSpvData
/dist
/HiddenWallet/HiddenWallet.GUI/Config.json
/HiddenWallet/HiddenWallet.API/Config.json
+TorData

MODIFY
HiddenWallet/HiddenWallet.API/Global.cs
HiddenWallet/HiddenWallet.API/Global.cs
@@ -10,6 +10,5 @@ namespace HiddenWallet.API
public static class Global
{
public static WalletWrapper WalletWrapper;
- public static Process TorProcess = null;
}
}

MODIFY
HiddenWallet/HiddenWallet.API/Models/StatusResponse.cs
HiddenWallet/HiddenWallet.API/Models/StatusResponse.cs
@@ -13,6 +13,7 @@ namespace HiddenWallet.API.Models
public int TrackingHeight { get; set; }
public int ConnectedNodeCount { get; set; }
public int MemPoolTransactionCount { get; set; }
+ public string TorState { get; set; }
public int ChangeBump { get; set; }
}
}

MODIFY
HiddenWallet/HiddenWallet.API/Program.cs
HiddenWallet/HiddenWallet.API/Program.cs
@@ -9,6 +9,7 @@ using System.Threading.Tasks;
using Microsoft.DotNet.PlatformAbstractions;
using System.Runtime.InteropServices;
using NBitcoin;
+using System.Threading;
namespace HiddenWallet.API
{
@@ -33,7 +34,6 @@ namespace HiddenWallet.API
if (!alreadyRunning)
{
- Console.WriteLine("Starting Tor process...");
var torPath = "tor"; // On Linux and OSX tor must be installed and added to path
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
@@ -41,12 +41,33 @@ namespace HiddenWallet.API
}
var torProcessStartInfo = new ProcessStartInfo(torPath)
{
- Arguments = "SOCKSPort 37121 ControlPort 37122 HashedControlPassword 16:0978DBAF70EEB5C46063F3F6FD8CBC7A86DF70D2206916C1E2AE29EAF6",
+ Arguments = Tor.TorArguments,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true
};
- Global.TorProcess = Process.Start(torProcessStartInfo);
+
+ try
+ {
+ // if doesn't fail tor is already running with the control port
+ Tor.ControlPortClient.IsCircuitEstabilishedAsync().Wait();
+ Debug.WriteLine($"Tor is already running, using the existing instance.");
+ }
+ catch
+ {
+ Debug.WriteLine($"Starting Tor with arguments: {Tor.TorArguments}");
+ try
+ {
+ Tor.TorProcess = Process.Start(torProcessStartInfo);
+ }
+ catch
+ {
+ // ignore, just run the torjob
+ }
+ }
+#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
+ Tor.TorStateJobAsync();
+#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Global.WalletWrapper = new WalletWrapper();

MODIFY
HiddenWallet/HiddenWallet.API/Wrappers/WalletWrapper.cs
HiddenWallet/HiddenWallet.API/Wrappers/WalletWrapper.cs
@@ -52,8 +52,6 @@ namespace HiddenWallet.API.Wrappers
private HistoryResponse _historyResponseBob = new HistoryResponse();
public HistoryResponse GetHistoryResponse(SafeAccount account) => account == AliceAccount ? _historyResponseAlice : _historyResponseBob;
- public readonly SocksPortHandler SocksPortHandler = new SocksPortHandler("127.0.0.1", socksPort: 37121, ignoreSslCertification: true);
- public readonly DotNetTor.ControlPort.Client ControlPortClient = new DotNetTor.ControlPort.Client("127.0.0.1", controlPort: 37122, password: "ILoveBitcoin21");
#endregion
public WalletWrapper()
@@ -89,7 +87,7 @@ namespace HiddenWallet.API.Wrappers
// it's not running yet, let's run it
_password = password;
- _walletJob = new WalletJob(SocksPortHandler, ControlPortClient, safe, trackDefaultSafe: false, accountsToTrack: new SafeAccount[] { AliceAccount, BobAccount });
+ _walletJob = new WalletJob(Tor.SocksPortHandler, Tor.ControlPortClient, safe, trackDefaultSafe: false, accountsToTrack: new SafeAccount[] { AliceAccount, BobAccount });
_walletJob.StateChanged += _walletJob_StateChanged;
_walletJob.Tracker.TrackedTransactions.CollectionChanged += TrackedTransactions_CollectionChanged;
@@ -216,15 +214,12 @@ namespace HiddenWallet.API.Wrappers
_cts.Cancel();
await Task.WhenAll(_walletJobTask).ConfigureAwait(false);
- if(Global.TorProcess != null && !Global.TorProcess.HasExited)
- {
- Console.WriteLine("Terminating Tor process");
- Global.TorProcess.Kill();
- }
+ Tor.Kill();
}
public StatusResponse GetStatusResponse()
{
+ var ts = Tor.State.ToString();
if (_walletJob != null)
{
var hh = 0;
@@ -251,9 +246,9 @@ namespace HiddenWallet.API.Wrappers
var cb = _changeBump;
- return new StatusResponse { HeaderHeight = hh, TrackingHeight = th, ConnectedNodeCount = nc, MemPoolTransactionCount = mtxc, WalletState = ws, ChangeBump = cb };
+ return new StatusResponse { HeaderHeight = hh, TrackingHeight = th, ConnectedNodeCount = nc, MemPoolTransactionCount = mtxc, WalletState = ws, TorState = ts, ChangeBump = cb };
}
- else return new StatusResponse { HeaderHeight = 0, TrackingHeight = 0, ConnectedNodeCount = 0, MemPoolTransactionCount = 0, WalletState = WalletState.NotStarted.ToString(), ChangeBump = 0 };
+ else return new StatusResponse { HeaderHeight = 0, TrackingHeight = 0, ConnectedNodeCount = 0, MemPoolTransactionCount = 0, WalletState = WalletState.NotStarted.ToString(), TorState = ts, ChangeBump = 0 };
}
public BaseResponse BuildTransaction(string password, SafeAccount safeAccount, BitcoinAddress address, Money amount, FeeType feeType)

MODIFY
HiddenWallet/HiddenWallet.GUI/app/js/status.js
HiddenWallet/HiddenWallet.GUI/app/js/status.js
@@ -13,6 +13,7 @@ var headerHeight;
var trackingHeight;
var connectedNodeCount;
var memPoolTransactionCount;
+var torState;
function periodicUpdate() {
setInterval(function statusUpdate() {
var response = httpGetWallet("status");
@@ -22,6 +23,7 @@ function periodicUpdate() {
if (trackingHeight === response.TrackingHeight) {
if (connectedNodeCount === response.ConnectedNodeCount) {
if (memPoolTransactionCount === response.MemPoolTransactionCount) {
+ if (torState === response.TorState) {
if (changeBump === response.ChangeBump) {
return;
}
@@ -30,12 +32,14 @@ function periodicUpdate() {
}
}
}
+ }
walletState = response.WalletState;
headerHeight = response.HeaderHeight;
trackingHeight = response.TrackingHeight;
connectedNodeCount = response.ConnectedNodeCount;
memPoolTransactionCount = response.MemPoolTransactionCount;
+ torState = response.TorState;
var connectionText = "Connecting..."
if (connectedNodeCount !== 0) {
@@ -50,7 +54,7 @@ function periodicUpdate() {
var progressType = "";
if (walletState.toUpperCase() === "NotStarted".toUpperCase()) {
progressType = "info";
- text = "NotConnected";
+ text = "Tor circuit estabilished, Wallet is offline";
}
if (walletState.toUpperCase() === "SyncingHeaders".toUpperCase()) {
progressType = "info progress-bar-striped active";
@@ -73,7 +77,16 @@ function periodicUpdate() {
text = "Connecting. . .";
}
+ if (torState.toUpperCase() === "CircuitEstabilished".toUpperCase()) {
statusShow(100, text, progressType);
+ }
+ if (torState.toUpperCase() === "EstabilishingCircuit".toUpperCase()) {
+ statusShow(100, "Estabilishing Tor circuit...", progressType);
+ }
+ if (torState.toUpperCase() === "NotStarted".toUpperCase()) {
+ statusShow(100, "Tor is not running", "danger")
+ }
+
if (response.ChangeBump !== changeBump) {
updateWalletContent();

MODIFY
HiddenWallet/HiddenWallet.GUI/package.json
HiddenWallet/HiddenWallet.GUI/package.json
{
"name": "hiddenwallet",
- "version": "0.4.2",
+ "version": "0.4.3",
"description": "HiddenWallet.GUI",
"main": "main.js",
"author": {

MODIFY
HiddenWallet/HiddenWallet.Packager/HiddenWallet.Packager.csproj
HiddenWallet/HiddenWallet.Packager/HiddenWallet.Packager.csproj
</PropertyGroup>
<ItemGroup>
+ <PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
<PackageReference Include="System.Xml.XmlDocument" Version="4.3.0" />
</ItemGroup>

Handle Tor failures better