Skip to content

Commit

Permalink
Make P2P and Tor configurations oneliners (#1945)
Browse files Browse the repository at this point in the history
Make P2P and Tor configurations oneliners
  • Loading branch information
nopara73 committed Jul 22, 2019
2 parents dc435fd + 54a991d commit 572f2cd
Show file tree
Hide file tree
Showing 35 changed files with 1,021 additions and 474 deletions.
214 changes: 143 additions & 71 deletions WalletWasabi.Backend/Config.cs
@@ -1,4 +1,5 @@
using NBitcoin;
using NBitcoin.RPC;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
Expand Down Expand Up @@ -27,63 +28,68 @@ public class Config : IConfig
[JsonProperty(PropertyName = "BitcoinRpcConnectionString")]
public string BitcoinRpcConnectionString { get; private set; }

[JsonProperty(PropertyName = "MainNetBitcoinCoreHost")]
public string MainNetBitcoinCoreHost { get; internal set; }
[JsonProperty(PropertyName = "MainNetBitcoinP2pEndPoint")]
[JsonConverter(typeof(EndPointJsonConverter), Constants.DefaultMainNetBitcoinP2pPort)]
public EndPoint MainNetBitcoinP2pEndPoint { get; internal set; }

[JsonProperty(PropertyName = "TestNetBitcoinCoreHost")]
public string TestNetBitcoinCoreHost { get; internal set; }
[JsonProperty(PropertyName = "TestNetBitcoinP2pEndPoint")]
[JsonConverter(typeof(EndPointJsonConverter), Constants.DefaultTestNetBitcoinP2pPort)]
public EndPoint TestNetBitcoinP2pEndPoint { get; internal set; }

[JsonProperty(PropertyName = "RegTestBitcoinCoreHost")]
public string RegTestBitcoinCoreHost { get; internal set; }
[JsonProperty(PropertyName = "RegTestBitcoinP2pEndPoint")]
[JsonConverter(typeof(EndPointJsonConverter), Constants.DefaultRegTestBitcoinP2pPort)]
public EndPoint RegTestBitcoinP2pEndPoint { get; internal set; }

[JsonProperty(PropertyName = "MainNetBitcoinCorePort")]
public int? MainNetBitcoinCorePort { get; internal set; }
[JsonProperty(PropertyName = "MainNetBitcoinCoreRpcEndPoint")]
[JsonConverter(typeof(EndPointJsonConverter), Constants.DefaultMainNetBitcoinCoreRpcPort)]
public EndPoint MainNetBitcoinCoreRpcEndPoint { get; internal set; }

[JsonProperty(PropertyName = "TestNetBitcoinCorePort")]
public int? TestNetBitcoinCorePort { get; internal set; }
[JsonProperty(PropertyName = "TestNetBitcoinCoreRpcEndPoint")]
[JsonConverter(typeof(EndPointJsonConverter), Constants.DefaultTestNetBitcoinCoreRpcPort)]
public EndPoint TestNetBitcoinCoreRpcEndPoint { get; internal set; }

[JsonProperty(PropertyName = "RegTestBitcoinCorePort")]
public int? RegTestBitcoinCorePort { get; internal set; }
[JsonProperty(PropertyName = "RegTestBitcoinCoreRpcEndPoint")]
[JsonConverter(typeof(EndPointJsonConverter), Constants.DefaultRegTestBitcoinCoreRpcPort)]
public EndPoint RegTestBitcoinCoreRpcEndPoint { get; internal set; }

private EndPoint _bitcoinCoreEndPoint;

public EndPoint GetBitcoinCoreEndPoint()
public EndPoint GetBitcoinP2pEndPoint()
{
if (_bitcoinCoreEndPoint is null)
if (Network == Network.Main)
{
IPAddress ipHost;
string dnsHost = null;
int? port = null;
try
{
if (Network == Network.Main)
{
port = MainNetBitcoinCorePort;
dnsHost = MainNetBitcoinCoreHost;
ipHost = IPAddress.Parse(MainNetBitcoinCoreHost);
}
else if (Network == Network.TestNet)
{
port = TestNetBitcoinCorePort;
dnsHost = TestNetBitcoinCoreHost;
ipHost = IPAddress.Parse(TestNetBitcoinCoreHost);
}
else // if (Network == Network.RegTest)
{
port = RegTestBitcoinCorePort;
dnsHost = RegTestBitcoinCoreHost;
ipHost = IPAddress.Parse(RegTestBitcoinCoreHost);
}

_bitcoinCoreEndPoint = new IPEndPoint(ipHost, port ?? Network.DefaultPort);
}
catch
{
_bitcoinCoreEndPoint = new DnsEndPoint(dnsHost, port ?? Network.DefaultPort);
}
return MainNetBitcoinP2pEndPoint;
}
else if (Network == Network.TestNet)
{
return TestNetBitcoinP2pEndPoint;
}
else if (Network == Network.RegTest)
{
return RegTestBitcoinP2pEndPoint;
}
else
{
throw new NotSupportedException($"{nameof(Network)} not supported: {Network}.");
}
}

return _bitcoinCoreEndPoint;
public EndPoint GetBitcoinCoreRpcEndPoint()
{
if (Network == Network.Main)
{
return MainNetBitcoinCoreRpcEndPoint;
}
else if (Network == Network.TestNet)
{
return TestNetBitcoinCoreRpcEndPoint;
}
else if (Network == Network.RegTest)
{
return RegTestBitcoinCoreRpcEndPoint;
}
else
{
throw new NotSupportedException($"{nameof(Network)} not supported: {Network}.");
}
}

public Config()
Expand All @@ -97,22 +103,23 @@ public Config(string filePath)

public Config(Network network,
string bitcoinRpcConnectionString,
string mainNetBitcoinCoreHost,
string testNetBitcoinCoreHost,
string regTestBitcoinCoreHost,
int? mainNetBitcoinCorePort,
int? testNetBitcoinCorePort,
int? regTestBitcoinCorePort)
EndPoint mainNetBitcoinP2pEndPoint,
EndPoint testNetBitcoinP2pEndPoint,
EndPoint regTestBitcoinP2pEndPoint,
EndPoint mainNetBitcoinCoreRpcEndPoint,
EndPoint testNetBitcoinCoreRpcEndPoint,
EndPoint regTestBitcoinCoreRpcEndPoint)
{
Network = Guard.NotNull(nameof(network), network);
BitcoinRpcConnectionString = Guard.NotNullOrEmptyOrWhitespace(nameof(bitcoinRpcConnectionString), bitcoinRpcConnectionString);

MainNetBitcoinCoreHost = Guard.NotNullOrEmptyOrWhitespace(nameof(mainNetBitcoinCoreHost), mainNetBitcoinCoreHost);
TestNetBitcoinCoreHost = Guard.NotNullOrEmptyOrWhitespace(nameof(testNetBitcoinCoreHost), testNetBitcoinCoreHost);
RegTestBitcoinCoreHost = Guard.NotNullOrEmptyOrWhitespace(nameof(regTestBitcoinCoreHost), regTestBitcoinCoreHost);
MainNetBitcoinCorePort = Guard.NotNull(nameof(mainNetBitcoinCorePort), mainNetBitcoinCorePort);
TestNetBitcoinCorePort = Guard.NotNull(nameof(testNetBitcoinCorePort), testNetBitcoinCorePort);
RegTestBitcoinCorePort = Guard.NotNull(nameof(regTestBitcoinCorePort), regTestBitcoinCorePort);
MainNetBitcoinP2pEndPoint = Guard.NotNull(nameof(mainNetBitcoinP2pEndPoint), mainNetBitcoinP2pEndPoint);
TestNetBitcoinP2pEndPoint = Guard.NotNull(nameof(testNetBitcoinP2pEndPoint), testNetBitcoinP2pEndPoint);
RegTestBitcoinP2pEndPoint = Guard.NotNull(nameof(regTestBitcoinP2pEndPoint), regTestBitcoinP2pEndPoint);

MainNetBitcoinCoreRpcEndPoint = Guard.NotNull(nameof(mainNetBitcoinCoreRpcEndPoint), mainNetBitcoinCoreRpcEndPoint);
TestNetBitcoinCoreRpcEndPoint = Guard.NotNull(nameof(testNetBitcoinCoreRpcEndPoint), testNetBitcoinCoreRpcEndPoint);
RegTestBitcoinCoreRpcEndPoint = Guard.NotNull(nameof(regTestBitcoinCoreRpcEndPoint), regTestBitcoinCoreRpcEndPoint);
}

/// <inheritdoc />
Expand All @@ -134,12 +141,14 @@ public async Task LoadOrCreateDefaultFileAsync()
Network = Network.Main;
BitcoinRpcConnectionString = "user:password";

MainNetBitcoinCoreHost = IPAddress.Loopback.ToString();
TestNetBitcoinCoreHost = IPAddress.Loopback.ToString();
RegTestBitcoinCoreHost = IPAddress.Loopback.ToString();
MainNetBitcoinCorePort = Network.Main.DefaultPort;
TestNetBitcoinCorePort = Network.TestNet.DefaultPort;
RegTestBitcoinCorePort = Network.RegTest.DefaultPort;
MainNetBitcoinP2pEndPoint = new IPEndPoint(IPAddress.Loopback, Constants.DefaultMainNetBitcoinP2pPort);
TestNetBitcoinP2pEndPoint = new IPEndPoint(IPAddress.Loopback, Constants.DefaultTestNetBitcoinP2pPort);
RegTestBitcoinP2pEndPoint = new IPEndPoint(IPAddress.Loopback, Constants.DefaultRegTestBitcoinP2pPort);

MainNetBitcoinCoreRpcEndPoint = new IPEndPoint(IPAddress.Loopback, Constants.DefaultMainNetBitcoinCoreRpcPort);
TestNetBitcoinCoreRpcEndPoint = new IPEndPoint(IPAddress.Loopback, Constants.DefaultTestNetBitcoinCoreRpcPort);
RegTestBitcoinCoreRpcEndPoint = new IPEndPoint(IPAddress.Loopback, Constants.DefaultRegTestBitcoinCoreRpcPort);

if (!File.Exists(FilePath))
{
Logger.LogInfo<Config>($"{nameof(Config)} file did not exist. Created at path: `{FilePath}`.");
Expand All @@ -152,12 +161,18 @@ public async Task LoadOrCreateDefaultFileAsync()
Network = config.Network ?? Network;
BitcoinRpcConnectionString = config.BitcoinRpcConnectionString ?? BitcoinRpcConnectionString;

MainNetBitcoinCoreHost = config.MainNetBitcoinCoreHost ?? MainNetBitcoinCoreHost;
TestNetBitcoinCoreHost = config.TestNetBitcoinCoreHost ?? TestNetBitcoinCoreHost;
RegTestBitcoinCoreHost = config.RegTestBitcoinCoreHost ?? RegTestBitcoinCoreHost;
MainNetBitcoinCorePort = config.MainNetBitcoinCorePort ?? MainNetBitcoinCorePort;
TestNetBitcoinCorePort = config.TestNetBitcoinCorePort ?? TestNetBitcoinCorePort;
RegTestBitcoinCorePort = config.RegTestBitcoinCorePort ?? RegTestBitcoinCorePort;
MainNetBitcoinP2pEndPoint = config.MainNetBitcoinP2pEndPoint ?? MainNetBitcoinP2pEndPoint;
TestNetBitcoinP2pEndPoint = config.TestNetBitcoinP2pEndPoint ?? TestNetBitcoinP2pEndPoint;
RegTestBitcoinP2pEndPoint = config.RegTestBitcoinP2pEndPoint ?? RegTestBitcoinP2pEndPoint;

MainNetBitcoinCoreRpcEndPoint = config.MainNetBitcoinCoreRpcEndPoint ?? MainNetBitcoinCoreRpcEndPoint;
TestNetBitcoinCoreRpcEndPoint = config.TestNetBitcoinCoreRpcEndPoint ?? TestNetBitcoinCoreRpcEndPoint;
RegTestBitcoinCoreRpcEndPoint = config.RegTestBitcoinCoreRpcEndPoint ?? RegTestBitcoinCoreRpcEndPoint;

if (TryEnsureBackwardsCompatibility(jsonString))
{
await ToFileAsync();
}
}

await ToFileAsync();
Expand Down Expand Up @@ -193,5 +208,62 @@ public void AssertFilePathSet()
throw new NotSupportedException($"{nameof(FilePath)} is not set. Use {nameof(SetFilePath)} to set it.");
}
}

private bool TryEnsureBackwardsCompatibility(string jsonString)
{
try
{
var jsObject = JsonConvert.DeserializeObject<JObject>(jsonString);
bool saveIt = false;

var mainNetBitcoinCoreHost = jsObject.Value<string>("MainNetBitcoinCoreHost");
var mainNetBitcoinCorePort = jsObject.Value<int?>("MainNetBitcoinCorePort");
var testNetBitcoinCoreHost = jsObject.Value<string>("TestNetBitcoinCoreHost");
var testNetBitcoinCorePort = jsObject.Value<int?>("TestNetBitcoinCorePort");
var regTestBitcoinCoreHost = jsObject.Value<string>("RegTestBitcoinCoreHost");
var regTestBitcoinCorePort = jsObject.Value<int?>("RegTestBitcoinCorePort");

if (mainNetBitcoinCoreHost != null)
{
int port = mainNetBitcoinCorePort ?? Constants.DefaultMainNetBitcoinP2pPort;

if (EndPointParser.TryParse(mainNetBitcoinCoreHost, port, out EndPoint ep))
{
MainNetBitcoinP2pEndPoint = ep;
saveIt = true;
}
}

if (testNetBitcoinCoreHost != null)
{
int port = testNetBitcoinCorePort ?? Constants.DefaultTestNetBitcoinP2pPort;

if (EndPointParser.TryParse(testNetBitcoinCoreHost, port, out EndPoint ep))
{
TestNetBitcoinP2pEndPoint = ep;
saveIt = true;
}
}

if (regTestBitcoinCoreHost != null)
{
int port = regTestBitcoinCorePort ?? Constants.DefaultRegTestBitcoinP2pPort;

if (EndPointParser.TryParse(regTestBitcoinCoreHost, port, out EndPoint ep))
{
RegTestBitcoinP2pEndPoint = ep;
saveIt = true;
}
}

return saveIt;
}
catch (Exception ex)
{
Logger.LogWarning<Config>("Backwards compatibility couldn't be ensured.");
Logger.LogInfo<Config>(ex);
return false;
}
}
}
}
2 changes: 1 addition & 1 deletion WalletWasabi.Backend/Global.cs
Expand Up @@ -52,7 +52,7 @@ public async Task InitializeAsync(Config config, CcjRoundConfig roundConfig, RPC
await AssertRpcNodeFullyInitializedAsync();

// Make sure P2P works.
await InitializeP2pAsync(config.Network, config.GetBitcoinCoreEndPoint());
await InitializeP2pAsync(config.Network, config.GetBitcoinP2pEndPoint());

// Initialize index building
var indexBuilderServiceDir = Path.Combine(DataDir, nameof(IndexBuilderService));
Expand Down
5 changes: 4 additions & 1 deletion WalletWasabi.Backend/InitConfigStartupTask.cs
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using WalletWasabi.Logging;
Expand Down Expand Up @@ -43,8 +44,10 @@ public async Task ExecuteAsync(CancellationToken cancellationToken)
await roundConfig.LoadOrCreateDefaultFileAsync();
Logger.LogInfo<CcjRoundConfig>("RoundConfig is successfully initialized.");

string host = config.GetBitcoinCoreRpcEndPoint().ToString(config.Network.RPCPort);
var rpc = new RPCClient(
credentials: RPCCredentialString.Parse(config.BitcoinRpcConnectionString),
authenticationString: config.BitcoinRpcConnectionString,
hostOrUri: host,
network: config.Network);

await Global.InitializeAsync(config, roundConfig, rpc);
Expand Down
34 changes: 34 additions & 0 deletions WalletWasabi.Gui/Behaviors/CommandOnLostFocusBehavior.cs
@@ -0,0 +1,34 @@
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using System;
using System.Collections.Generic;
using System.Reactive.Disposables;
using System.Text;

namespace WalletWasabi.Gui.Behaviors
{
internal class CommandOnLostFocusBehavior : CommandBasedBehavior<Control>
{
private CompositeDisposable Disposables { get; set; }

protected override void OnAttached()
{
Disposables = new CompositeDisposable();

base.OnAttached();

Disposables.Add(AssociatedObject.AddHandler(InputElement.LostFocusEvent, (sender, e) =>
{
e.Handled = ExecuteCommand();
}));
}

protected override void OnDetaching()
{
base.OnDetaching();

Disposables?.Dispose();
}
}
}

0 comments on commit 572f2cd

Please sign in to comment.