public static async Task <CoreNode> CreateAsync(CoreNodeParams coreNodeParams, CancellationToken cancel) { Guard.NotNull(nameof(coreNodeParams), coreNodeParams); using (BenchmarkLogger.Measure()) { var coreNode = new CoreNode(); coreNode.HostedServices = coreNodeParams.HostedServices; coreNode.DataDir = coreNodeParams.DataDir; coreNode.Network = coreNodeParams.Network; coreNode.MempoolService = coreNodeParams.MempoolService; var configPath = Path.Combine(coreNode.DataDir, "bitcoin.conf"); coreNode.Config = new CoreConfig(); if (File.Exists(configPath)) { var configString = await File.ReadAllTextAsync(configPath).ConfigureAwait(false); coreNode.Config.AddOrUpdate(configString); // Bitcoin Core considers the last entry to be valid. } cancel.ThrowIfCancellationRequested(); var configTranslator = new CoreConfigTranslator(coreNode.Config, coreNode.Network); string rpcUser = configTranslator.TryGetRpcUser(); string rpcPassword = configTranslator.TryGetRpcPassword(); string rpcCookieFilePath = configTranslator.TryGetRpcCookieFile(); string rpcHost = configTranslator.TryGetRpcBind(); int? rpcPort = configTranslator.TryGetRpcPort(); WhiteBind whiteBind = configTranslator.TryGetWhiteBind(); string authString; bool cookieAuth = rpcCookieFilePath is { }; if (cookieAuth) { authString = $"cookiefile={rpcCookieFilePath}"; } else { rpcUser ??= Encoders.Hex.EncodeData(RandomUtils.GetBytes(21)); rpcPassword ??= Encoders.Hex.EncodeData(RandomUtils.GetBytes(21)); authString = $"{rpcUser}:{rpcPassword}"; } coreNode.P2pEndPoint = whiteBind?.EndPoint ?? coreNodeParams.P2pEndPointStrategy.EndPoint; rpcHost ??= coreNodeParams.RpcEndPointStrategy.EndPoint.GetHostOrDefault(); rpcPort ??= coreNodeParams.RpcEndPointStrategy.EndPoint.GetPortOrDefault(); EndPointParser.TryParse($"{rpcHost}:{rpcPort}", coreNode.Network.RPCPort, out EndPoint rpce); coreNode.RpcEndPoint = rpce; var rpcClient = new RPCClient( $"{authString}", coreNode.RpcEndPoint.ToString(coreNode.Network.DefaultPort), coreNode.Network); coreNode.RpcClient = new CachedRpcClient(rpcClient, new MemoryCache(new MemoryCacheOptions { SizeLimit = 1_000 }));
public void TryGetWhiteBindTests() { var config = new CoreConfig(); var translator = new CoreConfigTranslator(config, Network.Main); Assert.Null(translator.TryGetWhiteBind()); config.AddOrUpdate("whitebind"); Assert.Null(translator.TryGetWhiteBind()); config.AddOrUpdate("main.whitebind=127.0.0.1:18444"); WhiteBind?whiteBind = translator.TryGetWhiteBind(); var ipEndPoint = whiteBind.EndPoint as IPEndPoint; Assert.Equal(IPAddress.Loopback, ipEndPoint.Address); Assert.Equal(18444, ipEndPoint.Port); Assert.Equal("", whiteBind.Permissions); config.AddOrUpdate("whitebind=127.0.0.1:0"); whiteBind = translator.TryGetWhiteBind(); ipEndPoint = whiteBind.EndPoint as IPEndPoint; Assert.Equal(IPAddress.Loopback, ipEndPoint.Address); Assert.Equal(0, ipEndPoint.Port); Assert.Equal("", whiteBind.Permissions); config.AddOrUpdate("whitebind=127.0.0.1"); whiteBind = translator.TryGetWhiteBind(); ipEndPoint = whiteBind.EndPoint as IPEndPoint; Assert.Equal(IPAddress.Loopback, ipEndPoint.Address); // Default port. Assert.Equal(8333, ipEndPoint.Port); Assert.Equal("", whiteBind.Permissions); config.AddOrUpdate("[email protected]"); whiteBind = translator.TryGetWhiteBind(); ipEndPoint = whiteBind.EndPoint as IPEndPoint; Assert.Equal(IPAddress.Loopback, ipEndPoint.Address); Assert.Equal(8333, ipEndPoint.Port); Assert.Equal("foo", whiteBind.Permissions); config.AddOrUpdate("whitebind=foo,[email protected]"); whiteBind = translator.TryGetWhiteBind(); ipEndPoint = whiteBind.EndPoint as IPEndPoint; Assert.Equal(IPAddress.Loopback, ipEndPoint.Address); Assert.Equal(8333, ipEndPoint.Port); Assert.Equal("foo,boo", whiteBind.Permissions); config.AddOrUpdate("main.whitebind=@@@"); Assert.Null(translator.TryGetWhiteBind()); }
public void TryGetRpcPortTests() { var config = new CoreConfig(); var translator = new CoreConfigTranslator(config, Network.Main); Assert.Null(translator.TryGetRpcPort()); config.AddOrUpdate("rpcport"); Assert.Null(translator.TryGetRpcPort()); config.AddOrUpdate("main.rpcport=1"); Assert.Equal((ushort)1, translator.TryGetRpcPort()); config.AddOrUpdate("rpcport=2"); Assert.Equal((ushort)2, translator.TryGetRpcPort()); config.AddOrUpdate("main.rpcport=foo"); Assert.Null(translator.TryGetRpcPort()); }
public void TryGetRpcUserTests() { var config = new CoreConfig(); var translatorMain = new CoreConfigTranslator(config, Network.Main); var translatorTest = new CoreConfigTranslator(config, Network.TestNet); var translatorReg = new CoreConfigTranslator(config, Network.RegTest); Assert.Null(translatorMain.TryGetRpcUser()); Assert.Null(translatorTest.TryGetRpcUser()); Assert.Null(translatorReg.TryGetRpcUser()); config.AddOrUpdate("rpcuser"); Assert.Null(translatorMain.TryGetRpcUser()); Assert.Null(translatorTest.TryGetRpcUser()); Assert.Null(translatorReg.TryGetRpcUser()); config.AddOrUpdate("rpcuser=foo"); Assert.Equal("foo", translatorMain.TryGetRpcUser()); Assert.Null(translatorTest.TryGetRpcUser()); Assert.Null(translatorReg.TryGetRpcUser()); config.AddOrUpdate("rpcuser=boo"); Assert.Equal("boo", translatorMain.TryGetRpcUser()); Assert.Null(translatorTest.TryGetRpcUser()); Assert.Null(translatorReg.TryGetRpcUser()); config.AddOrUpdate("main.rpcuser=ooh"); Assert.Equal("ooh", translatorMain.TryGetRpcUser()); Assert.Null(translatorTest.TryGetRpcUser()); Assert.Null(translatorReg.TryGetRpcUser()); config.AddOrUpdate("rpcuser=boo"); Assert.Equal("boo", translatorMain.TryGetRpcUser()); Assert.Null(translatorTest.TryGetRpcUser()); Assert.Null(translatorReg.TryGetRpcUser()); config.AddOrUpdate("test.rpcuser=boo"); Assert.Equal("boo", translatorMain.TryGetRpcUser()); Assert.Equal("boo", translatorTest.TryGetRpcUser()); Assert.Null(translatorReg.TryGetRpcUser()); config.AddOrUpdate("regtest.rpcuser=boo"); Assert.Equal("boo", translatorMain.TryGetRpcUser()); Assert.Equal("boo", translatorTest.TryGetRpcUser()); Assert.Equal("boo", translatorReg.TryGetRpcUser()); }
public static async Task <CoreNode> CreateAsync(CoreNodeParams coreNodeParams, CancellationToken cancel) { Guard.NotNull(nameof(coreNodeParams), coreNodeParams); using (BenchmarkLogger.Measure()) { var coreNode = new CoreNode(); coreNode.HostedServices = coreNodeParams.HostedServices; coreNode.DataDir = coreNodeParams.DataDir; coreNode.Network = coreNodeParams.Network; coreNode.MempoolService = coreNodeParams.MempoolService; var configPath = Path.Combine(coreNode.DataDir, "bitcoin.conf"); coreNode.Config = new CoreConfig(); if (File.Exists(configPath)) { var configString = await File.ReadAllTextAsync(configPath).ConfigureAwait(false); coreNode.Config.AddOrUpdate(configString); // Bitcoin Core considers the last entry to be valid. } cancel.ThrowIfCancellationRequested(); var configTranslator = new CoreConfigTranslator(coreNode.Config, coreNode.Network); string rpcUser = configTranslator.TryGetRpcUser(); string rpcPassword = configTranslator.TryGetRpcPassword(); string rpcCookieFilePath = configTranslator.TryGetRpcCookieFile(); string rpcHost = configTranslator.TryGetRpcBind(); int? rpcPort = configTranslator.TryGetRpcPort(); WhiteBind whiteBind = configTranslator.TryGetWhiteBind(); string authString; bool cookieAuth = rpcCookieFilePath is { }; if (cookieAuth) { authString = $"cookiefile={rpcCookieFilePath}"; } else { rpcUser ??= Encoders.Hex.EncodeData(RandomUtils.GetBytes(21)); rpcPassword ??= Encoders.Hex.EncodeData(RandomUtils.GetBytes(21)); authString = $"{rpcUser}:{rpcPassword}"; } coreNode.P2pEndPoint = whiteBind?.EndPoint ?? coreNodeParams.P2pEndPointStrategy.EndPoint; rpcHost ??= coreNodeParams.RpcEndPointStrategy.EndPoint.GetHostOrDefault(); rpcPort ??= coreNodeParams.RpcEndPointStrategy.EndPoint.GetPortOrDefault(); EndPointParser.TryParse($"{rpcHost}:{rpcPort}", coreNode.Network.RPCPort, out EndPoint rpce); coreNode.RpcEndPoint = rpce; var rpcClient = new RPCClient( $"{authString}", coreNode.RpcEndPoint.ToString(coreNode.Network.DefaultPort), coreNode.Network); coreNode.RpcClient = new CachedRpcClient(rpcClient, coreNodeParams.Cache); if (coreNodeParams.TryRestart) { await coreNode.TryStopAsync(false).ConfigureAwait(false); } cancel.ThrowIfCancellationRequested(); if (coreNodeParams.TryDeleteDataDir) { await IoHelpers.DeleteRecursivelyWithMagicDustAsync(coreNode.DataDir).ConfigureAwait(false); } cancel.ThrowIfCancellationRequested(); IoHelpers.EnsureDirectoryExists(coreNode.DataDir); var configPrefix = NetworkTranslator.GetConfigPrefix(coreNode.Network); var whiteBindPermissionsPart = !string.IsNullOrWhiteSpace(whiteBind?.Permissions) ? $"{whiteBind?.Permissions}@" : ""; var desiredConfigLines = new List <string>() { $"{configPrefix}.server = 1", $"{configPrefix}.listen = 1", $"{configPrefix}.whitebind = {whiteBindPermissionsPart}{coreNode.P2pEndPoint.ToString(coreNode.Network.DefaultPort)}", $"{configPrefix}.rpcbind = {coreNode.RpcEndPoint.GetHostOrDefault()}", $"{configPrefix}.rpcallowip = {IPAddress.Loopback}", $"{configPrefix}.rpcport = {coreNode.RpcEndPoint.GetPortOrDefault()}" }; if (!cookieAuth) { desiredConfigLines.Add($"{configPrefix}.rpcuser = {coreNode.RpcClient.CredentialString.UserPassword.UserName}"); desiredConfigLines.Add($"{configPrefix}.rpcpassword = {coreNode.RpcClient.CredentialString.UserPassword.Password}"); } if (coreNodeParams.TxIndex is { })
public static async Task <CoreNode> CreateAsync(CoreNodeParams coreNodeParams, CancellationToken cancel) { Guard.NotNull(nameof(coreNodeParams), coreNodeParams); using (BenchmarkLogger.Measure()) { var coreNode = new CoreNode { DataDir = coreNodeParams.DataDir, Network = coreNodeParams.Network, MempoolService = coreNodeParams.MempoolService }; var configPath = Path.Combine(coreNode.DataDir, "bitcoin.conf"); coreNode.Config = new CoreConfig(); if (File.Exists(configPath)) { var configString = await File.ReadAllTextAsync(configPath, cancel).ConfigureAwait(false); coreNode.Config.AddOrUpdate(configString); // Bitcoin Core considers the last entry to be valid. } cancel.ThrowIfCancellationRequested(); var configTranslator = new CoreConfigTranslator(coreNode.Config, coreNode.Network); string? rpcUser = configTranslator.TryGetRpcUser(); string? rpcPassword = configTranslator.TryGetRpcPassword(); string? rpcCookieFilePath = configTranslator.TryGetRpcCookieFile(); string? rpcHost = configTranslator.TryGetRpcBind(); int? rpcPort = configTranslator.TryGetRpcPort(); WhiteBind?whiteBind = configTranslator.TryGetWhiteBind(); string authString; bool cookieAuth = rpcCookieFilePath is not null; if (cookieAuth) { authString = $"cookiefile={rpcCookieFilePath}"; } else { rpcUser ??= Encoders.Hex.EncodeData(RandomUtils.GetBytes(21)); rpcPassword ??= Encoders.Hex.EncodeData(RandomUtils.GetBytes(21)); authString = $"{rpcUser}:{rpcPassword}"; } coreNode.P2pEndPoint = whiteBind?.EndPoint ?? coreNodeParams.P2pEndPointStrategy.EndPoint; if (rpcHost is null) { coreNodeParams.RpcEndPointStrategy.EndPoint.TryGetHost(out rpcHost); } if (rpcPort is null) { coreNodeParams.RpcEndPointStrategy.EndPoint.TryGetPort(out rpcPort); } if (!EndPointParser.TryParse($"{rpcHost}:{rpcPort}", coreNode.Network.RPCPort, out EndPoint? rpce)) { throw new InvalidOperationException($"Failed to get RPC endpoint on {rpcHost}:{rpcPort}."); } coreNode.RpcEndPoint = rpce; var rpcClient = new RPCClient( $"{authString}", coreNode.RpcEndPoint.ToString(coreNode.Network.DefaultPort), coreNode.Network); coreNode.RpcClient = new CachedRpcClient(rpcClient, coreNodeParams.Cache); if (coreNodeParams.TryRestart) { await coreNode.TryStopAsync(false).ConfigureAwait(false); } cancel.ThrowIfCancellationRequested(); if (coreNodeParams.TryDeleteDataDir) { await IoHelpers.TryDeleteDirectoryAsync(coreNode.DataDir).ConfigureAwait(false); } cancel.ThrowIfCancellationRequested(); IoHelpers.EnsureDirectoryExists(coreNode.DataDir); var configPrefix = NetworkTranslator.GetConfigPrefix(coreNode.Network); var whiteBindPermissionsPart = !string.IsNullOrWhiteSpace(whiteBind?.Permissions) ? $"{whiteBind?.Permissions}@" : ""; if (!coreNode.RpcEndPoint.TryGetHost(out string?rpcBindParameter) || !coreNode.RpcEndPoint.TryGetPort(out int?rpcPortParameter)) { throw new ArgumentException("Endpoint type is not supported.", nameof(coreNode.RpcEndPoint)); } var desiredConfigLines = new List <string>() { $"{configPrefix}.server = 1", $"{configPrefix}.listen = 1", $"{configPrefix}.daemon = 0", // https://github.com/zkSNACKs/WalletWasabi/issues/3588 $"{configPrefix}.whitebind = {whiteBindPermissionsPart}{coreNode.P2pEndPoint.ToString(coreNode.Network.DefaultPort)}", $"{configPrefix}.rpcbind = {rpcBindParameter}", $"{configPrefix}.rpcallowip = {IPAddress.Loopback}", $"{configPrefix}.rpcport = {rpcPortParameter}" }; if (!cookieAuth) { desiredConfigLines.Add($"{configPrefix}.rpcuser = {coreNode.RpcClient.CredentialString.UserPassword.UserName}"); desiredConfigLines.Add($"{configPrefix}.rpcpassword = {coreNode.RpcClient.CredentialString.UserPassword.Password}"); } if (coreNodeParams.TxIndex is { })