Skip to content

Commit

Permalink
Remove default coordinator and help to find one (WalletWasabi#13317)
Browse files Browse the repository at this point in the history
  • Loading branch information
turbolay authored Aug 27, 2024
1 parent a04b138 commit b7c7ca4
Show file tree
Hide file tree
Showing 19 changed files with 158 additions and 41 deletions.
4 changes: 2 additions & 2 deletions WalletWasabi.Daemon/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ public Uri GetBackendUri()
throw new NotSupportedNetworkException(Network);
}

public Uri GetCoordinatorUri()
public Uri? GetCoordinatorUri()
{
var result = Network switch
{
Expand All @@ -260,7 +260,7 @@ public Uri GetCoordinatorUri()
_ => throw new NotSupportedNetworkException(Network)
};

return new Uri(result);
return result is "" ? null : new Uri(result);
}

public IEnumerable<(string ParameterName, string Hint)> GetConfigOptionsMetadata() =>
Expand Down
27 changes: 17 additions & 10 deletions WalletWasabi.Daemon/Global.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,16 @@ public Global(string dataDir, string configFilePath, Config config)

BitcoinStore = new BitcoinStore(IndexStore, AllTransactionStore, mempoolService, smartHeaderChain, blocks);
HttpClientFactory = BuildHttpClientFactory(() => Config.GetBackendUri());
CoordinatorHttpClientFactory = BuildHttpClientFactory(() => Config.GetCoordinatorUri());

if (Config.GetCoordinatorUri() is { } coordinatorUri)
{
CoordinatorHttpClientFactory = BuildHttpClientFactory(() => coordinatorUri);
CoinPrison = CoinPrison.CreateOrLoadFromFile(Path.Combine(DataDir, coordinatorUri.Host));
}
else
{
CoinPrison = CoinPrison.CreateDummyPrison();
}

HostedServices.Register<UpdateManager>(() => new UpdateManager(TimeSpan.FromDays(1), DataDir, Config.DownloadNewVersion, HttpClientFactory.NewHttpClient(Mode.DefaultCircuit, maximumRedirects: 10), HttpClientFactory.SharedWasabiClient), "Update Manager");
UpdateManager = HostedServices.Get<UpdateManager>();
Expand Down Expand Up @@ -146,8 +155,6 @@ public Global(string dataDir, string configFilePath, Config config)
WalletManager = new WalletManager(config.Network, DataDir, new WalletDirectories(Config.Network, DataDir), walletFactory);
TransactionBroadcaster = new TransactionBroadcaster(Network, BitcoinStore, HttpClientFactory, WalletManager);

var prisonForCoordinator = Path.Combine(DataDir, config.GetCoordinatorUri().Host);
CoinPrison = CoinPrison.CreateOrLoadFromFile(prisonForCoordinator);
WalletManager.WalletStateChanged += WalletManager_WalletStateChanged;
}

Expand All @@ -167,7 +174,7 @@ public Global(string dataDir, string configFilePath, Config config)
/// <summary>HTTP client factory for sending HTTP requests.</summary>
public WasabiHttpClientFactory HttpClientFactory { get; }

public WasabiHttpClientFactory CoordinatorHttpClientFactory { get; }
public WasabiHttpClientFactory? CoordinatorHttpClientFactory { get; }

public string ConfigFilePath { get; }
public Config Config { get; }
Expand All @@ -186,7 +193,7 @@ public Global(string dataDir, string configFilePath, Config config)
public Network Network => Config.Network;

public IMemoryCache Cache { get; private set; }
public CoinPrison CoinPrison { get; }
private CoinPrison CoinPrison { get; }
public JsonRpcServer? RpcServer { get; private set; }

public Uri? OnionServiceUri { get; private set; }
Expand Down Expand Up @@ -404,11 +411,8 @@ private void RegisterFeeRateProviders()

private void RegisterCoinJoinComponents()
{
Tor.Http.IHttpClient roundStateUpdaterHttpClient = CoordinatorHttpClientFactory.NewHttpClient(Mode.SingleCircuitPerLifetime, RoundStateUpdaterCircuit);
HostedServices.Register<RoundStateUpdater>(() => new RoundStateUpdater(TimeSpan.FromSeconds(10), new WabiSabiHttpApiClient(roundStateUpdaterHttpClient)), "Round info updater");

var coinJoinConfiguration = new CoinJoinConfiguration(Config.CoordinatorIdentifier, Config.MaxCoinjoinMiningFeeRate, Config.AbsoluteMinInputCount, AllowSoloCoinjoining: false);
HostedServices.Register<CoinJoinManager>(() => new CoinJoinManager(WalletManager, HostedServices.Get<RoundStateUpdater>(), CoordinatorHttpClientFactory, HostedServices.Get<WasabiSynchronizer>(), coinJoinConfiguration, CoinPrison), "CoinJoin Manager");
HostedServices.Register<CoinJoinManager>(() => new CoinJoinManager(WalletManager, CoordinatorHttpClientFactory, HostedServices.Get<WasabiSynchronizer>(), coinJoinConfiguration, CoinPrison), "CoinJoin Manager");
}

private void WalletManager_WalletStateChanged(object? sender, WalletState e)
Expand Down Expand Up @@ -499,7 +503,10 @@ public async Task DisposeAsync()
Logger.LogInfo($"{nameof(HttpClientFactory)} is disposed.");
}

await CoordinatorHttpClientFactory.DisposeAsync().ConfigureAwait(false);
if (CoordinatorHttpClientFactory is not null)
{
await CoordinatorHttpClientFactory.DisposeAsync().ConfigureAwait(false);
}
Logger.LogInfo($"{nameof(CoordinatorHttpClientFactory)} is disposed.");

if (BitcoinCoreNode is { } bitcoinCoreNode)
Expand Down
12 changes: 6 additions & 6 deletions WalletWasabi.Daemon/PersistentConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ public record PersistentConfig
{
public Network Network { get; init; } = Network.Main;

public string MainNetBackendUri { get; init; } = Constants.BackendUri;
public string MainNetBackendUri { get; init; } = Constants.DefaultBackendUri;

public string TestNetBackendUri { get; init; } = Constants.TestnetBackendUri;
public string TestNetBackendUri { get; init; } = Constants.DefaultTestnetBackendUri;

public string RegTestBackendUri { get; init; } = "http://localhost:37127/";
public string RegTestBackendUri { get; init; } = Constants.DefaultRegtestBackendUri;

public string MainNetCoordinatorUri { get; init; } = Constants.BackendUri;
public string MainNetCoordinatorUri { get; init; } = Constants.DefaultCoordinatorUri;

public string TestNetCoordinatorUri { get; init; } = Constants.TestnetBackendUri;
public string TestNetCoordinatorUri { get; init; } = Constants.DefaultTestnetCoordinatorUri;

public string RegTestCoordinatorUri { get; init; } = "http://localhost:37127/";
public string RegTestCoordinatorUri { get; init; } = Constants.DefaultRegtestCoordinatorUri;

/// <remarks>
/// For backward compatibility this was changed to an object.
Expand Down
6 changes: 6 additions & 0 deletions WalletWasabi.Fluent/Styles/HyperlinkMenuItem.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style Selector="MenuItem.hyperLinkMenuItem AccessText">
<Setter Property="TextDecorations" Value="Underline" />
</Style>
</Styles>
1 change: 1 addition & 0 deletions WalletWasabi.Fluent/Styles/Styles.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<StyleInclude Source="avares://WalletWasabi.Fluent/Styles/TextBox.axaml" />
<StyleInclude Source="avares://WalletWasabi.Fluent/Styles/NotificationCard.axaml" />
<StyleInclude Source="avares://WalletWasabi.Fluent/Styles/HyperlinkButton.axaml" />
<StyleInclude Source="avares://WalletWasabi.Fluent/Styles/HyperlinkMenuItem.axaml" />
<StyleInclude Source="avares://WalletWasabi.Fluent/Styles/CurrencyEntryBox.axaml" />
<StyleInclude Source="avares://WalletWasabi.Fluent/Styles/TreeDataGrid.axaml" />
<StyleInclude Source="avares://WalletWasabi.Fluent/Styles/RadioButton.axaml" />
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", "Docs", "Documentation", "Guide"
],
IconName = "book_question_mark_regular")]
public partial class FindCoordinatorViewModel : TriggerCommandViewModel
{
private FindCoordinatorViewModel()
{
TargetCommand = ReactiveCommand.CreateFromTask(async () => await UiContext.FileSystem.OpenBrowserAsync(CoinJoinStateViewModel.FindCoordinatorLink));
}

public override ICommand TargetCommand { get; }
}
1 change: 1 addition & 0 deletions WalletWasabi.Fluent/ViewModels/MainViewModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public static void RegisterAllViewModels(this MainViewModel mainViewModel, UiCon
UserSupportViewModel.RegisterLazy(() => new UserSupportViewModel(uiContext));
BugReportLinkViewModel.RegisterLazy(() => new BugReportLinkViewModel(uiContext));
DocsLinkViewModel.RegisterLazy(() => new DocsLinkViewModel(uiContext));
FindCoordinatorViewModel.RegisterLazy(() => new FindCoordinatorViewModel(uiContext));
OpenDataFolderViewModel.RegisterLazy(() => new OpenDataFolderViewModel(uiContext));
OpenWalletsFolderViewModel.RegisterLazy(() => new OpenWalletsFolderViewModel(uiContext));
OpenLogsViewModel.RegisterLazy(() => new OpenLogsViewModel(uiContext));
Expand Down
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 @@ -45,6 +46,7 @@ public partial class CoinJoinStateViewModel : ViewModelBase
private const string CoinsRejectedMessage = "Some funds are rejected from coinjoining";
private const string OnlyImmatureCoinsAvailableMessage = "Only immature funds are available";
private const string OnlyExcludedCoinsAvailableMessage = "Only excluded funds are available";
private const string NoCoordinatorConfiguredMessage = "Configure a coordinator to start coinjoin";

private readonly IWalletModel _wallet;
private readonly StateMachine<State, Trigger> _stateMachine;
Expand Down Expand Up @@ -165,6 +167,7 @@ public CoinJoinStateViewModel(UiContext uiContext, IWalletModel wallet, WalletSe
},
Observable.Return(!_wallet.IsWatchOnlyWallet));

OpenFindCoordinatorLinkCommand = ReactiveCommand.CreateFromTask(() => UiContext.FileSystem.OpenBrowserAsync(FindCoordinatorLink));
NavigateToSettingsCommand = coinJoinSettingsCommand;
CanNavigateToCoinjoinSettings = coinJoinSettingsCommand.CanExecute;
NavigateToExcludedCoinsCommand = ReactiveCommand.Create(() => UiContext.Navigate().To().ExcludedCoins(_wallet));
Expand Down Expand Up @@ -201,14 +204,18 @@ private enum Trigger
AreAllCoinsPrivateChanged
}

public static string FindCoordinatorLink { get; } = "https://docs.wasabiwallet.io/FAQ/FAQ-UseWasabi.html#how-do-i-find-a-coordinator";

public IObservable<bool> CanNavigateToCoinjoinSettings { get; }

public ICommand OpenFindCoordinatorLinkCommand { get; }
public ICommand NavigateToSettingsCommand { get; }

public ICommand NavigateToExcludedCoinsCommand { get; }

public ICommand NavigateToCoordinatorSettingsCommand { get; }

public bool NoCoordinatorConfigured => !Services.HostedServices.Get<CoinJoinManager>().HasCoordinatorConfigured;
public bool IsAutoCoinJoinEnabled => _wallet.Settings.AutoCoinjoin;

public IObservable<bool> AutoCoinJoinObservable { get; }
Expand Down Expand Up @@ -386,6 +393,7 @@ private void ProcessStatusChange(StatusChangedEventArgs e)
CoinjoinError.RandomlySkippedRound => RandomlySkippedRoundMessage,
CoinjoinError.MiningFeeRateTooHigh => CoinjoinMiningFeeRateTooHighMessage,
CoinjoinError.MinInputCountTooLow => MinInputCountTooLowMessage,
CoinjoinError.NoCoordinatorConfigured => NoCoordinatorConfiguredMessage,
_ => GeneralErrorMessage
};

Expand Down
5 changes: 5 additions & 0 deletions WalletWasabi.Fluent/Views/Wallets/MusicControlsView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@
<Button Classes="plain" IsVisible="{Binding CanNavigateToCoinjoinSettings^}">
<Button.Flyout>
<MenuFlyout Placement="Top">
<MenuItem ToolTip.Tip="{Binding FindCoordinatorLink}" Classes="hyperLinkMenuItem" Header="Find a Coordinator" Command="{Binding OpenFindCoordinatorLinkCommand}" IsVisible="{Binding NoCoordinatorConfigured}">
<MenuItem.Icon>
<PathIcon Data="{StaticResource book_question_mark_regular}" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Coinjoin Settings" Command="{Binding NavigateToSettingsCommand}">
<MenuItem.Icon>
<PathIcon Data="{StaticResource settings_general_regular}" />
Expand Down
4 changes: 2 additions & 2 deletions WalletWasabi.Tests/UnitTests/Bases/ConfigManagerNgTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ static string GetConfigString(string localBitcoinCoreDataDir)
"MainNetBackendUri": "https://api.wasabiwallet.io/",
"TestNetBackendUri": "https://api.wasabiwallet.co/",
"RegTestBackendUri": "http://localhost:37127/",
"MainNetCoordinatorUri": "https://api.wasabiwallet.io/",
"TestNetCoordinatorUri": "https://api.wasabiwallet.co/",
"MainNetCoordinatorUri": "",
"TestNetCoordinatorUri": "",
"RegTestCoordinatorUri": "http://localhost:37127/",
"UseTor": "Enabled",
"TerminateTorOnExit": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ public string Name
public IObservable<bool> HasBalance => throw new NotSupportedException();
public IAmountProvider AmountProvider => throw new NotSupportedException();
public IBuyAnythingModel BuyAnything => throw new NotSupportedException();

public bool IsLoggedIn { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }

public bool IsLoaded { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class LiveServerTestsFixture
{
public Dictionary<Network, Uri> UriMappings { get; } = new Dictionary<Network, Uri>
{
{ Network.Main, new Uri(Constants.BackendUri) },
{ Network.TestNet, new Uri(Constants.TestnetBackendUri) }
{ Network.Main, new Uri(Constants.DefaultBackendUri) },
{ Network.TestNet, new Uri(Constants.DefaultTestnetBackendUri) }
};
}
10 changes: 8 additions & 2 deletions WalletWasabi/Helpers/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@ public static class Constants
public const string ClientSupportBackendVersionMin = "4";
public const string ClientSupportBackendVersionMax = "4";

public const string BackendUri = "https://api.wasabiwallet.io/";
public const string TestnetBackendUri = "https://api.wasabiwallet.co/";
public const string DefaultBackendUri = "https://api.wasabiwallet.io/";
public const string DefaultTestnetBackendUri = "https://api.wasabiwallet.co/";
public const string DefaultRegtestBackendUri = "http://localhost:37127/";

public const string DefaultCoordinatorUri = "";
public const string DefaultTestnetCoordinatorUri = "";
public const string DefaultRegtestCoordinatorUri = "http://localhost:37127/";

public const string BackendMajorVersion = "4";

public const string WabiSabiFallBackCoordinatorExtPubKey = "xpub6C13JhXzjAhVRgeTcRSWqKEPe1vHi3Tmh2K9PN1cZaZFVjjSaj76y5NNyqYjc2bugj64LVDFYu8NZWtJsXNYKFb9J94nehLAPAKqKiXcebC";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@

namespace WalletWasabi.WabiSabi.Backend.PostRequests;

public interface IWabiSabiApiRequestHandler
public interface IWabiSabiStatusApiRequestHandler
{
Task<RoundStateResponse> GetStatusAsync(RoundStateRequest request, CancellationToken cancellationToken);
}

public interface IWabiSabiApiRequestHandler : IWabiSabiStatusApiRequestHandler
{
Task<InputRegistrationResponse> RegisterInputAsync(InputRegistrationRequest request, CancellationToken cancellationToken);

Expand All @@ -18,7 +23,13 @@ public interface IWabiSabiApiRequestHandler

Task<ReissueCredentialResponse> ReissuanceAsync(ReissueCredentialRequest request, CancellationToken cancellationToken);

Task<RoundStateResponse> GetStatusAsync(RoundStateRequest request, CancellationToken cancellationToken);

Task ReadyToSignAsync(ReadyToSignRequestRequest request, CancellationToken cancellationToken);
}

public class NullWabiSabiStatusApiRequestHandler : IWabiSabiStatusApiRequestHandler
{
public Task<RoundStateResponse> GetStatusAsync(RoundStateRequest request, CancellationToken cancellationToken)
{
return Task.FromResult(new RoundStateResponse([], []));
}
}
7 changes: 6 additions & 1 deletion WalletWasabi/WabiSabi/Client/Banning/CoinPrison.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace WalletWasabi.WabiSabi.Client.Banning;

public class CoinPrison(string filePath, Dictionary<OutPoint, PrisonedCoinRecord> bannedCoins) : IDisposable
public class CoinPrison(string? filePath, Dictionary<OutPoint, PrisonedCoinRecord> bannedCoins) : IDisposable
{
enum BanningStatus
{
Expand Down Expand Up @@ -48,6 +48,11 @@ public bool IsBanned(OutPoint outpoint)
}
}

public static CoinPrison CreateDummyPrison()
{
return new(null, []);
}

public static CoinPrison CreateOrLoadFromFile(string containingDirectory)
{
string prisonFilePath = Path.Combine(containingDirectory, "PrisonedCoins.json");
Expand Down
Loading

0 comments on commit b7c7ca4

Please sign in to comment.