Imrpove start-stop mechanism
MODIFY
WalletWasabi.Gui/Global.cs
WalletWasabi.Gui/Global.cs
@@ -155,6 +155,7 @@ namespace WalletWasabi.Gui
ChaumianClient = null;
AddressManager = null;
TorManager = null;
+ var cancel = StoppingCts.Token;
#region ConfigInitialization
@@ -164,6 +165,8 @@ namespace WalletWasabi.Gui
#endregion ConfigInitialization
+ cancel.ThrowIfCancellationRequested();
+
BitcoinStore = new BitcoinStore();
var bstoreInitTask = BitcoinStore.InitializeAsync(Path.Combine(DataDir, "BitcoinStore"), Network);
var addressManagerFolderPath = Path.Combine(DataDir, "AddressManager");
@@ -207,6 +210,8 @@ namespace WalletWasabi.Gui
#endregion ProcessKillSubscription
+ cancel.ThrowIfCancellationRequested();
+
#region TorProcessInitialization
if (Config.UseTor)
@@ -226,12 +231,16 @@ namespace WalletWasabi.Gui
#endregion TorProcessInitialization
+ cancel.ThrowIfCancellationRequested();
+
#region BitcoinStoreInitialization
await bstoreInitTask;
#endregion BitcoinStoreInitialization
+ cancel.ThrowIfCancellationRequested();
+
#region BitcoinCoreInitialization
try
@@ -252,7 +261,7 @@ namespace WalletWasabi.Gui
txIndex: null,
prune: null,
userAgent: $"/WasabiClient:{Constants.ClientVersion.ToString()}/"),
- CancellationToken.None)
+ cancel)
.ConfigureAwait(false);
}
}
@@ -261,7 +270,7 @@ namespace WalletWasabi.Gui
Logger.LogError(ex);
}
- await HostedServices.StartAllAsync(StoppingCts.Token).ConfigureAwait(false);
+ await HostedServices.StartAllAsync(cancel).ConfigureAwait(false);
var feeProviderList = new List<IFeeProvider>
{
@@ -278,12 +287,16 @@ namespace WalletWasabi.Gui
#endregion BitcoinCoreInitialization
+ cancel.ThrowIfCancellationRequested();
+
#region MempoolInitialization
connectionParameters.TemplateBehaviors.Add(BitcoinStore.CreateUntrustedP2pBehavior());
#endregion MempoolInitialization
+ cancel.ThrowIfCancellationRequested();
+
#region AddressManagerInitialization
AddressManagerBehavior addressManagerBehavior = await addrManTask;
@@ -291,6 +304,8 @@ namespace WalletWasabi.Gui
#endregion AddressManagerInitialization
+ cancel.ThrowIfCancellationRequested();
+
#region P2PInitialization
if (Network == Network.RegTest)
@@ -342,6 +357,8 @@ namespace WalletWasabi.Gui
#endregion P2PInitialization
+ cancel.ThrowIfCancellationRequested();
+
#region SynchronizerInitialization
var requestInterval = TimeSpan.FromSeconds(30);
@@ -357,6 +374,8 @@ namespace WalletWasabi.Gui
#endregion SynchronizerInitialization
+ cancel.ThrowIfCancellationRequested();
+
TransactionBroadcaster = new TransactionBroadcaster(Network, BitcoinStore, Synchronizer, Nodes, BitcoinCoreNode?.RpcClient);
CoinJoinProcessor = new CoinJoinProcessor(Synchronizer, BitcoinCoreNode?.RpcClient);
}

MODIFY
WalletWasabi/BitcoinCore/CoreNode.cs
WalletWasabi/BitcoinCore/CoreNode.cs
@@ -59,6 +59,7 @@ namespace WalletWasabi.BitcoinCore
var configString = await File.ReadAllTextAsync(configPath).ConfigureAwait(false);
coreNode.Config.TryAdd(configString);
}
+ cancel.ThrowIfCancellationRequested();
var configDic = coreNode.Config.ToDictionary();
string rpcUser = null;
@@ -140,11 +141,13 @@ namespace WalletWasabi.BitcoinCore
{
await coreNode.TryStopAsync(false).ConfigureAwait(false);
}
+ cancel.ThrowIfCancellationRequested();
if (coreNodeParams.TryDeleteDataDir)
{
await IoHelpers.DeleteRecursivelyWithMagicDustAsync(coreNode.DataDir).ConfigureAwait(false);
}
+ cancel.ThrowIfCancellationRequested();
IoHelpers.EnsureDirectoryExists(coreNode.DataDir);
@@ -192,6 +195,7 @@ namespace WalletWasabi.BitcoinCore
IoHelpers.EnsureContainingDirectoryExists(configPath);
await File.WriteAllTextAsync(configPath, coreNode.Config.ToString());
}
+ cancel.ThrowIfCancellationRequested();
// If it isn't already running, then we run it.
if (await coreNode.RpcClient.TestAsync().ConfigureAwait(false) is null)
@@ -201,12 +205,14 @@ namespace WalletWasabi.BitcoinCore
else
{
coreNode.Bridge = new BitcoindRpcProcessBridge(coreNode.RpcClient, coreNode.DataDir, printToConsole: false);
- await coreNode.Bridge.StartAsync().ConfigureAwait(false);
+ await coreNode.Bridge.StartAsync(cancel).ConfigureAwait(false);
Logger.LogInfo("Started Bitcoin Core.");
}
+ cancel.ThrowIfCancellationRequested();
coreNode.P2pNode = new P2pNode(coreNode.Network, coreNode.P2pEndPoint, coreNode.MempoolService, coreNodeParams.UserAgent);
await coreNode.P2pNode.ConnectAsync(cancel).ConfigureAwait(false);
+ cancel.ThrowIfCancellationRequested();
coreNode.HostedServices.Register(new BlockNotifier(TimeSpan.FromSeconds(7), new RpcWrappedClient(coreNode.RpcClient), coreNode.P2pNode), "Block Notifier");
coreNode.HostedServices.Register(new RpcMonitor(TimeSpan.FromSeconds(7), coreNode.RpcClient), "RPC Monitor");

MODIFY
WalletWasabi/BitcoinCore/Processes/BitcoindRpcProcessBridge.cs
WalletWasabi/BitcoinCore/Processes/BitcoindRpcProcessBridge.cs
@@ -35,7 +35,7 @@ namespace WalletWasabi.BitcoinCore.Processes
CachedPid = null;
}
- public async Task StartAsync()
+ public async Task StartAsync(CancellationToken cancel)
{
var ptcv = PrintToConsole ? 1 : 0;
using var process = Start($"{NetworkTranslator.GetCommandLineArguments(Network)} -datadir={DataDir} -printtoconsole={ptcv}", false);
@@ -43,18 +43,33 @@ namespace WalletWasabi.BitcoinCore.Processes
await PidFile.SerializeAsync(process.Id).ConfigureAwait(false);
CachedPid = process.Id;
+ string latestFailureMessage = null;
while (true)
{
var ex = await RpcClient.TestAsync().ConfigureAwait(false);
if (ex is null)
{
+ Logger.LogInfo($"RPC connection is sucessfully established.");
break;
}
+ else if (latestFailureMessage != ex.Message)
+ {
+ latestFailureMessage = ex.Message;
+ Logger.LogInfo($"Bitcoin Core is not yet ready... Reason: {latestFailureMessage}");
+ }
if (process is null || process.HasExited)
{
throw ex;
}
+
+ if (cancel.IsCancellationRequested)
+ {
+ await StopAsync(true).ConfigureAwait(false);
+ cancel.ThrowIfCancellationRequested();
+ }
+
+ await Task.Delay(100).ConfigureAwait(false); // So to leave some breathing room before the next check.
}
}

Imrpove start-stop mechanism