Skip to content

Commit

Permalink
Don't register Coinjoin Coordinator when it's not set up (WalletWasab…
Browse files Browse the repository at this point in the history
  • Loading branch information
SuperJMN authored Sep 19, 2024
1 parent f53846e commit 705f516
Show file tree
Hide file tree
Showing 16 changed files with 233 additions and 108 deletions.
15 changes: 11 additions & 4 deletions WalletWasabi.Daemon/Global.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ public Global(string dataDir, string configFilePath, Config config)
private AllTransactionStore AllTransactionStore { get; }
private IndexStore IndexStore { get; }

private bool HasCoordinatorConfigured => Config.GetCoordinatorUri() is { } coordinatorUri &&
coordinatorUri.AbsoluteUri != "https://api.wasabiwallet.io/" &&
coordinatorUri.AbsoluteUri != "https://api.wasabiwallet.co/";

private WasabiHttpClientFactory BuildHttpClientFactory(Func<Uri> backendUriGetter) =>
new(
Config.UseTor != TorMode.Disabled ? TorSettings.SocksEndpoint : null,
Expand Down Expand Up @@ -256,11 +260,14 @@ public async Task InitializeNoWalletAsync(bool initializeSleepInhibitor, Termina

await BlockDownloadService.StartAsync(cancel).ConfigureAwait(false);

RegisterCoinJoinComponents();

if (initializeSleepInhibitor)
if (HasCoordinatorConfigured)
{
await CreateSleepInhibitorAsync().ConfigureAwait(false);
RegisterCoinJoinComponents();

if (initializeSleepInhibitor)
{
await CreateSleepInhibitorAsync().ConfigureAwait(false);
}
}

bool useTestApi = Network != Network.Main;
Expand Down
2 changes: 1 addition & 1 deletion WalletWasabi.Fluent/Models/Wallets/CoinListModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public CoinListModel(Wallet wallet, IWalletModel walletModel)
WalletModel = walletModel;
var transactionProcessed = walletModel.Transactions.TransactionProcessed;
var anonScoreTargetChanged = this.WhenAnyValue(x => x.WalletModel.Settings.AnonScoreTarget).Skip(1).ToSignal();
var isCoinjoinRunningChanged = walletModel.Coinjoin.IsRunning.ToSignal();
var isCoinjoinRunningChanged = walletModel.IsCoinjoinRunning.ToSignal();
var isSelected = this.WhenAnyValue(x => x.WalletModel.IsSelected).Skip(1).ToSignal();

var signals =
Expand Down
5 changes: 3 additions & 2 deletions WalletWasabi.Fluent/Models/Wallets/HardwareWalletModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using WalletWasabi.Wallets;
using WalletWasabi.Extensions;
using WalletWasabi.Logging;
using WalletWasabi.WabiSabi.Client;

namespace WalletWasabi.Fluent.Models.Wallets;

Expand All @@ -22,13 +23,13 @@ public async Task<bool> AuthorizeTransactionAsync(TransactionAuthorizationInfo t
try
{
var client = new HwiClient(Wallet.Network);

TimeSpan baseTimeout = TimeSpan.FromMinutes(3);

// Define the additional timeout increment as a TimeSpan for every 10 inputs.
TimeSpan additionalTimeoutPer10Inputs = TimeSpan.FromMinutes(1);
int inputCount = transactionAuthorizationInfo.Transaction.WalletInputs.Count;

TimeSpan totalTimeout = baseTimeout + TimeSpan.FromMinutes((inputCount / 10) * additionalTimeoutPer10Inputs.TotalMinutes);
using var cts = new CancellationTokenSource(totalTimeout);

Expand Down
23 changes: 13 additions & 10 deletions WalletWasabi.Fluent/Models/Wallets/WalletCoinjoinModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,24 @@ public partial class WalletCoinjoinModel : ReactiveObject
{
private readonly Wallet _wallet;
private readonly IWalletSettingsModel _settings;
private CoinJoinManager _coinJoinManager;
private CoinJoinManager? _coinJoinManager;
[AutoNotify] private bool _isCoinjoining;

public WalletCoinjoinModel(Wallet wallet, IWalletSettingsModel settings)
public WalletCoinjoinModel(Wallet wallet, CoinJoinManager? coinjoinManager, IWalletSettingsModel settings)
{
_wallet = wallet;
_settings = settings;
_coinJoinManager = Services.HostedServices.Get<CoinJoinManager>();

StatusUpdated =
Observable.FromEventPattern<StatusChangedEventArgs>(_coinJoinManager, nameof(CoinJoinManager.StatusChanged))
.Where(x => x.EventArgs.Wallet == wallet)
.Select(x => x.EventArgs)
.Where(x => x is WalletStartedCoinJoinEventArgs or WalletStoppedCoinJoinEventArgs or StartErrorEventArgs or CoinJoinStatusEventArgs or CompletedEventArgs or StartedEventArgs)
.ObserveOn(RxApp.MainThreadScheduler);
_coinJoinManager = coinjoinManager;

StatusUpdated = _coinJoinManager is { }
? Observable
.FromEventPattern<StatusChangedEventArgs>(_coinJoinManager, nameof(CoinJoinManager.StatusChanged))
.Where(x => x.EventArgs.Wallet == wallet)
.Select(x => x.EventArgs)
.Where(x => x is WalletStartedCoinJoinEventArgs or WalletStoppedCoinJoinEventArgs or StartErrorEventArgs
or CoinJoinStatusEventArgs or CompletedEventArgs or StartedEventArgs)
.ObserveOn(RxApp.MainThreadScheduler)
: Observable.Return(new StatusChangedEventArgs(wallet));

settings.WhenAnyValue(x => x.AutoCoinjoin)
.Skip(1) // The first one is triggered at the creation.
Expand Down
23 changes: 18 additions & 5 deletions WalletWasabi.Fluent/Models/Wallets/WalletModel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reactive.Linq;
Expand All @@ -8,6 +7,7 @@
using WalletWasabi.Fluent.Infrastructure;
using WalletWasabi.Fluent.Models.Transactions;
using WalletWasabi.Fluent.ViewModels.Wallets.Labels;
using WalletWasabi.WabiSabi.Client;
using WalletWasabi.Wallets;

namespace WalletWasabi.Fluent.Models.Wallets;
Expand All @@ -18,14 +18,14 @@ public partial interface IWalletModel : INotifyPropertyChanged;
[AutoInterface]
public partial class WalletModel : ReactiveObject
{
private readonly Lazy<IWalletCoinjoinModel> _coinjoin;
private readonly Lazy<IWalletCoinjoinModel?> _coinjoin;
private readonly Lazy<IWalletCoinsModel> _coins;

[AutoNotify] private bool _isLoggedIn;
[AutoNotify] private bool _isLoaded;
[AutoNotify] private bool _isSelected;

public WalletModel(Wallet wallet, IAmountProvider amountProvider)
public WalletModel(Wallet wallet, IAmountProvider amountProvider)
{
Wallet = wallet;
AmountProvider = amountProvider;
Expand All @@ -34,7 +34,14 @@ public WalletModel(Wallet wallet, IAmountProvider amountProvider)
Loader = new WalletLoadWorkflow(Wallet);
Settings = new WalletSettingsModel(Wallet.KeyManager);

_coinjoin = new(() => new WalletCoinjoinModel(Wallet, Settings));
_coinjoin = new(() =>
{
var coinJoinManager = Services.HostedServices.GetOrDefault<CoinJoinManager>();
return coinJoinManager is not null
? new WalletCoinjoinModel(Wallet, coinJoinManager, Settings)
: null;
});

_coins = new(() => new WalletCoinsModel(wallet, this));

Transactions = new WalletTransactionsModel(this, wallet);
Expand Down Expand Up @@ -76,6 +83,12 @@ public WalletModel(Wallet wallet, IAmountProvider amountProvider)
.BindTo(this, x => x.IsLoaded);
}

public IObservable<bool> IsCoinjoinRunning => _coinjoin.Value?.IsRunning ?? Observable.Return(false);

public IObservable<bool> IsCoinjoinStarted => _coinjoin.Value?.IsStarted ?? Observable.Return(false);

public bool IsCoinJoinEnabled => _coinjoin.Value is not null;

public IAddressesModel Addresses { get; }

internal Wallet Wallet { get; }
Expand Down Expand Up @@ -104,7 +117,7 @@ public WalletModel(Wallet wallet, IAmountProvider amountProvider)

public IWalletPrivacyModel Privacy { get; }

public IWalletCoinjoinModel Coinjoin => _coinjoin.Value;
public IWalletCoinjoinModel? Coinjoin => _coinjoin.Value;

public IObservable<WalletState> State { get; }

Expand Down
1 change: 1 addition & 0 deletions WalletWasabi.Fluent/Models/Wallets/WalletRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using WalletWasabi.Helpers;
using WalletWasabi.Hwi.Models;
using WalletWasabi.Models;
using WalletWasabi.WabiSabi.Client;
using WalletWasabi.Wallets;

namespace WalletWasabi.Fluent.Models.Wallets;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Windows.Input;
using ReactiveUI;
using WalletWasabi.Fluent.ViewModels.Wallets;

namespace WalletWasabi.Fluent.ViewModels.HelpAndSupport;

[NavigationMetaData(
Title = "Find a Coordinator",
Caption = "Open Wasabi's documentation website",
Order = 3,
Category = "Help & Support",
Keywords =
[
"Find", "Coordinator", "Coinjoin", "Docs", "Documentation", "Guide"
],
IconName = "book_question_mark_regular")]
public partial class FindCoordinatorLinkViewModel : TriggerCommandViewModel
{
private FindCoordinatorLinkViewModel()
{
TargetCommand = ReactiveCommand.CreateFromTask(async () => await UiContext.FileSystem.OpenBrowserAsync(WalletViewModel.FindCoordinatorLink));
}

public override ICommand TargetCommand { get; }
}
2 changes: 1 addition & 1 deletion WalletWasabi.Fluent/ViewModels/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ public void Initialize()
{
UiContext.WalletRepository.Wallets
.Connect()
.FilterOnObservable(x => x.Coinjoin.IsRunning)
.FilterOnObservable(x => x.IsCoinjoinRunning)
.ToCollection()
.Select(x => x.Count != 0)
.BindTo(this, x => x.IsCoinJoinActive);
Expand Down
1 change: 1 addition & 0 deletions WalletWasabi.Fluent/ViewModels/MainViewModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public static void RegisterAllViewModels(this MainViewModel mainViewModel, UiCon
BugReportLinkViewModel.RegisterLazy(() => new BugReportLinkViewModel(uiContext));
DocsLinkViewModel.RegisterLazy(() => new DocsLinkViewModel(uiContext));
OpenDataFolderViewModel.RegisterLazy(() => new OpenDataFolderViewModel(uiContext));
FindCoordinatorLinkViewModel.RegisterLazy(() => new FindCoordinatorLinkViewModel(uiContext));
OpenWalletsFolderViewModel.RegisterLazy(() => new OpenWalletsFolderViewModel(uiContext));
OpenLogsViewModel.RegisterLazy(() => new OpenLogsViewModel(uiContext));
OpenTorLogsViewModel.RegisterLazy(() => new OpenTorLogsViewModel(uiContext));
Expand Down
22 changes: 15 additions & 7 deletions WalletWasabi.Fluent/ViewModels/Wallets/CoinJoinStateViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using WalletWasabi.Fluent.State;
using WalletWasabi.Fluent.ViewModels.Wallets.Settings;
using WalletWasabi.WabiSabi.Backend.Rounds;
using WalletWasabi.WabiSabi.Client;
using WalletWasabi.WabiSabi.Client.CoinJoinProgressEvents;
using WalletWasabi.WabiSabi.Client.StatusChangedEvents;

Expand Down Expand Up @@ -64,16 +65,17 @@ public partial class CoinJoinStateViewModel : ViewModelBase
[AutoNotify] private bool _isInCriticalPhase;
[AutoNotify] private bool _isCountDownDelayHappening;
[AutoNotify] private bool _areAllCoinsPrivate;
[AutoNotify] private bool _isCoinjoinSupported;

private DateTimeOffset _countDownStartTime;
private DateTimeOffset _countDownEndTime;

public CoinJoinStateViewModel(UiContext uiContext, IWalletModel wallet, WalletSettingsViewModel settings)
public CoinJoinStateViewModel(UiContext uiContext, IWalletModel wallet, IWalletCoinjoinModel walletCoinjoinModel, WalletSettingsViewModel settings)
{
UiContext = uiContext;
_wallet = wallet;

wallet.Coinjoin.StatusUpdated
walletCoinjoinModel.StatusUpdated
.Do(ProcessStatusChange)
.Subscribe();

Expand Down Expand Up @@ -117,7 +119,7 @@ public CoinJoinStateViewModel(UiContext uiContext, IWalletModel wallet, WalletSe
if (wallet.Settings.IsCoinjoinProfileSelected)
{
var overridePlebStop = _stateMachine.IsInState(State.PlebStopActive);
await wallet.Coinjoin.StartAsync(stopWhenAllMixed: !IsAutoCoinJoinEnabled, overridePlebStop);
await walletCoinjoinModel.StartAsync(stopWhenAllMixed: !IsAutoCoinJoinEnabled, overridePlebStop);
}
});

Expand All @@ -127,7 +129,7 @@ public CoinJoinStateViewModel(UiContext uiContext, IWalletModel wallet, WalletSe
x => x.PauseSpreading,
(isInCriticalPhase, pauseSpreading) => !isInCriticalPhase && !pauseSpreading);

StopPauseCommand = ReactiveCommand.CreateFromTask(wallet.Coinjoin.StopAsync, stopPauseCommandCanExecute);
StopPauseCommand = ReactiveCommand.CreateFromTask(walletCoinjoinModel.StopAsync, stopPauseCommandCanExecute);

AutoCoinJoinObservable = wallet.Settings.WhenAnyValue(x => x.AutoCoinjoin);

Expand All @@ -148,7 +150,8 @@ public CoinJoinStateViewModel(UiContext uiContext, IWalletModel wallet, WalletSe
_autoCoinJoinStartTimer = new DispatcherTimer { Interval = TimeSpan.FromMinutes(Random.Shared.Next(5, 16)) };
_autoCoinJoinStartTimer.Tick += async (_, _) =>
{
await wallet.Coinjoin.StartAsync(stopWhenAllMixed: false, false);
await walletCoinjoinModel.StartAsync(stopWhenAllMixed: false, false);

_autoCoinJoinStartTimer.Stop();
};

Expand All @@ -175,6 +178,10 @@ public CoinJoinStateViewModel(UiContext uiContext, IWalletModel wallet, WalletSe
await mainViewModel.SettingsPage.ActivateCoordinatorTab();
}
});

CoordinatorHelpCommand = ReactiveCommand.CreateFromTask(() => UiContext.FileSystem.OpenBrowserAsync("https://www.google.com"));

IsCoinjoinSupported = _wallet.Coinjoin is not null;
}

private enum State
Expand Down Expand Up @@ -207,8 +214,6 @@ private enum Trigger

public ICommand NavigateToExcludedCoinsCommand { get; }

public ICommand NavigateToCoordinatorSettingsCommand { get; }

public bool IsAutoCoinJoinEnabled => _wallet.Settings.AutoCoinjoin;

public IObservable<bool> AutoCoinJoinObservable { get; }
Expand All @@ -220,6 +225,9 @@ private enum Trigger
public ICommand PlayCommand { get; }

public ICommand StopPauseCommand { get; }
public ICommand NavigateToCoordinatorSettingsCommand { get; }

public ICommand CoordinatorHelpCommand { get; }

private void ConfigureStateMachine()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public WalletCoinJoinSettingsViewModel(UiContext uiContext, IWalletModel walletM
.ObserveOn(RxApp.TaskpoolScheduler)
.Subscribe(x => _wallet.Settings.OutputWalletId = x.Id);

walletModel.Coinjoin.IsStarted
walletModel.IsCoinjoinStarted
.Select(isRunning => !isRunning)
.BindTo(this, x => x.IsOutputWalletSelectionEnabled);

Expand Down
Loading

0 comments on commit 705f516

Please sign in to comment.