Remove notifypropertycangebase from periodic runner.
MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/SendTabViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/SendTabViewModel.cs
@@ -510,7 +510,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
private void SetFeesAndTexts()
{
- AllFeeEstimate allFeeEstimate = Global.FeeProviders?.Status;
+ AllFeeEstimate allFeeEstimate = Global.FeeProviders?.AllFeeEstimate;
int feeTarget = -1; // 1 => 10 minutes
if (IsSliderFeeUsed)
@@ -686,7 +686,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
private void SetFeeTargetLimits()
{
- var allFeeEstimate = Global.FeeProviders?.Status;
+ var allFeeEstimate = Global.FeeProviders?.AllFeeEstimate;
if (allFeeEstimate != null)
{
@@ -1017,7 +1017,10 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
{
Disposables = Disposables is null ? new CompositeDisposable() : throw new NotSupportedException($"Cannot open {GetType().Name} before closing it.");
- Global.FeeProviders.WhenAnyValue(x => x.Status).Subscribe(_ =>
+ Observable
+ .FromEventPattern<UpdateStatus>(Global.FeeProviders, nameof(Global.FeeProviders.AllFeeEstimateChanged))
+ .ObserveOn(RxApp.MainThreadScheduler)
+ .Subscribe(_ =>
{
SetFeeTargetLimits();
@@ -1031,7 +1034,8 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
}
SetFeesAndTexts();
- }).DisposeWith(Disposables);
+ })
+ .DisposeWith(Disposables);
_usdExchangeRate = Global.Synchronizer
.WhenAnyValue(x => x.UsdExchangeRate)

MODIFY
WalletWasabi.Gui/Converters/StatusColorConverter.cs
WalletWasabi.Gui/Converters/StatusColorConverter.cs
@@ -14,6 +14,11 @@ namespace WalletWasabi.Gui.Converters
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
+ if (value is null)
+ {
+ return Brushes.Yellow;
+ }
+
switch (parameter?.ToString())
{
case "BitcoinCoreStatus" when !(value as RpcStatus).Synchronized:

MODIFY
WalletWasabi.Gui/ViewModels/StatusBarViewModel.cs
WalletWasabi.Gui/ViewModels/StatusBarViewModel.cs
@@ -37,8 +37,8 @@ namespace WalletWasabi.Gui.ViewModels
private bool UseTor { get; set; }
- private ObservableAsPropertyHelper<RpcStatus> _bitcoinCoreStatus;
- private ObservableAsPropertyHelper<UpdateStatus> _updateStatus;
+ private RpcStatus _bitcoinCoreStatus;
+ private UpdateStatus _updateStatus;
private bool _updateAvailable;
private bool _criticalUpdateAvailable;
@@ -71,6 +71,8 @@ namespace WalletWasabi.Gui.ViewModels
HashChain = synchronizer.BitcoinStore.HashChain;
UseTor = Global.Config.UseTor; // Do not make it dynamic, because if you change this config settings only next time will it activate.
UseBitcoinCore = Global.Config.StartLocalBitcoinCoreOnStartup;
+ BitcoinCoreStatus = Global.RpcMonitor.RpcStatus;
+ UpdateStatus = Global.UpdateChecker.UpdateStatus;
_status = ActiveStatuses.WhenAnyValue(x => x.CurrentStatus)
.ObserveOn(RxApp.MainThreadScheduler)
@@ -113,18 +115,14 @@ namespace WalletWasabi.Gui.ViewModels
.Subscribe(usd => BtcPrice = $"${(long)usd}")
.DisposeWith(Disposables);
- _bitcoinCoreStatus = Global.RpcMonitor
- .WhenAnyValue(x => x.Status)
- .Throttle(TimeSpan.FromMilliseconds(100))
+ Observable.FromEventPattern<RpcStatus>(Global.RpcMonitor, nameof(Global.RpcMonitor.RpcStatusChanged))
.ObserveOn(RxApp.MainThreadScheduler)
- .ToProperty(this, x => x.BitcoinCoreStatus)
+ .Subscribe(e => BitcoinCoreStatus = e.EventArgs)
.DisposeWith(Disposables);
- _updateStatus = Global.UpdateChecker
- .WhenAnyValue(x => x.Status)
- .Throttle(TimeSpan.FromMilliseconds(100))
+ Observable.FromEventPattern<UpdateStatus>(Global.UpdateChecker, nameof(Global.UpdateChecker.UpdateStatusChanged))
.ObserveOn(RxApp.MainThreadScheduler)
- .ToProperty(this, x => x.UpdateStatus)
+ .Subscribe(e => UpdateStatus = e.EventArgs)
.DisposeWith(Disposables);
Observable.FromEventPattern<bool>(Synchronizer, nameof(Synchronizer.ResponseArrivedIsGenSocksServFail))
@@ -233,8 +231,18 @@ namespace WalletWasabi.Gui.ViewModels
}
public int FiltersLeft => _filtersLeft?.Value ?? 0;
- public RpcStatus BitcoinCoreStatus => _bitcoinCoreStatus?.Value ?? RpcStatus.Unresponsive;
- public UpdateStatus UpdateStatus => _updateStatus?.Value ?? new UpdateStatus(true, true);
+
+ public RpcStatus BitcoinCoreStatus
+ {
+ get => _bitcoinCoreStatus;
+ set => this.RaiseAndSetIfChanged(ref _bitcoinCoreStatus, value);
+ }
+
+ public UpdateStatus UpdateStatus
+ {
+ get => _updateStatus;
+ set => this.RaiseAndSetIfChanged(ref _updateStatus, value);
+ }
public bool UpdateAvailable
{

MODIFY
WalletWasabi.Tests/UnitTests/BlockNotifierTests.cs
WalletWasabi.Tests/UnitTests/BlockNotifierTests.cs
@@ -30,7 +30,7 @@ namespace WalletWasabi.Tests.UnitTests
await Assert.ThrowsAsync<OperationCanceledException>(() => blockAwaiter.WaitAsync(TimeSpan.FromSeconds(1)));
await Assert.ThrowsAsync<OperationCanceledException>(() => reorgAwaiter.WaitAsync(TimeSpan.FromSeconds(1)));
- Assert.Equal(Network.RegTest.GenesisHash, notifier.Status);
+ Assert.Equal(Network.RegTest.GenesisHash, notifier.BestBlockHash);
await notifier.StopAsync();
}
@@ -57,7 +57,7 @@ namespace WalletWasabi.Tests.UnitTests
await Assert.ThrowsAsync<OperationCanceledException>(() => blockAwaiter.WaitAsync(TimeSpan.FromSeconds(1)));
await Assert.ThrowsAsync<OperationCanceledException>(() => reorgAwaiter.WaitAsync(TimeSpan.FromSeconds(1)));
- Assert.Equal(chain.Tip.HashBlock, notifier.Status);
+ Assert.Equal(chain.Tip.HashBlock, notifier.BestBlockHash);
await notifier.StopAsync();
}
@@ -93,7 +93,7 @@ namespace WalletWasabi.Tests.UnitTests
// No reorg notifications
await Assert.ThrowsAsync<OperationCanceledException>(() => reorgAwaiter.WaitAsync(TimeSpan.FromSeconds(1)));
- Assert.Equal(chain.Tip.HashBlock, notifier.Status);
+ Assert.Equal(chain.Tip.HashBlock, notifier.BestBlockHash);
notifier.OnBlock -= onBlockInv;
await notifier.StopAsync();
@@ -133,7 +133,7 @@ namespace WalletWasabi.Tests.UnitTests
var reorgedkBlock = await reorgAwaiter.WaitAsync(TimeSpan.FromSeconds(1));
Assert.Equal(forkPoint.HashBlock, reorgedkBlock.HashPrevBlock);
Assert.Equal(blockToBeReorged.HashBlock, reorgedkBlock.GetHash());
- Assert.Equal(chain.Tip.HashBlock, notifier.Status);
+ Assert.Equal(chain.Tip.HashBlock, notifier.BestBlockHash);
await notifier.StopAsync();
}
@@ -187,7 +187,7 @@ namespace WalletWasabi.Tests.UnitTests
var reorgedkBlock = await reorgAwaiter.WaitAsync(TimeSpan.FromSeconds(1));
var expectedReorgedBlocks = firstReorgedChain.ToList().Concat(new[] { secondReorgedChain[2] });
Assert.Subset(reorgedkBlock.Select(x => x.GetHash()).ToHashSet(), expectedReorgedBlocks.Select(x => x.Header.GetHash()).ToHashSet());
- Assert.Equal(chain.Tip.HashBlock, notifier.Status);
+ Assert.Equal(chain.Tip.HashBlock, notifier.BestBlockHash);
await notifier.StopAsync();
}
@@ -213,7 +213,7 @@ namespace WalletWasabi.Tests.UnitTests
await AddBlockAsync(chain, wait: true);
notifier.TriggerRound();
- Assert.Equal(chain.Tip.HashBlock, notifier.Status);
+ Assert.Equal(chain.Tip.HashBlock, notifier.BestBlockHash);
var nofifiedBlocks = (await blockAwaiter.WaitAsync(TimeSpan.FromSeconds(1))).ToArray();

MODIFY
WalletWasabi/Bases/PeriodicRunner.cs
WalletWasabi/Bases/PeriodicRunner.cs
@@ -8,16 +8,8 @@ using WalletWasabi.Logging;
namespace WalletWasabi.Bases
{
- public abstract class PeriodicRunner<T> : NotifyPropertyChangedBase where T : IEquatable<T>
+ public abstract class PeriodicRunner
{
- private T _status;
-
- public T Status
- {
- get => _status;
- protected set => RaiseAndSetIfChanged(ref _status, value);
- }
-
protected CancellationTokenSource StoppingCts { get; set; }
private CancellationTokenSource TriggeringCts { get; set; }
private object TriggerLock { get; }
@@ -27,14 +19,13 @@ namespace WalletWasabi.Bases
public long LastExceptionCount { get; set; }
public DateTimeOffset LastExceptionFirstAppeared { get; set; }
- protected PeriodicRunner(TimeSpan period, T defaultResult)
+ protected PeriodicRunner(TimeSpan period)
{
StoppingCts = new CancellationTokenSource();
TriggeringCts = new CancellationTokenSource();
TriggerLock = new object();
Period = period;
ExecutingTask = Task.CompletedTask;
- Status = defaultResult;
ResetLastException();
}
@@ -53,26 +44,21 @@ namespace WalletWasabi.Bases
}
}
- protected abstract Task<T> ActionAsync(CancellationToken cancel);
+ protected abstract Task ActionAsync(CancellationToken cancel);
public void Start()
{
- ExecutingTask = ForeverMethodAsync(x => false);
+ ExecutingTask = ForeverMethodAsync();
}
- protected async Task ForeverMethodAsync(Func<T, bool> finishIf)
+ protected async Task ForeverMethodAsync()
{
while (!StoppingCts.IsCancellationRequested)
{
try
{
- var status = await ActionAsync(StoppingCts.Token).ConfigureAwait(false);
- Status = status;
+ await ActionAsync(StoppingCts.Token).ConfigureAwait(false);
LogAndResetLastExceptionIfNotNull();
- if (finishIf(status))
- {
- StoppingCts?.Cancel();
- }
}
catch (Exception ex) when (ex is OperationCanceledException || ex is TaskCanceledException || ex is TimeoutException)
{

MODIFY
WalletWasabi/BitcoinCore/Monitoring/P2pReconnector.cs
WalletWasabi/BitcoinCore/Monitoring/P2pReconnector.cs
@@ -9,16 +9,16 @@ using WalletWasabi.Logging;
namespace WalletWasabi.BitcoinCore.Monitoring
{
- public class P2pReconnector : PeriodicRunner<bool>
+ public class P2pReconnector : PeriodicRunner
{
public P2pNode P2pNode { get; set; }
- public P2pReconnector(TimeSpan period, P2pNode p2pNode) : base(period, false)
+ public P2pReconnector(TimeSpan period, P2pNode p2pNode) : base(period)
{
P2pNode = Guard.NotNull(nameof(p2pNode), p2pNode);
}
- protected override async Task<bool> ActionAsync(CancellationToken cancel)
+ protected override async Task ActionAsync(CancellationToken cancel)
{
try
{
@@ -33,14 +33,15 @@ namespace WalletWasabi.BitcoinCore.Monitoring
}
Logger.LogInfo("Successfully reconnected to P2P.");
- return true;
+
+ StoppingCts?.Cancel();
}
public async Task StartAndAwaitReconnectionAsync(CancellationToken cancel)
{
StoppingCts?.Dispose();
StoppingCts = CancellationTokenSource.CreateLinkedTokenSource(cancel);
- ExecutingTask = ForeverMethodAsync(x => x is true);
+ ExecutingTask = ForeverMethodAsync();
await ExecutingTask.ConfigureAwait(false);
await StopAsync().ConfigureAwait(false);
}

MODIFY
WalletWasabi/BitcoinCore/Monitoring/RpcFeeProvider.cs
WalletWasabi/BitcoinCore/Monitoring/RpcFeeProvider.cs
@@ -11,26 +11,44 @@ using WalletWasabi.Helpers;
namespace WalletWasabi.BitcoinCore.Monitoring
{
- public class RpcFeeProvider : PeriodicRunner<AllFeeEstimate>, IFeeProvider
+ public class RpcFeeProvider : PeriodicRunner, IFeeProvider
{
+ private AllFeeEstimate _allFeeEstimate;
+
+ public event EventHandler<AllFeeEstimate> AllFeeEstimateChanged;
+
+ public AllFeeEstimate AllFeeEstimate
+ {
+ get => _allFeeEstimate;
+ private set
+ {
+ if (value != _allFeeEstimate)
+ {
+ _allFeeEstimate = value;
+ AllFeeEstimateChanged?.Invoke(this, value);
+ }
+ }
+ }
+
public RPCClient RpcClient { get; set; }
- public RpcFeeProvider(TimeSpan period, RPCClient rpcClient) : base(period, null)
+ public RpcFeeProvider(TimeSpan period, RPCClient rpcClient) : base(period)
{
RpcClient = Guard.NotNull(nameof(rpcClient), rpcClient);
}
- protected override async Task<AllFeeEstimate> ActionAsync(CancellationToken cancel)
+ protected override async Task ActionAsync(CancellationToken cancel)
{
try
{
- return await RpcClient.EstimateAllFeeAsync(EstimateSmartFeeMode.Conservative, true, true).ConfigureAwait(false);
+ var allFeeEstimate = await RpcClient.EstimateAllFeeAsync(EstimateSmartFeeMode.Conservative, true, true).ConfigureAwait(false);
+ AllFeeEstimate = allFeeEstimate;
}
catch
{
- if (Status != null)
+ if (AllFeeEstimate != null)
{
- Status = new AllFeeEstimate(Status, false);
+ AllFeeEstimate = new AllFeeEstimate(AllFeeEstimate, false);
}
throw;
}

MODIFY
WalletWasabi/BitcoinCore/Monitoring/RpcMonitor.cs
WalletWasabi/BitcoinCore/Monitoring/RpcMonitor.cs
@@ -10,17 +10,27 @@ using WalletWasabi.Logging;
namespace WalletWasabi.BitcoinCore.Monitoring
{
- public class RpcMonitor : PeriodicRunner<RpcStatus>
+ public class RpcMonitor : PeriodicRunner
{
public RPCClient RpcClient { get; set; }
- public RpcMonitor(TimeSpan period) : base(period, RpcStatus.Unresponsive)
+ public RpcStatus RpcStatus { get; private set; }
+
+ public event EventHandler<RpcStatus> RpcStatusChanged;
+
+ public RpcMonitor(TimeSpan period) : base(period)
{
+ RpcStatus = RpcStatus.Unresponsive;
}
- protected override async Task<RpcStatus> ActionAsync(CancellationToken cancel)
+ protected override async Task ActionAsync(CancellationToken cancel)
{
- return await RpcClient.GetRpcStatusAsync(cancel).ConfigureAwait(false);
+ var rpcStatus = await RpcClient.GetRpcStatusAsync(cancel).ConfigureAwait(false);
+ if (rpcStatus != RpcStatus)
+ {
+ RpcStatus = rpcStatus;
+ RpcStatusChanged?.Invoke(this, rpcStatus);
+ }
}
}
}

MODIFY
WalletWasabi/Blockchain/Analysis/FeesEstimation/FeeProviders.cs
WalletWasabi/Blockchain/Analysis/FeesEstimation/FeeProviders.cs
@@ -11,17 +11,13 @@ using WalletWasabi.Services;
namespace WalletWasabi.Blockchain.Analysis.FeesEstimation
{
- public class FeeProviders : NotifyPropertyChangedBase, IFeeProvider, IDisposable
+ public class FeeProviders : IFeeProvider, IDisposable
{
- private IEnumerable<IFeeProvider> Providers { get; }
+ public event EventHandler<AllFeeEstimate> AllFeeEstimateChanged;
- private AllFeeEstimate _status;
+ public AllFeeEstimate AllFeeEstimate { get; private set; }
- public AllFeeEstimate Status
- {
- get => _status;
- private set => RaiseAndSetIfChanged(ref _status, value);
- }
+ private IEnumerable<IFeeProvider> Providers { get; }
private object Lock { get; }
@@ -34,18 +30,14 @@ namespace WalletWasabi.Blockchain.Analysis.FeesEstimation
foreach (var provider in Providers)
{
- provider.PropertyChanged += Provider_PropertyChanged;
+ provider.AllFeeEstimateChanged += Provider_AllFeeEstimateChanged;
}
}
- private void Provider_PropertyChanged(object sender, PropertyChangedEventArgs e)
- {
- IFeeProvider feeProvider;
- if (e.PropertyName == nameof(feeProvider.Status))
+ private void Provider_AllFeeEstimateChanged(object sender, AllFeeEstimate e)
{
SetAllFeeEstimate();
}
- }
private void SetAllFeeEstimate()
{
@@ -55,15 +47,22 @@ namespace WalletWasabi.Blockchain.Analysis.FeesEstimation
for (int i = 0; i < providerArray.Length - 1; i++)
{
IFeeProvider provider = providerArray[i];
- var allFee = provider.Status;
- if (allFee != null && allFee.IsAccurate)
+ var af = provider.AllFeeEstimate;
+ if (af != null && af.IsAccurate && af != AllFeeEstimate)
{
- Status = allFee;
+ AllFeeEstimate = af;
+ AllFeeEstimateChanged?.Invoke(this, af);
return;
}
}
- Status = providerArray[^1].Status;
+ var allFee = providerArray[^1].AllFeeEstimate;
+ if (allFee != AllFeeEstimate)
+ {
+ AllFeeEstimate = allFee;
+ AllFeeEstimateChanged?.Invoke(this, allFee);
+ return;
+ }
}
}
@@ -79,7 +78,7 @@ namespace WalletWasabi.Blockchain.Analysis.FeesEstimation
{
foreach (var provider in Providers)
{
- provider.PropertyChanged -= Provider_PropertyChanged;
+ provider.AllFeeEstimateChanged -= Provider_AllFeeEstimateChanged;
}
}

MODIFY
WalletWasabi/Blockchain/Analysis/FeesEstimation/IFeeProvider.cs
WalletWasabi/Blockchain/Analysis/FeesEstimation/IFeeProvider.cs
@@ -6,8 +6,10 @@ using System.Text;
namespace WalletWasabi.Blockchain.Analysis.FeesEstimation
{
- public interface IFeeProvider : INotifyPropertyChanged
+ public interface IFeeProvider
{
- public AllFeeEstimate Status { get; }
+ public event EventHandler<AllFeeEstimate> AllFeeEstimateChanged;
+
+ public AllFeeEstimate AllFeeEstimate { get; }
}
}

MODIFY
WalletWasabi/Blockchain/Blocks/BlockNotifier.cs
WalletWasabi/Blockchain/Blocks/BlockNotifier.cs
@@ -16,7 +16,7 @@ using WalletWasabi.Services;
namespace WalletWasabi.Blockchain.Blocks
{
- public class BlockNotifier : PeriodicRunner<uint256>
+ public class BlockNotifier : PeriodicRunner
{
public event EventHandler<Block> OnBlock;
@@ -26,8 +26,9 @@ namespace WalletWasabi.Blockchain.Blocks
public Network Network => RpcClient.Network;
private List<BlockHeader> ProcessedBlocks { get; }
public P2pNode P2pNode { get; }
+ public uint256 BestBlockHash { get; private set; }
- public BlockNotifier(TimeSpan period, IRPCClient rpcClient, P2pNode p2pNode = null) : base(period, null)
+ public BlockNotifier(TimeSpan period, IRPCClient rpcClient, P2pNode p2pNode = null) : base(period)
{
RpcClient = Guard.NotNull(nameof(rpcClient), rpcClient);
P2pNode = p2pNode;
@@ -43,14 +44,14 @@ namespace WalletWasabi.Blockchain.Blocks
TriggerRound();
}
- protected override async Task<uint256> ActionAsync(CancellationToken cancel)
+ protected override async Task ActionAsync(CancellationToken cancel)
{
var bestBlockHash = await RpcClient.GetBestBlockHashAsync().ConfigureAwait(false);
// If there's no new block.
- if (bestBlockHash == Status)
+ if (bestBlockHash == BestBlockHash)
{
- return bestBlockHash;
+ return;
}
var arrivedBlock = await RpcClient.GetBlockAsync(bestBlockHash).ConfigureAwait(false);
@@ -83,20 +84,23 @@ namespace WalletWasabi.Blockchain.Blocks
AddHeader(header);
}
- return bestBlockHash;
+ BestBlockHash = bestBlockHash;
+ return;
}
// If block was already processed return.
if (ProcessedBlocks.Any(x => x.GetHash() == arrivedHeader.GetHash()))
{
- return bestBlockHash;
+ BestBlockHash = bestBlockHash;
+ return;
}
// If this block follows the proper order then add.
if (ProcessedBlocks.Last().GetHash() == arrivedHeader.HashPrevBlock)
{
AddBlock(arrivedBlock);
- return bestBlockHash;
+ BestBlockHash = bestBlockHash;
+ return;
}
// Else let's sort out things.
@@ -107,12 +111,14 @@ namespace WalletWasabi.Blockchain.Blocks
// Reorg happened.
ReorgToBlock(foundPrevBlock);
AddBlock(arrivedBlock);
- return bestBlockHash;
+ BestBlockHash = bestBlockHash;
+ return;
}
await HandleMissedBlocksAsync(arrivedBlock);
- return bestBlockHash;
+ BestBlockHash = bestBlockHash;
+ return;
}
private async Task HandleMissedBlocksAsync(Block arrivedBlock)

MODIFY
WalletWasabi/Services/ConfigWatcher.cs
WalletWasabi/Services/ConfigWatcher.cs
@@ -8,19 +8,19 @@ using WalletWasabi.Logging;
namespace WalletWasabi.Services
{
- public class ConfigWatcher : PeriodicRunner<bool>
+ public class ConfigWatcher : PeriodicRunner
{
public IConfig Config { get; }
public Func<Task> ExecuteWhenChangedAsync { get; }
- public ConfigWatcher(TimeSpan period, IConfig config, Func<Task> executeWhenChangedAsync) : base(period, false)
+ public ConfigWatcher(TimeSpan period, IConfig config, Func<Task> executeWhenChangedAsync) : base(period)
{
Config = Guard.NotNull(nameof(config), config);
ExecuteWhenChangedAsync = Guard.NotNull(nameof(executeWhenChangedAsync), executeWhenChangedAsync);
config.AssertFilePathSet();
}
- protected override async Task<bool> ActionAsync(CancellationToken cancel)
+ protected override async Task ActionAsync(CancellationToken cancel)
{
if (await Config.CheckFileChangeAsync().ConfigureAwait(false))
{
@@ -28,10 +28,10 @@ namespace WalletWasabi.Services
await Config.LoadOrCreateDefaultFileAsync().ConfigureAwait(false);
await ExecuteWhenChangedAsync?.Invoke();
- return true;
+ return;
}
- return false;
+ return;
}
}
}

MODIFY
WalletWasabi/Services/UpdateChecker.cs
WalletWasabi/Services/UpdateChecker.cs
using System;
+using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using WalletWasabi.Bases;
@@ -10,18 +11,28 @@ using WalletWasabi.WebClients.Wasabi;
namespace WalletWasabi.Services
{
- public class UpdateChecker : PeriodicRunner<UpdateStatus>
+ public class UpdateChecker : PeriodicRunner
{
public WasabiClient WasabiClient { get; }
- public UpdateChecker(TimeSpan period, WasabiClient client) : base(period, new UpdateStatus(true, true))
+ public UpdateStatus UpdateStatus { get; private set; }
+
+ public event EventHandler<UpdateStatus> UpdateStatusChanged;
+
+ public UpdateChecker(TimeSpan period, WasabiClient client) : base(period)
{
WasabiClient = Guard.NotNull(nameof(client), client);
+ UpdateStatus = new UpdateStatus(true, true);
}
- protected override async Task<UpdateStatus> ActionAsync(CancellationToken cancel)
+ protected override async Task ActionAsync(CancellationToken cancel)
{
- return await WasabiClient.CheckUpdatesAsync(cancel).ConfigureAwait(false);
+ var updateStatus = await WasabiClient.CheckUpdatesAsync(cancel).ConfigureAwait(false);
+ if (updateStatus != UpdateStatus)
+ {
+ UpdateStatus = updateStatus;
+ UpdateStatusChanged?.Invoke(this, updateStatus);
+ }
}
}
}

MODIFY
WalletWasabi/Services/WalletService.cs
WalletWasabi/Services/WalletService.cs
@@ -760,7 +760,7 @@ namespace WalletWasabi.Services
{
if (feeStrategy.Type == FeeStrategyType.Target)
{
- return FeeProvider.Status?.GetFeeRate(feeStrategy.Target) ?? throw new InvalidOperationException("Cannot get fee estimations.");
+ return FeeProvider.AllFeeEstimate?.GetFeeRate(feeStrategy.Target) ?? throw new InvalidOperationException("Cannot get fee estimations.");
}
else if (feeStrategy.Type == FeeStrategyType.Rate)
{

MODIFY
WalletWasabi/Services/WasabiSynchronizer.cs
WalletWasabi/Services/WasabiSynchronizer.cs
@@ -45,12 +45,20 @@ namespace WalletWasabi.Services
private set => RaiseAndSetIfChanged(ref _usdExchangeRate, value);
}
- private AllFeeEstimate _status;
+ public event EventHandler<AllFeeEstimate> AllFeeEstimateChanged;
- public AllFeeEstimate Status
+ private AllFeeEstimate _allFeeEstimate;
+
+ public AllFeeEstimate AllFeeEstimate
+ {
+ get => _allFeeEstimate;
+ private set
+ {
+ if (RaiseAndSetIfChanged(ref _allFeeEstimate, value))
{
- get => _status;
- private set => RaiseAndSetIfChanged(ref _status, value);
+ AllFeeEstimateChanged?.Invoke(this, value);
+ }
+ }
}
private TorStatus _torStatus;
@@ -200,7 +208,7 @@ namespace WalletWasabi.Services
if (response.AllFeeEstimate != null && response.AllFeeEstimate.Estimations.Any())
{
lastFeeQueried = DateTimeOffset.UtcNow;
- Status = response.AllFeeEstimate;
+ AllFeeEstimate = response.AllFeeEstimate;
}
if (response.Filters.Count() == maxFiltersToSyncAtInitialization)

Remove notifypropertycangebase from periodic runner.