Introduce configurable coordinator identifier in client
MODIFY
WalletWasabi.Fluent/Config.cs
WalletWasabi.Fluent/Config.cs
@@ -115,6 +115,10 @@ public class Config : ConfigBase
[JsonConverter(typeof(MoneyBtcJsonConverter))]
public Money DustThreshold { get; internal set; } = DefaultDustThreshold;
+ [DefaultValue("wasabiwallet.io")]
+ [JsonProperty(PropertyName = "CoordinatorIdentifier", DefaultValueHandling = DefaultValueHandling.Populate)]
+ public string CoordinatorIdentifier { get; set; } = "wasabiwallet.io";
+
public ServiceConfiguration ServiceConfiguration { get; private set; }
public Uri GetCurrentBackendUri()

MODIFY
WalletWasabi.Fluent/Global.cs
WalletWasabi.Fluent/Global.cs
@@ -297,7 +297,7 @@ public class Global
{
Tor.Http.IHttpClient roundStateUpdaterHttpClient = HttpClientFactory.NewHttpClient(Mode.SingleCircuitPerLifetime, RoundStateUpdaterCircuit);
HostedServices.Register<RoundStateUpdater>(() => new RoundStateUpdater(TimeSpan.FromSeconds(5), new WabiSabiHttpApiClient(roundStateUpdaterHttpClient)), "Round info updater");
- HostedServices.Register<CoinJoinManager>(() => new CoinJoinManager(WalletManager, HostedServices.Get<RoundStateUpdater>(), HttpClientFactory, Config.ServiceConfiguration), "CoinJoin Manager");
+ HostedServices.Register<CoinJoinManager>(() => new CoinJoinManager(WalletManager, HostedServices.Get<RoundStateUpdater>(), HttpClientFactory, Config.ServiceConfiguration, Config.CoordinatorIdentifier), "CoinJoin Manager");
}
public async Task DisposeAsync()

MODIFY
WalletWasabi.Tests/Helpers/WabiSabiFactory.cs
WalletWasabi.Tests/Helpers/WabiSabiFactory.cs
@@ -136,6 +136,7 @@ public static class WabiSabiFactory
return new ArenaClient(
roundState.CreateAmountCredentialClient(random),
roundState.CreateVsizeCredentialClient(random),
+ "wasabiwallet.io",
arena);
}
@@ -299,6 +300,7 @@ public static class WabiSabiFactory
keyChain,
destinationProvider,
roundStateUpdater,
+ "wasabiwallet.io",
int.MaxValue,
true,
TimeSpan.Zero,

MODIFY
WalletWasabi.Tests/UnitTests/WabiSabi/Client/ArenaClientTests.cs
WalletWasabi.Tests/UnitTests/WabiSabi/Client/ArenaClientTests.cs
@@ -74,6 +74,7 @@ public class ArenaClientTests
var aliceArenaClient = new ArenaClient(
roundState.CreateAmountCredentialClient(insecureRandom),
roundState.CreateVsizeCredentialClient(insecureRandom),
+ "wasabiwallet.io",
wabiSabiApi);
var ownershipProof = WabiSabiFactory.CreateOwnershipProof(key, round.Id);
@@ -126,6 +127,7 @@ public class ArenaClientTests
var bobArenaClient = new ArenaClient(
roundState.CreateAmountCredentialClient(insecureRandom),
roundState.CreateVsizeCredentialClient(insecureRandom),
+ "wasabiwallet.io",
wabiSabiApi);
var reissuanceResponse = await bobArenaClient.ReissueCredentialAsync(
@@ -188,7 +190,7 @@ public class ArenaClientTests
using CoinJoinFeeRateStatStore coinJoinFeeRateStatStore = new(config, arena.Rpc);
var wabiSabiApi = new WabiSabiController(idempotencyRequestCache, arena, coinJoinFeeRateStatStore);
- var apiClient = new ArenaClient(null!, null!, wabiSabiApi);
+ var apiClient = new ArenaClient(null!, null!, "wasabiwallet.io", wabiSabiApi);
round.SetPhase(Phase.InputRegistration);
@@ -231,7 +233,7 @@ public class ArenaClientTests
InsecureRandom rnd = InsecureRandom.Instance;
var amountClient = new WabiSabiClient(round.AmountCredentialIssuerParameters, rnd, 4300000000000L);
var vsizeClient = new WabiSabiClient(round.VsizeCredentialIssuerParameters, rnd, 2000L);
- var apiClient = new ArenaClient(amountClient, vsizeClient, wabiSabiApi);
+ var apiClient = new ArenaClient(amountClient, vsizeClient, "wasabiwallet.io", wabiSabiApi);
round.SetPhase(Phase.TransactionSigning);

MODIFY
WalletWasabi.Tests/UnitTests/WabiSabi/Client/BobClientTests.cs
WalletWasabi.Tests/UnitTests/WabiSabi/Client/BobClientTests.cs
@@ -46,10 +46,12 @@ public class BobClientTests
var aliceArenaClient = new ArenaClient(
roundState.CreateAmountCredentialClient(insecureRandom),
roundState.CreateVsizeCredentialClient(insecureRandom),
+ "wasabiwallet.io",
wabiSabiApi);
var bobArenaClient = new ArenaClient(
roundState.CreateAmountCredentialClient(insecureRandom),
roundState.CreateVsizeCredentialClient(insecureRandom),
+ "wasabiwallet.io",
wabiSabiApi);
Assert.Equal(Phase.InputRegistration, round.Phase);

MODIFY
WalletWasabi.Tests/UnitTests/WabiSabi/Integration/WabiSabiApiApplicationFactory.cs
WalletWasabi.Tests/UnitTests/WabiSabi/Integration/WabiSabiApiApplicationFactory.cs
@@ -83,6 +83,7 @@ public class WabiSabiApiApplicationFactory<TStartup> : WebApplicationFactory<TSt
var arenaClient = new ArenaClient(
round.CreateAmountCredentialClient(insecureRandom),
round.CreateVsizeCredentialClient(insecureRandom),
+ "wasabiwallet.io",
wabiSabiHttpApiClient);
return arenaClient;
}

MODIFY
WalletWasabi/WabiSabi/Client/AliceClient.cs
WalletWasabi/WabiSabi/Client/AliceClient.cs
@@ -94,7 +94,7 @@ public class AliceClient
{
var ownershipProof = keyChain.GetOwnershipProof(
coin,
- new CoinJoinInputCommitmentData("CoinJoinCoordinatorIdentifier", roundState.Id));
+ new CoinJoinInputCommitmentData(arenaClient.CoordinatorIdentifier, roundState.Id));
var (response, isPayingZeroCoordinationFee) = await arenaClient.RegisterInputAsync(roundState.Id, coin.Coin.Outpoint, ownershipProof, cancellationToken).ConfigureAwait(false);
aliceClient = new(response.Value, roundState, arenaClient, coin, ownershipProof, response.IssuedAmountCredentials, response.IssuedVsizeCredentials, isPayingZeroCoordinationFee);

MODIFY
WalletWasabi/WabiSabi/Client/ArenaClient.cs
WalletWasabi/WabiSabi/Client/ArenaClient.cs
@@ -17,15 +17,18 @@ public class ArenaClient
public ArenaClient(
WabiSabiClient amountCredentialClient,
WabiSabiClient vsizeCredentialClient,
+ string coordinatorIdentifier,
IWabiSabiApiRequestHandler requestHandler)
{
AmountCredentialClient = amountCredentialClient;
VsizeCredentialClient = vsizeCredentialClient;
+ CoordinatorIdentifier = coordinatorIdentifier;
RequestHandler = requestHandler;
}
public WabiSabiClient AmountCredentialClient { get; }
public WabiSabiClient VsizeCredentialClient { get; }
+ public string CoordinatorIdentifier { get; }
public IWabiSabiApiRequestHandler RequestHandler { get; }
public async Task<(ArenaResponse<Guid> ArenaResponse, bool IsPayingZeroCoordinationFee)> RegisterInputAsync(

MODIFY
WalletWasabi/WabiSabi/Client/CoinJoinClient.cs
WalletWasabi/WabiSabi/Client/CoinJoinClient.cs
@@ -41,6 +41,7 @@ public class CoinJoinClient
IKeyChain keyChain,
IDestinationProvider destinationProvider,
RoundStateUpdater roundStatusUpdater,
+ string coordinatorIdentifier,
int anonScoreTarget = int.MaxValue,
bool consolidationMode = false,
TimeSpan feeRateMedianTimeFrame = default,
@@ -51,6 +52,7 @@ public class CoinJoinClient
DestinationProvider = destinationProvider;
RoundStatusUpdater = roundStatusUpdater;
AnonScoreTarget = anonScoreTarget;
+ CoordinatorIdentifier = coordinatorIdentifier;
ConsolidationMode = consolidationMode;
FeeRateMedianTimeFrame = feeRateMedianTimeFrame;
SecureRandom = new SecureRandom();
@@ -64,6 +66,7 @@ public class CoinJoinClient
private IKeyChain KeyChain { get; }
private IDestinationProvider DestinationProvider { get; }
private RoundStateUpdater RoundStatusUpdater { get; }
+ public string CoordinatorIdentifier { get; }
public int AnonScoreTarget { get; }
private TimeSpan DoNotRegisterInLastMinuteTimeLimit { get; }
@@ -282,6 +285,7 @@ public class CoinJoinClient
var aliceArenaClient = new ArenaClient(
roundState.CreateAmountCredentialClient(SecureRandom),
roundState.CreateVsizeCredentialClient(SecureRandom),
+ CoordinatorIdentifier,
arenaRequestHandler);
var aliceClient = await AliceClient.CreateRegisterAndConfirmInputAsync(roundState, aliceArenaClient, coin, KeyChain, RoundStatusUpdater, linkedUnregisterCts.Token, linkedRegistrationsCts.Token, linkedConfirmationsCts.Token).ConfigureAwait(false);
@@ -375,6 +379,7 @@ public class CoinJoinClient
new(
roundState.CreateAmountCredentialClient(SecureRandom),
roundState.CreateVsizeCredentialClient(SecureRandom),
+ CoordinatorIdentifier,
arenaRequestHandler));
}

MODIFY
WalletWasabi/WabiSabi/Client/CoinJoinManager.cs
WalletWasabi/WabiSabi/Client/CoinJoinManager.cs
@@ -26,18 +26,20 @@ public class CoinJoinManager : BackgroundService
private record StartCoinJoinCommand(Wallet Wallet, bool StopWhenAllMixed, bool OverridePlebStop) : CoinJoinCommand(Wallet);
private record StopCoinJoinCommand(Wallet Wallet) : CoinJoinCommand(Wallet);
- public CoinJoinManager(WalletManager walletManager, RoundStateUpdater roundStatusUpdater, IWasabiHttpClientFactory backendHttpClientFactory, ServiceConfiguration serviceConfiguration)
+ public CoinJoinManager(WalletManager walletManager, RoundStateUpdater roundStatusUpdater, IWasabiHttpClientFactory backendHttpClientFactory, ServiceConfiguration serviceConfiguration, string coordinatorIdentifier)
{
WalletManager = walletManager;
HttpClientFactory = backendHttpClientFactory;
RoundStatusUpdater = roundStatusUpdater;
ServiceConfiguration = serviceConfiguration;
+ CoordinatorIdentifier = coordinatorIdentifier;
}
public WalletManager WalletManager { get; }
public IWasabiHttpClientFactory HttpClientFactory { get; }
public RoundStateUpdater RoundStatusUpdater { get; }
public ServiceConfiguration ServiceConfiguration { get; }
+ public string CoordinatorIdentifier { get; }
private CoinRefrigerator CoinRefrigerator { get; } = new();
public bool IsUserInSendWorkflow { get; set; }
@@ -129,7 +131,7 @@ public class CoinJoinManager : BackgroundService
private async Task HandleCoinJoinCommandsAsync(ConcurrentDictionary<string, CoinJoinTracker> trackedCoinJoins, ConcurrentDictionary<Wallet, TrackedAutoStart> trackedAutoStarts, CancellationToken stoppingToken)
{
- var coinJoinTrackerFactory = new CoinJoinTrackerFactory(HttpClientFactory, RoundStatusUpdater, stoppingToken);
+ var coinJoinTrackerFactory = new CoinJoinTrackerFactory(HttpClientFactory, RoundStatusUpdater, CoordinatorIdentifier, stoppingToken);
void StartCoinJoinCommand(StartCoinJoinCommand startCommand)
{

MODIFY
WalletWasabi/WabiSabi/Client/CoinJoinTrackerFactory.cs
WalletWasabi/WabiSabi/Client/CoinJoinTrackerFactory.cs
@@ -12,16 +12,19 @@ public class CoinJoinTrackerFactory
public CoinJoinTrackerFactory(
IWasabiHttpClientFactory httpClientFactory,
RoundStateUpdater roundStatusUpdater,
+ string coordinatorIdentifier,
CancellationToken cancellationToken)
{
HttpClientFactory = httpClientFactory;
RoundStatusUpdater = roundStatusUpdater;
+ CoordinatorIdentifier = coordinatorIdentifier;
CancellationToken = cancellationToken;
}
private IWasabiHttpClientFactory HttpClientFactory { get; }
private RoundStateUpdater RoundStatusUpdater { get; }
private CancellationToken CancellationToken { get; }
+ private string CoordinatorIdentifier { get; }
public CoinJoinTracker CreateAndStart(Wallet wallet, IEnumerable<SmartCoin> coinCandidates, bool restartAutomatically, bool overridePlebStop)
{
@@ -30,6 +33,7 @@ public class CoinJoinTrackerFactory
new KeyChain(wallet.KeyManager, wallet.Kitchen),
new InternalDestinationProvider(wallet.KeyManager),
RoundStatusUpdater,
+ CoordinatorIdentifier,
wallet.KeyManager.AnonScoreTarget,
feeRateMedianTimeFrame: TimeSpan.FromHours(wallet.KeyManager.FeeRateMedianTimeFrameHours),
doNotRegisterInLastMinuteTimeLimit: TimeSpan.FromMinutes(1));

Introduce configurable coordinator identifier in client