Add pid file
MODIFY
WalletWasabi.Gui/Global.cs
WalletWasabi.Gui/Global.cs
@@ -643,7 +643,7 @@ namespace WalletWasabi.Gui
if (BitcoinCoreNode != null)
{
- await BitcoinCoreNode.TryStopAsync(deleteDataDir: false).ConfigureAwait(false);
+ await BitcoinCoreNode.TryStopAsync().ConfigureAwait(false);
Logger.LogInfo($"{nameof(BitcoinCoreNode)} is stopped.");
}

MODIFY
WalletWasabi.Tests/UnitTests/BitcoinCore/NodeBuildingTests.cs
WalletWasabi.Tests/UnitTests/BitcoinCore/NodeBuildingTests.cs
@@ -22,7 +22,7 @@ namespace WalletWasabi.Tests.UnitTests.BitcoinCore
}
finally
{
- await coreNode.TryStopAsync(deleteDataDir: true);
+ await coreNode.TryStopAsync();
}
}
@@ -41,7 +41,7 @@ namespace WalletWasabi.Tests.UnitTests.BitcoinCore
}
finally
{
- await Task.WhenAll(node1.TryStopAsync(deleteDataDir: true), node2.TryStopAsync(deleteDataDir: true));
+ await Task.WhenAll(node1.TryStopAsync(), node2.TryStopAsync());
}
}
@@ -56,7 +56,7 @@ namespace WalletWasabi.Tests.UnitTests.BitcoinCore
}
finally
{
- await coreNode.TryStopAsync(deleteDataDir: true);
+ await coreNode.TryStopAsync();
}
}
@@ -74,7 +74,7 @@ namespace WalletWasabi.Tests.UnitTests.BitcoinCore
finally
{
node.Disconnect();
- await coreNode.TryStopAsync(deleteDataDir: true);
+ await coreNode.TryStopAsync();
}
}

MODIFY
WalletWasabi.Tests/UnitTests/BitcoinCore/P2pBasedTests.cs
WalletWasabi.Tests/UnitTests/BitcoinCore/P2pBasedTests.cs
@@ -62,7 +62,7 @@ namespace WalletWasabi.Tests.UnitTests.BitcoinCore
finally
{
node.Disconnect();
- await coreNode.TryStopAsync(deleteDataDir: true);
+ await coreNode.TryStopAsync();
}
}
}

MODIFY
WalletWasabi.Tests/UnitTests/BitcoinCore/RpcBasedTests.cs
WalletWasabi.Tests/UnitTests/BitcoinCore/RpcBasedTests.cs
@@ -42,7 +42,7 @@ namespace WalletWasabi.Tests.UnitTests.BitcoinCore
}
finally
{
- await coreNode.TryStopAsync(deleteDataDir: true);
+ await coreNode.TryStopAsync();
}
}
}

MODIFY
WalletWasabi.Tests/XunitConfiguration/RegTestFixture.cs
WalletWasabi.Tests/XunitConfiguration/RegTestFixture.cs
@@ -113,7 +113,7 @@ namespace WalletWasabi.Tests.XunitConfiguration
{
BackendHost?.StopAsync().GetAwaiter().GetResult();
BackendHost?.Dispose();
- BackendRegTestNode?.TryStopAsync(deleteDataDir: true).GetAwaiter().GetResult();
+ BackendRegTestNode?.TryStopAsync().GetAwaiter().GetResult();
}
_disposedValue = true;

ADD
WalletWasabi/BitcoinCore/Configuration/PidFile.cs
+using NBitcoin;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+using WalletWasabi.Helpers;
+
+namespace WalletWasabi.BitcoinCore.Configuration
+{
+ public class PidFile
+ {
+ public PidFile(string dataDir, Network network)
+ {
+ DataDir = Guard.NotNullOrEmptyOrWhitespace(nameof(dataDir), dataDir);
+ Network = Guard.NotNull(nameof(network), network);
+ FilePath = Path.Combine(DataDir, NetworkTranslator.GetDataDirPrefix(Network), FileName);
+ }
+
+ public string DataDir { get; }
+ public Network Network { get; }
+ public const string FileName = "bitcoin.pid";
+ public string FilePath { get; }
+
+ public bool Exists => File.Exists(FilePath);
+
+ public async Task<int?> TryReadAsync()
+ {
+ if (!Exists)
+ {
+ return null;
+ }
+
+ var pidString = await File.ReadAllTextAsync(FilePath).ConfigureAwait(false);
+ return int.Parse(pidString);
+ }
+
+ public async Task SerializeAsync(int pid)
+ {
+ IoHelpers.EnsureContainingDirectoryExists(FilePath);
+ await File.WriteAllTextAsync(FilePath, pid.ToString()).ConfigureAwait(false);
+ }
+ }
+}

MODIFY
WalletWasabi/BitcoinCore/CoreNode.cs
WalletWasabi/BitcoinCore/CoreNode.cs
@@ -96,12 +96,17 @@ namespace WalletWasabi.BitcoinCore
coreNode.RpcEndPoint = rpce;
coreNode.RpcClient = new RPCClient($"{creds.UserName}:{creds.Password}", coreNode.RpcEndPoint.ToString(coreNode.Network.DefaultPort), coreNode.Network);
- var pidFileName = "bitcoind.pid";
if (coreNodeParams.TryRestart)
{
- await coreNode.TryStopNoLockAsync(deleteDataDir: coreNodeParams.TryDeleteDataDir).ConfigureAwait(false);
+ await coreNode.TryStopNoLockAsync().ConfigureAwait(false);
}
+
+ if (coreNodeParams.TryDeleteDataDir)
+ {
+ await IoHelpers.DeleteRecursivelyWithMagicDustAsync(coreNode.DataDir).ConfigureAwait(false);
+ }
+
IoHelpers.EnsureDirectoryExists(coreNode.DataDir);
var configPrefix = NetworkTranslator.GetConfigPrefix(coreNode.Network);
@@ -113,8 +118,7 @@ namespace WalletWasabi.BitcoinCore
$"{configPrefix}.rpcuser = {coreNode.RpcClient.CredentialString.UserPassword.UserName}",
$"{configPrefix}.rpcpassword = {coreNode.RpcClient.CredentialString.UserPassword.Password}",
$"{configPrefix}.rpchost = {coreNode.RpcEndPoint.GetHostOrDefault()}",
- $"{configPrefix}.rpcport = {coreNode.RpcEndPoint.GetPortOrDefault()}",
- $"{configPrefix}.pid = {pidFileName}"
+ $"{configPrefix}.rpcport = {coreNode.RpcEndPoint.GetPortOrDefault()}"
};
var sectionComment = $"# The following configuration options were added or modified by Wasabi Wallet.";
@@ -135,12 +139,9 @@ namespace WalletWasabi.BitcoinCore
coreNode.Bridge = new BitcoindProcessBridge();
coreNode.Process = coreNode.Bridge.Start($"-{coreNode.Network.ToString().ToLowerInvariant()} -conf={configFileName} -datadir={coreNode.DataDir} -printtoconsole=0", false);
- string pidFile = Path.Combine(coreNode.DataDir, NetworkTranslator.GetDataDirPrefix(coreNode.Network), pidFileName);
- if (!File.Exists(pidFile))
- {
- IoHelpers.EnsureDirectoryExists(Path.Combine(coreNode.DataDir, NetworkTranslator.GetDataDirPrefix(coreNode.Network)));
- await File.WriteAllTextAsync(pidFile, coreNode.Process.Id.ToString());
- }
+
+ var pidFile = new PidFile(coreNode.DataDir, coreNode.Network);
+ await pidFile.SerializeAsync(coreNode.Process.Id).ConfigureAwait(false);
while (true)
{
@@ -195,15 +196,15 @@ namespace WalletWasabi.BitcoinCore
private static AsyncLock KillerLock { get; } = new AsyncLock();
- public async Task TryStopAsync(bool deleteDataDir)
+ public async Task TryStopAsync()
{
using (await KillerLock.LockAsync().ConfigureAwait(false))
{
- await TryStopNoLockAsync(deleteDataDir).ConfigureAwait(false);
+ await TryStopNoLockAsync().ConfigureAwait(false);
}
}
- public async Task TryStopNoLockAsync(bool deleteDataDir)
+ public async Task TryStopNoLockAsync()
{
try
{
@@ -211,33 +212,27 @@ namespace WalletWasabi.BitcoinCore
var foundConfigDic = Config.ToDictionary();
- var networkEntry = NetworkTranslator.GetConfigPrefix(Network);
- var pidFileName = foundConfigDic.TryGet($"{networkEntry}.pid");
-
- await RpcClient.StopAsync().ConfigureAwait(false);
-
- var pidFile = Path.Combine(DataDir, NetworkTranslator.GetDataDirPrefix(Network), pidFileName);
using CancellationTokenSource cts = new CancellationTokenSource(reasonableCoreShutdownTimeout);
- if (File.Exists(pidFile))
+ var pidFile = new PidFile(DataDir, Network);
+ var pid = await pidFile.TryReadAsync().ConfigureAwait(false);
+
+ if (pid.HasValue)
{
- var pid = await File.ReadAllTextAsync(pidFile).ConfigureAwait(false);
- using var process = Process.GetProcessById(int.Parse(pid));
- await process.WaitForExitAsync(cts.Token).ConfigureAwait(false);
- }
- else
+ try
{
- var allProcesses = Process.GetProcesses();
- var bitcoindProcesses = allProcesses.Where(x => x.ProcessName.Contains("bitcoind"));
- if (bitcoindProcesses.Count() == 1)
+ using Process process = Process.GetProcessById(pid.Value);
+ var waitForExit = process.WaitForExitAsync(cts.Token);
+ await RpcClient.StopAsync().ConfigureAwait(false);
+ await waitForExit.ConfigureAwait(false);
+ }
+ catch (Exception ex)
{
- var bitcoind = bitcoindProcesses.First();
- await bitcoind.WaitForExitAsync(cts.Token).ConfigureAwait(false);
+ Logger.LogDebug(ex);
}
}
-
- if (deleteDataDir)
+ else
{
- await IoHelpers.DeleteRecursivelyWithMagicDustAsync(DataDir).ConfigureAwait(false);
+ await RpcClient.StopAsync().ConfigureAwait(false);
}
}
catch (Exception ex)

Add pid file