public ProgramTest() { this.apiSettings = new NodeHostSettings(NodeSettings.Default(KnownNetworks.TestNet)) { UseHttps = true }; this.certificateToUse = new X509Certificate2(); this.certificateStore = Substitute.For <ICertificateStore>(); this.webHostBuilder = Substitute.For <IWebHostBuilder>(); }
public void GivenStratisTestnet_ThenUseTheCorrectPort() { // Arrange. NodeSettings nodeSettings = NodeSettings.Default(KnownNetworks.StratisTest); // Act. NodeHostSettings settings = FullNodeSetup(nodeSettings); // Assert. Assert.Equal(KnownNetworks.StratisTest.DefaultAPIPort, settings.ApiPort); }
public void GivenBitcoinMain_ThenUseTheCorrectPort() { // Arrange. NodeSettings nodeSettings = NodeSettings.Default(KnownNetworks.Main); // Act. NodeHostSettings settings = FullNodeSetup(nodeSettings); // Assert. Assert.Equal(KnownNetworks.Main.DefaultAPIPort, settings.ApiPort); }
public ApiKeyAuthenticationHandler( NodeHostSettings nodeSettings, IOptionsMonitor <ApiKeyAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IGetApiKeyQuery getApiKeyQuery) : base(options, logger, encoder, clock) { this.nodeSettings = nodeSettings; this.getApiKeyQuery = getApiKeyQuery ?? throw new ArgumentNullException(nameof(getApiKeyQuery)); }
public void GivenCertificateFilePath_ThenUsesTheCorrectFileName() { // Arrange. var certificateFileName = @"abcd/someCertificate.pfx"; var nodeSettings = new NodeSettings(KnownNetworks.TestNet, args: new[] { $"-certificatefilepath={certificateFileName}" }); // Act. NodeHostSettings settings = FullNodeSetup(nodeSettings); // Assert. settings.HttpsCertificateFilePath.Should().Be(certificateFileName); }
public void GivenUseHttps_ThenUsesTheCorrectProtocol(bool useHttps, string expectedProtocolPrefix) { // Arrange. var nodeSettings = new NodeSettings(KnownNetworks.TestNet, args: new[] { $"-usehttps={useHttps}", "-certificatefilepath=nonNullValue" }); // Act. NodeHostSettings settings = FullNodeSetup(nodeSettings); // Assert. settings.UseHttps.Should().Be(useHttps); settings.ApiUri.ToString().Should().StartWith(expectedProtocolPrefix); }
public void GivenApiPortIsProvided_ThenPortIsUsedWithDefaultApiUri() { // Arrange. int customPort = 55555; var nodeSettings = new NodeSettings(this.Network, args: new[] { $"-apiport={customPort}" }); // Act. NodeHostSettings settings = FullNodeSetup(nodeSettings); // Assert. Assert.Equal(customPort, settings.ApiPort); Assert.Equal(new Uri($"{NodeHostSettings.DefaultApiHost}:{customPort}"), settings.ApiUri); }
public void GivenNoApiSettingsAreProvided_AndOnBitcoinNetwork_ThenDefaultSettingAreUsed() { // Arrange. Network network = KnownNetworks.Main; var nodeSettings = new NodeSettings(network); // Act. NodeHostSettings settings = FullNodeSetup(nodeSettings); // Assert. Assert.Equal(network.DefaultAPIPort, settings.ApiPort); Assert.Equal(new Uri($"{NodeHostSettings.DefaultApiHost}:{network.DefaultAPIPort}"), settings.ApiUri); }
private static NodeConfigurationData LoadConfigurationData(INodeRuntime runtime, NodeHostSettings settings) { Debug.Indent(); Debug.Print("Create Node Config Loader of type '{0}'", settings.ConfigurationLoader); var configurationLoader = runtime.CreateObject<IConfigurationLoader>(settings.ConfigurationLoader); Debug.Print("Load Node Configuration from '{0}'", settings.ConfigLocations); var result = configurationLoader.Load(settings.ConfigLocations.First()); Debug.Unindent(); return result; }
public void GivenApiUriIsProvided_AndGivenBitcoinNetwork_ThenApiUriIsUsedWithDefaultBitcoinApiPort() { // Arrange. string customApiUri = "http://0.0.0.0"; Network network = KnownNetworks.Main; var nodeSettings = new NodeSettings(network, args: new[] { $"-apiuri={customApiUri}" }); // Act. NodeHostSettings settings = FullNodeSetup(nodeSettings); // Assert. Assert.Equal(network.DefaultAPIPort, settings.ApiPort); Assert.Equal(new Uri($"{customApiUri}:{network.DefaultAPIPort}"), settings.ApiUri); }
public void NodeSettings_CanOverrideOnlyApiPort() { const int apiport = 12345; var nodeSettings = new NodeSettings(new BitcoinRegTest(), args: new[] { $"-apiport={apiport}" }); var apiSettings = new NodeHostSettings(nodeSettings); var rpcSettings = new RpcSettings(nodeSettings); var configurationManagerSettings = new ConnectionManagerSettings(nodeSettings); Assert.Equal(apiport, apiSettings.ApiPort); Assert.Equal(nodeSettings.Network.DefaultRPCPort, rpcSettings.RPCPort); Assert.Equal(nodeSettings.Network.DefaultPort, configurationManagerSettings.Port); }
public void GivenApiUriIncludingPortIsProvided_ThenUseThePassedApiUri() { // Arrange. int customPort = 5522; string customApiUri = $"http://0.0.0.0:{customPort}"; Network network = KnownNetworks.Main; var nodeSettings = new NodeSettings(network, args: new[] { $"-apiuri={customApiUri}" }); // Act. NodeHostSettings settings = FullNodeSetup(nodeSettings); // Assert. Assert.Equal(customPort, settings.ApiPort); Assert.Equal(new Uri($"{customApiUri}"), settings.ApiUri); }
public void GivenNoApiSettingsAreProvided_AndOnStratisNetwork_ThenDefaultSettingAreUsed() { // Arrange. Network network = KnownNetworks.StratisMain; var nodeSettings = new NodeSettings(network); // Act. NodeHostSettings settings = FullNodeSetup(nodeSettings); // Assert. Assert.Equal(network.DefaultAPIPort, settings.ApiPort); Assert.Equal(new Uri($"{NodeHostSettings.DefaultApiHost}:{network.DefaultAPIPort}"), settings.ApiUri); settings.HttpsCertificateFilePath.Should().BeNull(); settings.UseHttps.Should().BeFalse(); }
public void NodeSettings_CanOverrideAllPorts() { // On MacOS ports below 1024 are privileged, and cannot be bound to by anyone other than root. const int port = 1024 + 123; const int rpcPort = 1024 + 456; const int apiPort = 1024 + 567; var args = new[] { $"-port={port.ToString()}", $"-rpcport={rpcPort.ToString()}", $"-apiport={apiPort.ToString()}" }; var nodeSettings = new NodeSettings(new BitcoinRegTest(), args: args); var apiSettings = new NodeHostSettings(nodeSettings); var rpcSettings = new RpcSettings(nodeSettings); var configurationManagerSettings = new ConnectionManagerSettings(nodeSettings); Assert.Equal(apiPort, apiSettings.ApiPort); Assert.Equal(rpcPort, rpcSettings.RPCPort); Assert.Equal(port, configurationManagerSettings.Port); }
/// <summary> /// The expected sequence of arguments: /// <list> /// <item> /// 1, [network-name] [options] [rpc-command] [rpc-params]. /// </item> /// <item> /// 2, [network-name] [options] [api-controller "/" api-command] [api-params]. /// </item> /// </list> /// </summary> public static void Main(string[] args) { try { // Preprocess the command line arguments var argList = new List <string>(args); string networkName = null; if (argList.Any()) { networkName = argList.First(); argList.RemoveAt(0); } var optionList = new List <string>(); while ((argList.Any()) && (argList[0].StartsWith('-'))) { optionList.Add(argList[0]); argList.RemoveAt(0); } string method = ""; if (argList.Any()) { method = argList.First().ToUpper(); if (method == "GET" || method == "POST" || method == "DELETE") { argList.RemoveAt(0); } else { method = ""; } } string command = string.Empty; if (argList.Any()) { command = argList.First(); argList.RemoveAt(0); } var commandArgList = new List <string>(argList); // Display help if required. if (optionList.Contains("-help") || optionList.Contains("--help") || string.IsNullOrWhiteSpace(command)) { var builder = new StringBuilder(); builder.AppendLine("Usage:"); builder.AppendLine(" dotnet run <Blockcore.Cli/Blockcore.Cli.dll> [network-name] [options] [method] <command> [arguments]"); builder.AppendLine(); builder.AppendLine("Command line arguments:"); builder.AppendLine(); builder.AppendLine("[network-name] Name of the network - e.g. \"stratis\" or \"bitcoin\"."); builder.AppendLine("[options] Options for the CLI (optional) - e.g. -help, -rpcuser, see below."); builder.AppendLine("[method] Method to use for API calls - 'GET', 'POST' or 'DELETE'."); builder.AppendLine("[command] Name of RPC method or API <controller>/<method>."); builder.AppendLine("[arguments] Argument by position (RPC) or Name = Value pairs (API) (optional)."); builder.AppendLine(); builder.AppendLine("Options:"); builder.AppendLine("-help This help message"); builder.AppendLine("-rpcconnect=<ip> Send commands to node running on <ip> (default: 127.0.0.1)"); builder.AppendLine("-rpcport=<port> Connect to JSON-RPC on <port> (default for Stratis: 26174 or default for Bitcoin: 8332)"); builder.AppendLine("-rpcuser=<user> Username for JSON-RPC connections"); builder.AppendLine("-rpcpassword=<pw> Password for JSON-RPC connections"); builder.AppendLine(); builder.AppendLine("Examples:"); builder.AppendLine(); builder.AppendLine("dotnet run stratis -testnet GET Wallet/history WalletName=testwallet - Lists all the historical transactions of the wallet called 'testwallet' on the stratis test network."); builder.AppendLine("dotnet run stratis -rpcuser=stratistestuser -rpcpassword=stratistestpassword -rpcconnect=127.0.0.3 -rpcport=26174 getinfo - Displays general information about the Stratis node on the 127.0.0.3:26174, authenticating with the RPC specified user."); builder.AppendLine("dotnet run bitcoin -rpcuser=btctestuser -rpcpassword=btctestpass getbalance - Displays the current balance of the opened wallet on the 127.0.0.1:8332 node, authenticating with the RPC specified user."); Console.WriteLine(builder); return; } // Determine API port. NetworksSelector networksSelector = null; networksSelector = Blockcore.Networks.Bitcoin.Networks.Bitcoin; // API calls require both the contoller name and the method name separated by "/". // If this is not an API call then assume it is an RPC call. if (!command.Contains("/")) { // Process RPC call. try { string[] options = optionList.Append("-server").ToArray(); var nodeSettings = new NodeSettings(networksSelector: networksSelector, args: options) { MinProtocolVersion = ProtocolVersion.POS_PROTOCOL_VERSION }; var rpcSettings = new RpcSettings(nodeSettings); Network network = nodeSettings.Network; // Find the binding to 127.0.0.1 or the first available. The logic in RPC settings ensures there will be at least 1. System.Net.IPEndPoint nodeEndPoint = rpcSettings.Bind.FirstOrDefault(b => b.Address.ToString() == "127.0.0.1") ?? rpcSettings.Bind[0]; var rpcUri = new Uri($"http://{nodeEndPoint}"); // Process the command line RPC arguments // TODO: this should probably be moved to the NodeSettings.FromArguments if (options.GetValueOf("-rpcbind") != null) { rpcUri = new Uri($"http://{options.GetValueOf("-rpcbind")}"); } if (options.GetValueOf("-rpcconnect") != null || options.GetValueOf("-rpcport") != null) { string rpcAddress = options.GetValueOf("-rpcconnect") ?? "127.0.0.1"; int rpcPort = rpcSettings.RPCPort; int.TryParse(options.GetValueOf("-rpcport"), out rpcPort); rpcUri = new Uri($"http://{rpcAddress}:{rpcPort}"); } rpcSettings.RpcUser = options.GetValueOf("-rpcuser") ?? rpcSettings.RpcUser; rpcSettings.RpcPassword = options.GetValueOf("-rpcpassword") ?? rpcSettings.RpcPassword; Console.WriteLine($"Connecting to the following RPC node: http://{rpcSettings.RpcUser}:{rpcSettings.RpcPassword}@{rpcUri.Authority}."); // Initialize the RPC client with the configured or passed userid, password and endpoint. var rpcClient = new RPCClient($"{rpcSettings.RpcUser}:{rpcSettings.RpcPassword}", rpcUri, network); // Execute the RPC command Console.WriteLine($"Sending RPC command '{command} {string.Join(" ", commandArgList)}' to '{rpcUri}'."); RPCResponse response = rpcClient.SendCommand(command, commandArgList.ToArray()); // Return the result as a string to the console. Console.WriteLine(response.ResultString); } catch (Exception err) { Console.WriteLine(err.Message); } } else { // Process API call. string[] options = optionList.ToArray(); var nodeSettings = new NodeSettings(networksSelector: networksSelector, args: options); var apiSettings = new NodeHostSettings(nodeSettings); string url = $"http://localhost:{apiSettings.ApiPort}/api".AppendPathSegment(command); object commandArgObj = GetAnonymousObjectFromDictionary(commandArgList .Select(a => a.Split('=')) .ToDictionary(a => a[0], a => a[1])); HttpResponseMessage httpResponse; switch (method) { case "POST": httpResponse = CallApiPost(url, commandArgObj); break; case "DELETE": httpResponse = CallApiDelete(url, commandArgObj); break; default: httpResponse = CallApiGet(url, commandArgObj); break; } var response = httpResponse.Content.ReadAsStringAsync().GetAwaiter().GetResult(); // Format and return the result as a string to the console. Console.WriteLine(JsonConvert.SerializeObject(JsonConvert.DeserializeObject <object>(response), Formatting.Indented)); } } catch (Exception err) { // Report any errors to the console. Console.WriteLine(ExceptionToString(err)); } }