Remove ConcurrentBlockDownload
MODIFY
WalletWasabi.Gui/Controls/StatusBar.xaml
WalletWasabi.Gui/Controls/StatusBar.xaml
<TextBlock Text="{Binding ShowNetwork}" />
</StackPanel>
- <Panel IsVisible="{Binding BlocksLeft, Converter={StaticResource ShouldDisplayValueConverter}}">
+ <Panel IsVisible="{Binding DownloadingBlock}">
<StackPanel Orientation="Horizontal" Spacing="4" IsVisible="{Binding !CriticalUpdateAvailable}">
<Grid Height="10" Width="10">
<DrawingPresenter VerticalAlignment="Center" HorizontalAlignment="Center">
</DrawingPresenter.Drawing>
</DrawingPresenter>
</Grid>
- <TextBlock Text="Downloading a block..." Foreground="{Binding BlocksLeft, ConverterParameter=BlocksLeft, Converter={StaticResource StatusColorConverter}}" />
+ <TextBlock Text="Downloading a block..." Foreground="{Binding DownloadingBlock, ConverterParameter=DownloadingBlock, Converter={StaticResource StatusColorConverter}}" />
</StackPanel>
</Panel>

MODIFY
WalletWasabi.Gui/ViewModels/StatusBarViewModel.cs
WalletWasabi.Gui/ViewModels/StatusBarViewModel.cs
@@ -49,9 +49,10 @@ namespace WalletWasabi.Gui.ViewModels
private TorStatus _tor;
private int _peers;
private ObservableAsPropertyHelper<int> _filtersLeft;
- private int _blocksLeft;
private string _btcPrice;
private ObservableAsPropertyHelper<StatusBarStatus> _status;
+ private bool _downloadingBlock;
+
private StatusBarStatusSet ActiveStatuses { get; }
public StatusBarViewModel()
@@ -63,7 +64,6 @@ namespace WalletWasabi.Gui.ViewModels
UseTor = false;
Tor = TorStatus.NotRunning;
Peers = 0;
- BlocksLeft = 0;
BtcPrice = "$0";
ActiveStatuses = new StatusBarStatusSet();
}
@@ -96,12 +96,10 @@ namespace WalletWasabi.Gui.ViewModels
SetPeers(Nodes.Count);
- Observable.FromEventPattern<int>(typeof(WalletService), nameof(WalletService.ConcurrentBlockDownloadNumberChanged))
+ Observable.FromEventPattern<bool>(typeof(WalletService), nameof(WalletService.DownloadingBlockChanged))
.ObserveOn(RxApp.MainThreadScheduler)
- .Subscribe(x =>
- {
- BlocksLeft = x.EventArgs;
- }).DisposeWith(Disposables);
+ .Subscribe(x => DownloadingBlock = x.EventArgs)
+ .DisposeWith(Disposables);
Synchronizer.WhenAnyValue(x => x.TorStatus)
.ObserveOn(RxApp.MainThreadScheduler)
@@ -138,12 +136,12 @@ namespace WalletWasabi.Gui.ViewModels
OnResponseArrivedIsGenSocksServFail(e.EventArgs);
}).DisposeWith(Disposables);
- this.WhenAnyValue(x => x.FiltersLeft, x => x.BlocksLeft)
+ this.WhenAnyValue(x => x.FiltersLeft, x => x.DownloadingBlock)
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(tup =>
{
- (int filtersLeft, int blocksLeft) = tup.ToValueTuple();
- if (filtersLeft == 0 && blocksLeft == 0)
+ (int filtersLeft, bool downloadingBlock) = tup.ToValueTuple();
+ if (filtersLeft == 0 && !downloadingBlock)
{
TryRemoveStatus(StatusBarStatus.Synchronizing);
}
@@ -276,12 +274,6 @@ namespace WalletWasabi.Gui.ViewModels
public int FiltersLeft => _filtersLeft?.Value ?? 0;
- public int BlocksLeft
- {
- get => _blocksLeft;
- set => this.RaiseAndSetIfChanged(ref _blocksLeft, value);
- }
-
public string BtcPrice
{
get => _btcPrice;
@@ -290,6 +282,12 @@ namespace WalletWasabi.Gui.ViewModels
public StatusBarStatus Status => _status?.Value ?? StatusBarStatus.Loading;
+ public bool DownloadingBlock
+ {
+ get => _downloadingBlock;
+ set => this.RaiseAndSetIfChanged(ref _downloadingBlock, value);
+ }
+
private void OnResponseArrivedIsGenSocksServFail(bool isGenSocksServFail)
{
if (isGenSocksServFail)

MODIFY
WalletWasabi/Services/WalletService.cs
WalletWasabi/Services/WalletService.cs
@@ -9,6 +9,7 @@ using Nito.AsyncEx;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
@@ -30,6 +31,26 @@ namespace WalletWasabi.Services
{
public class WalletService : IDisposable
{
+ public static event EventHandler<bool> DownloadingBlockChanged;
+
+ // So we will make sure when blocks are downloading with multiple wallet services, they don't conflict.
+ private static AsyncLock BlockDownloadLock { get; } = new AsyncLock();
+
+ private static bool DownloadingBlockBacking;
+
+ public static bool DownloadingBlock
+ {
+ get => DownloadingBlockBacking;
+ set
+ {
+ if (value != DownloadingBlockBacking)
+ {
+ DownloadingBlockBacking = value;
+ DownloadingBlockChanged?.Invoke(null, value);
+ }
+ }
+ }
+
public BitcoinStore BitcoinStore { get; }
public KeyManager KeyManager { get; }
public WasabiSynchronizer Synchronizer { get; }
@@ -42,19 +63,11 @@ namespace WalletWasabi.Services
public string TransactionsFilePath { get; }
private AsyncLock HandleFiltersLock { get; }
- private AsyncLock BlockDownloadLock { get; }
+
private AsyncLock BlockFolderLock { get; }
private int NodeTimeouts { get; set; }
- // These are static functions, so we will make sure when blocks are downloading with multiple wallet services, they don't conflict.
- private static int ConcurrentBlockDownload = 0;
-
- /// <summary>
- /// int: number of blocks being downloaded in parallel, not the number of blocks left to download!
- /// </summary>
- public static event EventHandler<int> ConcurrentBlockDownloadNumberChanged;
-
public ServiceConfiguration ServiceConfiguration { get; }
public ConcurrentDictionary<uint256, (Height height, DateTimeOffset dateTime)> ProcessedBlocks { get; }
@@ -100,7 +113,6 @@ namespace WalletWasabi.Services
RuntimeParams.SetDataDir(workFolderDir);
BlockFolderLock = new AsyncLock();
- BlockDownloadLock = new AsyncLock();
KeyManager.AssertCleanKeysIndexed();
KeyManager.AssertLockedInternalKeysIndexed(14);
@@ -730,8 +742,11 @@ namespace WalletWasabi.Services
// Download the block
Block block = null;
- using (await BlockDownloadLock.LockAsync())
+ try
{
+ await BlockDownloadLock.LockAsync();
+ DownloadingBlock = true;
+
while (true)
{
cancel.ThrowIfCancellationRequested();
@@ -846,8 +861,6 @@ namespace WalletWasabi.Services
try
{
- ConcurrentBlockDownloadNumberChanged?.Invoke(this, Interlocked.Increment(ref ConcurrentBlockDownload));
-
using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(RuntimeParams.Instance.NetworkNodeTimeout))) // 1/2 ADSL 512 kbit/s 00:00:32
{
block = node.GetBlocks(new uint256[] { hash }, cts.Token)?.Single();
@@ -893,11 +906,6 @@ namespace WalletWasabi.Services
node.DisconnectAsync("Block download failed.");
continue;
}
- finally
- {
- var concurrentBlockDownload = Interlocked.Decrement(ref ConcurrentBlockDownload);
- ConcurrentBlockDownloadNumberChanged?.Invoke(this, concurrentBlockDownload);
- }
break; // If got this far break, then we have the block, it's valid. Break.
}
@@ -906,13 +914,19 @@ namespace WalletWasabi.Services
Logger.LogDebug<WalletService>(ex);
}
}
- }
+
// Save the block
using (await BlockFolderLock.LockAsync())
{
var path = Path.Combine(BlocksFolderPath, hash.ToString());
await File.WriteAllBytesAsync(path, block.ToBytes());
}
+ }
+ finally
+ {
+ DownloadingBlock = false;
+ BlockDownloadLock.ReleaseLock();
+ }
return block;
}

Remove ConcurrentBlockDownload