Start implementing syncing
MODIFY
HiddenWallet/HiddenWallet.API/Controllers/WalletController.cs
HiddenWallet/HiddenWallet.API/Controllers/WalletController.cs
@@ -11,8 +11,6 @@ namespace HiddenWallet.API.Controllers
[Route("api/v1/[controller]")]
public class WalletController : Controller
{
- public readonly WalletWrapper WalletWrapper = new WalletWrapper();
-
[HttpGet]
public string Test()
{
@@ -30,7 +28,7 @@ namespace HiddenWallet.API.Controllers
try
{
- WalletCreateResponse response = WalletWrapper.Create(request.Password);
+ WalletCreateResponse response = Global.WalletWrapper.Create(request.Password);
return new ObjectResult(response);
}
@@ -51,7 +49,7 @@ namespace HiddenWallet.API.Controllers
try
{
- WalletWrapper.Recover(request.Password, request.Mnemonic, request.CreationTime);
+ Global.WalletWrapper.Recover(request.Password, request.Mnemonic, request.CreationTime);
return new ObjectResult(new SuccessResponse());
}
@@ -72,7 +70,7 @@ namespace HiddenWallet.API.Controllers
try
{
- WalletWrapper.Load(request.Password);
+ Global.WalletWrapper.Load(request.Password);
return new ObjectResult(new SuccessResponse());
}
@@ -88,7 +86,7 @@ namespace HiddenWallet.API.Controllers
{
try
{
- if (WalletWrapper.WalletExists)
+ if (Global.WalletWrapper.WalletExists)
{
return new ObjectResult(new YesNoResponse { Value = true });
}
@@ -106,7 +104,7 @@ namespace HiddenWallet.API.Controllers
{
try
{
- return new ObjectResult(WalletWrapper.StatusResponse);
+ return new ObjectResult(Global.WalletWrapper.GetStatusResponse());
}
catch (Exception ex)
{
@@ -120,7 +118,7 @@ namespace HiddenWallet.API.Controllers
{
try
{
- WalletWrapper.ShutdownAsync().Wait();
+ Global.WalletWrapper.ShutdownAsync().Wait();
return new ObjectResult(new SuccessResponse());
}

MODIFY
HiddenWallet/HiddenWallet.API/HiddenWallet.API.csproj
HiddenWallet/HiddenWallet.API/HiddenWallet.API.csproj
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="HBitcoin" Version="0.1.6" />
+ <PackageReference Include="HBitcoin" Version="0.1.7" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Routing" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.1.1" />

MODIFY
HiddenWallet/HiddenWallet.API/Program.cs
HiddenWallet/HiddenWallet.API/Program.cs
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using System.Net.Http;
+using HiddenWallet.API.Wrappers;
namespace HiddenWallet.API
{
@@ -13,6 +14,10 @@ namespace HiddenWallet.API
{
public static void Main(string[] args)
{
+ try
+ {
+ Global.WalletWrapper = new WalletWrapper();
+
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
@@ -21,5 +26,10 @@ namespace HiddenWallet.API
host.Run();
}
+ finally
+ {
+ Global.WalletWrapper.ShutdownAsync().Wait(); // won't happen if process is killed
+ }
+ }
}
}

MODIFY
HiddenWallet/HiddenWallet.API/Wrappers/WalletWrapper.cs
HiddenWallet/HiddenWallet.API/Wrappers/WalletWrapper.cs
@@ -19,15 +19,13 @@ namespace HiddenWallet.API.Wrappers
{
private string _password = null;
private WalletJob _walletJob = null;
- private SafeAccount aliceAccount = new SafeAccount(1);
- private SafeAccount bobAccount = new SafeAccount(2);
+ private readonly SafeAccount _aliceAccount = new SafeAccount(1);
+ private readonly SafeAccount _bobAccount = new SafeAccount(2);
- private CancellationTokenSource _cts = new CancellationTokenSource();
+ private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private Task _walletJobTask = Task.CompletedTask;
- private Task _headerHeightReporter = Task.CompletedTask;
public bool WalletExists => File.Exists(Config.WalletFilePath);
- public StatusResponse StatusResponse = new StatusResponse{ HeaderHeight = 0, TrackingHeight = 0, WalletState = WalletState.NotStarted.ToString() };
public WalletWrapper()
{
@@ -52,53 +50,9 @@ namespace HiddenWallet.API.Wrappers
if (safe.Network != Config.Network) throw new NotSupportedException("Network in the config file differs from the netwrok in the wallet file");
_password = password;
- _walletJob = new WalletJob(safe, trackDefaultSafe: false, accountsToTrack: new SafeAccount[] { aliceAccount, bobAccount });
+ _walletJob = new WalletJob(safe, trackDefaultSafe: false, accountsToTrack: new SafeAccount[] { _aliceAccount, _bobAccount });
_walletJobTask = _walletJob.StartAsync(_cts.Token);
-
- _walletJob.BestHeightChanged += _walletJob_BestHeightChanged;
- _walletJob.StateChanged += _walletJob_StateChanged;
-
- _headerHeightReporter = ReportHeaderHeightAsync(_cts.Token);
- }
-
- private async Task ReportHeaderHeightAsync(CancellationToken ctsToken)
- {
- while (true)
- {
- try
- {
- await Task.Delay(1000, ctsToken).ContinueWith(t => { }).ConfigureAwait(false);
- if (ctsToken.IsCancellationRequested) return;
-
- if (WalletJob.TryGetHeaderHeight(out Height height))
- {
- if (height.Type != HeightType.Chain)
- StatusResponse.HeaderHeight = 0;
- else StatusResponse.HeaderHeight = height.Value;
- }
- }
- catch (OperationCanceledException)
- {
-
- }
- catch (Exception ex)
- {
- Debug.WriteLine($"Ignoring {nameof(ReportHeaderHeightAsync)} exception:");
- Debug.WriteLine(ex);
- }
- }
- }
- private void _walletJob_StateChanged(object sender, EventArgs e)
- {
- StatusResponse.WalletState = _walletJob.State.ToString();
- }
- private void _walletJob_BestHeightChanged(object sender, EventArgs e)
- {
- var height = _walletJob.BestHeight;
- if (height.Type != HeightType.Chain)
- StatusResponse.TrackingHeight = 0;
- else StatusResponse.TrackingHeight = height.Value;
}
public void Recover(string password, string mnemonic, string creationTime)
@@ -114,13 +68,35 @@ namespace HiddenWallet.API.Wrappers
public async Task ShutdownAsync()
{
_cts.Cancel();
+ await Task.WhenAll(_walletJobTask).ConfigureAwait(false);
+ Console.WriteLine("Gracefully shut down...");
+ }
+
+ public StatusResponse GetStatusResponse()
+ {
if (_walletJob != null)
{
- _walletJob.BestHeightChanged -= _walletJob_BestHeightChanged;
- _walletJob.StateChanged -= _walletJob_StateChanged;
+ var hh = 0;
+ if (WalletJob.TryGetHeaderHeight(out Height headerHeight))
+ {
+ if (headerHeight.Type == HeightType.Chain)
+ {
+ hh = headerHeight.Value;
+ }
+ }
+
+ var th = 0;
+ var trackingHeight = _walletJob.BestHeight;
+ if (trackingHeight.Type == HeightType.Chain)
+ {
+ th = trackingHeight.Value;
}
- await Task.WhenAll(_walletJobTask, _headerHeightReporter).ConfigureAwait(false);
+ var ws = _walletJob.State.ToString();
+
+ return new StatusResponse { HeaderHeight = hh, TrackingHeight = th, WalletState = ws };
+ }
+ else return new StatusResponse { HeaderHeight = 0, TrackingHeight = 0, WalletState = WalletState.NotStarted.ToString() };
}
}
}

MODIFY
HiddenWallet/HiddenWallet.GUI/app/js/decryption-phase.js
HiddenWallet/HiddenWallet.GUI/app/js/decryption-phase.js
var walletExists;
function decryptionPhaseShow(menuItem = "") {
- statusShow(0, "walletDecryption");
if (menuItem === "") {
walletExists = httpGetWallet("wallet-exists").Value;
if (walletExists === true) {
@@ -129,7 +128,6 @@ function decryptWallet() {
alert(result.Message, "Could not decrypt wallet");
}
else {
- statusShow(100, "Decrypted");
walletPhaseShow("alice");
}
}
\ No newline at end of file

MODIFY
HiddenWallet/HiddenWallet.GUI/app/js/status.js
HiddenWallet/HiddenWallet.GUI/app/js/status.js
-function statusShow(progress, text) {
+function statusShow(progress, text, progressType = "") {
+ if (progressType == "") {
document.getElementById("status").innerHTML = '<div class="progress" style="margin:0"><div class="progress-bar" role="progressbar" style="width:' + progress + '%;"><span><strong>' + text + '</strong></span></div></div>';
}
+ else {
+ document.getElementById("status").innerHTML = '<div class="progress" style="margin:0"><div class="progress-bar progress-bar-' + progressType + '" role="progressbar" style="width:' + progress + '%;"><span><strong>' + text + '</strong></span></div></div>';
+ }
+}
+
+var walletState;
+var headerHeight;
+var trackingHeight;
+function periodicStatusUpdate() {
+ setInterval(function statusUpdate() {
+ var response = httpGetWallet("status");
+ if (walletState === response.WalletState) {
+ if (headerHeight === response.HeaderHeight) {
+ if (trackingHeight === response.TrackingHeight) {
+ return;
+ }
+ }
+ }
+ walletState = response.WalletState;
+ headerHeight = response.HeaderHeight;
+ trackingHeight = response.TrackingHeight;
+
+ var text = "Status: " + walletState + ", Header Height: " + headerHeight + ", Tracking Height: " + trackingHeight;
+ var zeroCheck = 1;
+ if (trackingHeight !== 0) zeroCheck = trackingHeight;
+ var progress = Math.floor((headerHeight / zeroCheck) * 100);
+
+ var progressType = "";
+ if (walletState.toUpperCase() === "NotStarted".toUpperCase()) {
+ progressType = "warning";
+ }
+ if (walletState.toUpperCase() === "SyncingHeaders".toUpperCase()) {
+ progressType = "info";
+ }
+ if (walletState.toUpperCase() === "SyncingBlocks".toUpperCase()) {
+ progressType = "striped";
+ }
+ if (walletState.toUpperCase() === "SyncingMemPool".toUpperCase()) {
+ progressType = ""; // this is the default
+ }
+ if (walletState.toUpperCase() === "Synced".toUpperCase()) {
+ progressType = "success";
+ }
+
+ if (progress > 50) statusShow(progress, text, progressType);
+ else statusShow(50, text, progressType);
+ }, 1000);
+}
\ No newline at end of file

MODIFY
HiddenWallet/HiddenWallet.GUI/index.html
HiddenWallet/HiddenWallet.GUI/index.html
<link rel="stylesheet" href="app/css/justified-nav.css">
</head>
-<body onload="decryptionPhaseShow()">
+<body onload="decryptionPhaseShow(); periodicStatusUpdate();">
<iframe id="decryption-phase-menu-frame" src="app/html/decryption-phase-menu.html" style="display:none"></iframe>
<iframe id="decryption-phase-content-frame" src="app/html/decryption-phase-content.html" style="display:none"></iframe>
<iframe id="wallet-phase-tabs-frame" src="app/html/wallet-phase-tabs.html" style="display:none"></iframe>

MODIFY
HiddenWallet/HiddenWallet.GUI/main.js
HiddenWallet/HiddenWallet.GUI/main.js
@@ -77,8 +77,11 @@ function startApi() {
//Kill process when electron exits
process.on('exit', function () {
writeLog('exit');
+ var request = require('request');
+ request('http://localhost:5000/api/v1/wallet/shutdown', function (error, response, body) {
apiProcess.kill();
});
+});
function writeLog(msg) {
console.log(msg);

MODIFY
HiddenWallet/HiddenWallet.GUI/package.json
HiddenWallet/HiddenWallet.GUI/package.json
"electron-builder": "^17.0.1"
},
"dependencies": {
+ "request": "^2.81.0",
"bootstrap": "^3.3.7",
"electron": "^1.6.7",
"electron-builder": "^17.0.2"

Start implementing syncing