< Summary - Combined Code Coverage

Information
Class: Program
Assembly: NLightning.Node
File(s): /home/runner/work/nlightning/nlightning/src/NLightning.Node/Program.cs
Tag: 38_17925369700
Line coverage
0%
Covered lines: 0
Uncovered lines: 74
Coverable lines: 74
Total lines: 159
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 24
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
<Main>$()0%420200%
ReportDaemonStatus()0%2040%

File(s)

/home/runner/work/nlightning/nlightning/src/NLightning.Node/Program.cs

#LineLine coverage
 1using Microsoft.Extensions.Hosting;
 2using NBitcoin;
 3using NLightning.Domain.Protocol.ValueObjects;
 4using NLightning.Infrastructure.Bitcoin.Managers;
 5using NLightning.Node.Extensions;
 6using NLightning.Node.Helpers;
 7using NLightning.Node.Utilities;
 8using Serilog;
 9
 10try
 11{
 12    // Bootstrap logger for startup messages
 013    Log.Logger = new LoggerConfiguration()
 014                .WriteTo.Console()
 015                .CreateBootstrapLogger();
 16
 017    AppDomain.CurrentDomain.UnhandledException += (_, e) =>
 018    {
 019        var exception = (Exception)e.ExceptionObject;
 020        Log.Logger.Error("An unhandled exception occurred: {exception}", exception);
 021    };
 22
 23    // Get network for the PID file path
 024    var network = CommandLineHelper.GetNetwork(args);
 025    var pidFilePath = DaemonUtils.GetPidFilePath(network);
 26
 27    // Check for the stop command
 028    if (CommandLineHelper.IsStopRequested(args))
 29    {
 030        var stopped = DaemonUtils.StopDaemon(pidFilePath, Log.Logger);
 031        return stopped ? 0 : 1;
 32    }
 33
 34    // Check for status command
 035    if (CommandLineHelper.IsStatusRequested(args))
 36    {
 037        ReportDaemonStatus(pidFilePath);
 038        return 0;
 39    }
 40
 41    // Check if help is requested
 042    if (CommandLineHelper.IsHelpRequested(args))
 43    {
 044        CommandLineHelper.ShowUsage();
 045        return 0;
 46    }
 47
 48    // Read the configuration file to check for daemon setting
 049    var initialConfig = NodeConfigurationExtensions.ReadInitialConfiguration(args);
 50
 051    string? password = null;
 52
 53    // Try to get password from args or prompt
 054    if (args.Contains("--password"))
 55    {
 056        var idx = Array.IndexOf(args, "--password");
 057        if (idx >= 0 && idx + 1 < args.Length)
 058            password = args[idx + 1];
 59    }
 60
 061    if (string.IsNullOrWhiteSpace(password))
 62    {
 063        password = ConsoleUtils.ReadPassword("Enter password for key encryption: ");
 64    }
 65
 066    if (string.IsNullOrWhiteSpace(password))
 67    {
 068        Log.Error("Password cannot be empty.");
 069        return 1;
 70    }
 71
 72    SecureKeyManager keyManager;
 073    var keyFilePath = SecureKeyManager.GetKeyFilePath(network);
 074    if (!File.Exists(keyFilePath))
 75    {
 76        // Creates new key
 077        var key = new Key();
 078        keyManager = new SecureKeyManager(key.ToBytes(), new BitcoinNetwork(network), keyFilePath);
 079        keyManager.SaveToFile(password);
 080        Console.WriteLine($"New key created and saved to {keyFilePath}");
 81    }
 82    else
 83    {
 84        // Load the existing key
 085        keyManager = SecureKeyManager.FromFilePath(keyFilePath, new BitcoinNetwork(network), password);
 086        Console.WriteLine($"Loaded key from {keyFilePath}");
 87    }
 88
 89    // Start as a daemon if requested
 090    if (DaemonUtils.StartDaemonIfRequested(args, initialConfig, pidFilePath, Log.Logger))
 91    {
 92        // The parent process exits immediately after starting the daemon
 093        return 0;
 94    }
 95
 096    Log.Information("Starting NLTG...");
 97
 98    // Create and run host
 099    var host = Host.CreateDefaultBuilder(args)
 0100                   .ConfigureNltg(initialConfig)
 0101                   .ConfigureNltgServices(keyManager)
 0102                   .Build();
 103
 104    // Run migrations if configured
 0105    await host.MigrateDatabaseIfConfiguredAsync();
 106
 107    // Run the host
 0108    await host.RunAsync();
 109
 0110    return 0;
 111}
 112catch (Exception e)
 113{
 0114    Log.Fatal(e, "Application terminated unexpectedly");
 0115    return 1;
 116}
 117finally
 118{
 0119    Log.CloseAndFlush();
 120}
 121
 122static void ReportDaemonStatus(string pidFilePath)
 123{
 124    try
 125    {
 0126        if (!File.Exists(pidFilePath))
 127        {
 0128            Console.WriteLine("NLTG daemon is not running");
 0129            return;
 130        }
 131
 0132        var pidText = File.ReadAllText(pidFilePath).Trim();
 0133        if (!int.TryParse(pidText, out var pid))
 134        {
 0135            Console.WriteLine("Invalid PID in file, daemon may not be running");
 0136            return;
 137        }
 138
 139        try
 140        {
 0141            var process = System.Diagnostics.Process.GetProcessById(pid);
 0142            var runTime = DateTime.Now - process.StartTime;
 143
 0144            Console.WriteLine("NLTG daemon is running");
 0145            Console.WriteLine($"PID: {pid}");
 0146            Console.WriteLine($"Started: {process.StartTime}");
 0147            Console.WriteLine($"Uptime: {runTime.Days}d {runTime.Hours}h {runTime.Minutes}m");
 0148            Console.WriteLine($"Memory: {process.WorkingSet64 / (1024 * 1024)} MB");
 0149        }
 0150        catch (ArgumentException)
 151        {
 0152            Console.WriteLine("NLTG daemon is not running (stale PID file)");
 0153        }
 0154    }
 0155    catch (Exception e)
 156    {
 0157        Console.WriteLine($"Error checking daemon status: {e.Message}");
 0158    }
 0159}

Methods/Properties

<Main>$()
ReportDaemonStatus()