Fix Tor downtime problem (for some reason our old fix stopped working along the line and wasn't using the fallback url)
MODIFY
WalletWasabi.Gui/Global.cs
WalletWasabi.Gui/Global.cs
@@ -263,7 +263,7 @@ namespace WalletWasabi.Gui
RegTestMemPoolServingNode = null;
}
- Synchronizer = new WasabiSynchronizer(Network, IndexFilePath, Config.GetCurrentBackendUri(), Config.GetTorSocks5EndPoint());
+ Synchronizer = new WasabiSynchronizer(Network, IndexFilePath, () => Config.GetCurrentBackendUri(), Config.GetTorSocks5EndPoint());
UpdateChecker = new UpdateChecker(Synchronizer.WasabiClient);
@@ -292,7 +292,7 @@ namespace WalletWasabi.Gui
public static async Task InitializeWalletServiceAsync(KeyManager keyManager)
{
- ChaumianClient = new CcjClient(Synchronizer, Network, keyManager, Config.GetCurrentBackendUri(), Config.GetTorSocks5EndPoint());
+ ChaumianClient = new CcjClient(Synchronizer, Network, keyManager, () => Config.GetCurrentBackendUri(), Config.GetTorSocks5EndPoint());
WalletService = new WalletService(keyManager, Synchronizer, ChaumianClient, MemPoolService, Nodes, DataDir, Config.ServiceConfiguration);
ChaumianClient.Start();

MODIFY
WalletWasabi/Bases/TorDisposableBase.cs
WalletWasabi/Bases/TorDisposableBase.cs
@@ -14,6 +14,12 @@ namespace WalletWasabi.Bases
TorClient = new TorHttpClient(baseUri, torSocks5EndPoint, isolateStream: true);
}
+ /// <param name="torSocks5EndPoint">if null, then localhost:9050</param>
+ protected TorDisposableBase(Func<Uri> baseUriAction, IPEndPoint torSocks5EndPoint = null)
+ {
+ TorClient = new TorHttpClient(baseUriAction, torSocks5EndPoint, isolateStream: true);
+ }
+
#region IDisposable Support
private volatile bool _disposedValue = false; // To detect redundant calls

MODIFY
WalletWasabi/Services/CcjClient.cs
WalletWasabi/Services/CcjClient.cs
@@ -25,23 +25,23 @@ namespace WalletWasabi.Services
{
public class CcjClient
{
- public Network Network { get; }
- public KeyManager KeyManager { get; }
+ public Network Network { get; private set; }
+ public KeyManager KeyManager { get; private set; }
public bool IsQuitPending { get; set; }
private ClientRoundRegistration DelayedRoundRegistration { get; set; }
- public Uri CcjHostUri { get; }
- public WasabiSynchronizer Synchronizer { get; }
- private IPEndPoint TorSocks5EndPoint { get; }
+ public Func<Uri> CcjHostUriAction { get; private set; }
+ public WasabiSynchronizer Synchronizer { get; private set; }
+ private IPEndPoint TorSocks5EndPoint { get; set; }
private decimal? CoordinatorFeepercentToCheck { get; set; }
public ConcurrentDictionary<TxoRef, IEnumerable<HdPubKeyBlindedPair>> ExposedLinks { get; set; }
- private AsyncLock MixLock { get; }
+ private AsyncLock MixLock { get; set; }
- public CcjClientState State { get; }
+ public CcjClientState State { get; private set; }
public event EventHandler StateUpdated;
@@ -61,7 +61,17 @@ namespace WalletWasabi.Services
private long _statusProcessing;
- private CancellationTokenSource Cancel { get; }
+ private CancellationTokenSource Cancel { get; set; }
+
+ public CcjClient(
+ WasabiSynchronizer synchronizer,
+ Network network,
+ KeyManager keyManager,
+ Func<Uri> ccjHostUriAction,
+ IPEndPoint torSocks5EndPoint = null)
+ {
+ Create(synchronizer, network, keyManager, ccjHostUriAction, torSocks5EndPoint);
+ }
public CcjClient(
WasabiSynchronizer synchronizer,
@@ -69,10 +79,15 @@ namespace WalletWasabi.Services
KeyManager keyManager,
Uri ccjHostUri,
IPEndPoint torSocks5EndPoint = null)
+ {
+ Create(synchronizer, network, keyManager, () => ccjHostUri, torSocks5EndPoint);
+ }
+
+ private void Create(WasabiSynchronizer synchronizer, Network network, KeyManager keyManager, Func<Uri> ccjHostUriAction, IPEndPoint torSocks5EndPoint)
{
Network = Guard.NotNull(nameof(network), network);
KeyManager = Guard.NotNull(nameof(keyManager), keyManager);
- CcjHostUri = Guard.NotNull(nameof(ccjHostUri), ccjHostUri);
+ CcjHostUriAction = Guard.NotNull(nameof(ccjHostUriAction), ccjHostUriAction);
Synchronizer = Guard.NotNull(nameof(synchronizer), synchronizer);
TorSocks5EndPoint = torSocks5EndPoint;
CoordinatorFeepercentToCheck = null;
@@ -407,7 +422,7 @@ namespace WalletWasabi.Services
shuffledOutputs.Shuffle();
foreach ((BitcoinAddress address, UnblindedSignature signature, int mixingLevel) activeOutput in shuffledOutputs)
{
- using (var bobClient = new BobClient(CcjHostUri, TorSocks5EndPoint))
+ using (var bobClient = new BobClient(CcjHostUriAction, TorSocks5EndPoint))
{
if (!await bobClient.PostOutputAsync(ongoingRound.RoundId, activeOutput.address, activeOutput.signature, activeOutput.mixingLevel))
{
@@ -532,7 +547,7 @@ namespace WalletWasabi.Services
AliceClient aliceClient = null;
try
{
- aliceClient = await AliceClient.CreateNewAsync(inputRegistrableRound.RoundId, registeredAddresses, schnorrPubKeys, requesters, Network, outputAddresses.change.GetP2wpkhAddress(Network), blindedOutputScriptHashes, inputProofs, CcjHostUri, TorSocks5EndPoint);
+ aliceClient = await AliceClient.CreateNewAsync(inputRegistrableRound.RoundId, registeredAddresses, schnorrPubKeys, requesters, Network, outputAddresses.change.GetP2wpkhAddress(Network), blindedOutputScriptHashes, inputProofs, CcjHostUriAction, TorSocks5EndPoint);
}
catch (HttpRequestException ex) when (ex.Message.Contains("Input is banned", StringComparison.InvariantCultureIgnoreCase))
{

MODIFY
WalletWasabi/Services/WalletService.cs
WalletWasabi/Services/WalletService.cs
@@ -997,7 +997,7 @@ namespace WalletWasabi.Services
Logger.LogInfo<WalletService>("Calculating dynamic transaction fee...");
Money feePerBytes = null;
- using (var client = new WasabiClient(Synchronizer.WasabiClient.TorClient.DestinationUri, Synchronizer.WasabiClient.TorClient.TorSocks5EndPoint))
+ using (var client = new WasabiClient(Synchronizer.WasabiClient.TorClient.DestinationUriAction, Synchronizer.WasabiClient.TorClient.TorSocks5EndPoint))
{
Money feeRate = Synchronizer.GetFeeRate(feeTarget);
Money sanityCheckedFeeRate = Math.Max(feeRate, 2); // Use the sanity check that under 2 satoshi per bytes should not be displayed. To correct possible rounding errors.
@@ -1230,7 +1230,7 @@ namespace WalletWasabi.Services
public async Task SendTransactionAsync(SmartTransaction transaction)
{
- using (var client = new WasabiClient(Synchronizer.WasabiClient.TorClient.DestinationUri, Synchronizer.WasabiClient.TorClient.TorSocks5EndPoint))
+ using (var client = new WasabiClient(Synchronizer.WasabiClient.TorClient.DestinationUriAction, Synchronizer.WasabiClient.TorClient.TorSocks5EndPoint))
{
try
{

MODIFY
WalletWasabi/Services/WasabiSynchronizer.cs
WalletWasabi/Services/WasabiSynchronizer.cs
@@ -167,6 +167,12 @@ namespace WalletWasabi.Services
CreateNew(network, indexFilePath, client);
}
+ public WasabiSynchronizer(Network network, string indexFilePath, Func<Uri> baseUriAction, IPEndPoint torSocks5EndPoint = null)
+ {
+ var client = new WasabiClient(baseUriAction, torSocks5EndPoint);
+ CreateNew(network, indexFilePath, client);
+ }
+
public WasabiSynchronizer(Network network, string indexFilePath, Uri baseUri, IPEndPoint torSocks5EndPoint = null)
{
var client = new WasabiClient(baseUri, torSocks5EndPoint);

MODIFY
WalletWasabi/TorSocks5/TorHttpClient.cs
WalletWasabi/TorSocks5/TorHttpClient.cs
@@ -40,10 +40,11 @@ namespace WalletWasabi.TorSocks5
public static Exception LatestTorException { get; private set; } = null;
- public Uri DestinationUri { get; }
- public IPEndPoint TorSocks5EndPoint { get; }
+ public Uri DestinationUri => DestinationUriAction();
+ public Func<Uri> DestinationUriAction { get; private set; }
+ public IPEndPoint TorSocks5EndPoint { get; private set; }
- public bool IsolateStream { get; }
+ public bool IsolateStream { get; private set; }
public TorSocks5Client TorSocks5Client { get; private set; }
@@ -51,7 +52,18 @@ namespace WalletWasabi.TorSocks5
public TorHttpClient(Uri baseUri, IPEndPoint torSocks5EndPoint, bool isolateStream = false)
{
- DestinationUri = Guard.NotNull(nameof(baseUri), baseUri);
+ baseUri = Guard.NotNull(nameof(baseUri), baseUri);
+ Create(torSocks5EndPoint, isolateStream, () => baseUri);
+ }
+
+ public TorHttpClient(Func<Uri> baseUriAction, IPEndPoint torSocks5EndPoint, bool isolateStream = false)
+ {
+ Create(torSocks5EndPoint, isolateStream, baseUriAction);
+ }
+
+ private void Create(IPEndPoint torSocks5EndPoint, bool isolateStream, Func<Uri> baseUriAction)
+ {
+ DestinationUriAction = Guard.NotNull(nameof(baseUriAction), baseUriAction);
if (DestinationUri.IsLoopback)
{
TorSocks5EndPoint = null;

MODIFY
WalletWasabi/WebClients/Wasabi/ChaumianCoinJoin/AliceClient.cs
WalletWasabi/WebClients/Wasabi/ChaumianCoinJoin/AliceClient.cs
@@ -39,8 +39,8 @@ namespace WalletWasabi.WebClients.Wasabi.ChaumianCoinJoin
IEnumerable<SchnorrPubKey> schnorrPubKeys,
IEnumerable<Requester> requesters,
Network network,
- Uri baseUri,
- IPEndPoint torSocks5EndPoint = null) : base(baseUri, torSocks5EndPoint)
+ Func<Uri> baseUriAction,
+ IPEndPoint torSocks5EndPoint = null) : base(baseUriAction, torSocks5EndPoint)
{
RoundId = roundId;
RegisteredAddresses = registeredAddresses.ToArray();
@@ -59,7 +59,19 @@ namespace WalletWasabi.WebClients.Wasabi.ChaumianCoinJoin
Uri baseUri,
IPEndPoint torSocks5EndPoint = null)
{
- AliceClient client = new AliceClient(roundId, registeredAddresses, schnorrPubKeys, requesters, network, baseUri, torSocks5EndPoint);
+ return await CreateNewAsync(roundId, registeredAddresses, schnorrPubKeys, requesters, network, request, () => baseUri, torSocks5EndPoint);
+ }
+
+ public static async Task<AliceClient> CreateNewAsync(long roundId,
+ IEnumerable<BitcoinAddress> registeredAddresses,
+ IEnumerable<SchnorrPubKey> schnorrPubKeys,
+ IEnumerable<Requester> requesters,
+ Network network,
+ InputsRequest request,
+ Func<Uri> baseUriAction,
+ IPEndPoint torSocks5EndPoint)
+ {
+ AliceClient client = new AliceClient(roundId, registeredAddresses, schnorrPubKeys, requesters, network, baseUriAction, torSocks5EndPoint);
try
{
// Correct it if forgot to set.
@@ -112,6 +124,20 @@ namespace WalletWasabi.WebClients.Wasabi.ChaumianCoinJoin
IEnumerable<InputProofModel> inputs,
Uri baseUri,
IPEndPoint torSocks5EndPoint = null)
+ {
+ return await CreateNewAsync(roundId, registeredAddresses, schnorrPubKeys, requesters, network, changeOutput, blindedOutputScriptHashes, inputs, () => baseUri, torSocks5EndPoint);
+ }
+
+ public static async Task<AliceClient> CreateNewAsync(long roundId,
+ IEnumerable<BitcoinAddress> registeredAddresses,
+ IEnumerable<SchnorrPubKey> schnorrPubKeys,
+ IEnumerable<Requester> requesters,
+ Network network,
+ BitcoinAddress changeOutput,
+ IEnumerable<uint256> blindedOutputScriptHashes,
+ IEnumerable<InputProofModel> inputs,
+ Func<Uri> baseUriAction,
+ IPEndPoint torSocks5EndPoint)
{
var request = new InputsRequest
{
@@ -120,7 +146,7 @@ namespace WalletWasabi.WebClients.Wasabi.ChaumianCoinJoin
ChangeOutputAddress = changeOutput,
Inputs = inputs
};
- return await CreateNewAsync(roundId, registeredAddresses, schnorrPubKeys, requesters, network, request, baseUri, torSocks5EndPoint);
+ return await CreateNewAsync(roundId, registeredAddresses, schnorrPubKeys, requesters, network, request, baseUriAction, torSocks5EndPoint);
}
public async Task<(CcjRoundPhase currentPhase, IEnumerable<(BitcoinAddress output, UnblindedSignature signature, int level)> activeOutputs)> PostConfirmationAsync()

MODIFY
WalletWasabi/WebClients/Wasabi/ChaumianCoinJoin/BobClient.cs
WalletWasabi/WebClients/Wasabi/ChaumianCoinJoin/BobClient.cs
@@ -12,6 +12,11 @@ namespace WalletWasabi.WebClients.Wasabi.ChaumianCoinJoin
{
public class BobClient : TorDisposableBase
{
+ /// <inheritdoc/>
+ public BobClient(Func<Uri> baseUriAction, IPEndPoint torSocks5EndPoint = null) : base(baseUriAction, torSocks5EndPoint)
+ {
+ }
+
/// <inheritdoc/>
public BobClient(Uri baseUri, IPEndPoint torSocks5EndPoint = null) : base(baseUri, torSocks5EndPoint)
{

MODIFY
WalletWasabi/WebClients/Wasabi/ChaumianCoinJoin/SatoshiClient.cs
WalletWasabi/WebClients/Wasabi/ChaumianCoinJoin/SatoshiClient.cs
@@ -12,6 +12,11 @@ namespace WalletWasabi.WebClients.Wasabi.ChaumianCoinJoin
{
public class SatoshiClient : TorDisposableBase
{
+ /// <inheritdoc/>
+ public SatoshiClient(Func<Uri> baseUriAction, IPEndPoint torSocks5EndPoint = null) : base(baseUriAction, torSocks5EndPoint)
+ {
+ }
+
/// <inheritdoc/>
public SatoshiClient(Uri baseUri, IPEndPoint torSocks5EndPoint = null) : base(baseUri, torSocks5EndPoint)
{

MODIFY
WalletWasabi/WebClients/Wasabi/WasabiClient.cs
WalletWasabi/WebClients/Wasabi/WasabiClient.cs
@@ -16,6 +16,11 @@ namespace WalletWasabi.WebClients.Wasabi
{
public class WasabiClient : TorDisposableBase
{
+ /// <inheritdoc/>
+ public WasabiClient(Func<Uri> baseUriAction, IPEndPoint torSocks5EndPoint = null) : base(baseUriAction, torSocks5EndPoint)
+ {
+ }
+
/// <inheritdoc/>
public WasabiClient(Uri baseUri, IPEndPoint torSocks5EndPoint = null) : base(baseUri, torSocks5EndPoint)
{

Fix Tor downtime problem (for some reason our old fix stopped working along the line and wasn't using the fallback url)