public PeerManagerProvider(
     INBXplorerClientProvider nbXplorerClientProvider,
     NRustLightningNetworkProvider networkProvider,
     IKeysRepository keysRepository,
     ILoggerFactory loggerFactory,
     ChannelProvider channelProvider,
     IOptions <Config> config
     )
 {
     foreach (var n in networkProvider.GetAll())
     {
         var nbx = nbXplorerClientProvider.TryGetClient(n);
         if (nbx != null)
         {
             var b      = new NbXplorerBroadcaster(nbx, loggerFactory.CreateLogger <NbXplorerBroadcaster>());
             var feeEst = new NbXplorerFeeEstimator(loggerFactory.CreateLogger <NbXplorerFeeEstimator>(),
                                                    channelProvider.GetFeeRateChannel(n).Reader);
             var chainWatchInterface =
                 new NbxChainWatchInterface(nbx, loggerFactory.CreateLogger <NbxChainWatchInterface>(), n);
             var peerManSeed = new byte[32];
             RandomUtils.GetBytes(peerManSeed);
             var logger          = new NativeLogger(loggerFactory.CreateLogger <NativeLogger>());
             var nbitcoinNetwork = n.NBitcoinNetwork;
             var conf            = config.Value.RustLightningConfig;
             var peerMan         = PeerManager.Create(peerManSeed.AsSpan(), nbitcoinNetwork, conf, chainWatchInterface, keysRepository, b,
                                                      logger, feeEst, 400000);
             _peerManagers.Add(n.CryptoCode, peerMan);
         }
     }
 }
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            foreach (var n in _networkProvider.GetAll())
            {
                var nbx = _nbXplorerClientProvider.TryGetClient(n);
                if (nbx != null)
                {
                    var b      = new NbXplorerBroadcaster(nbx, _loggerFactory.CreateLogger <NbXplorerBroadcaster>(), _eventAggregator);
                    var feeEst = new NbXplorerFeeEstimator(_loggerFactory.CreateLogger <NbXplorerFeeEstimator>(),
                                                           _channelProvider.GetFeeRateChannel(n).Reader);
                    var chainWatchInterface =
                        new NbxChainWatchInterface(nbx, _loggerFactory.CreateLogger <NbxChainWatchInterface>(), n);
                    var conf   = _config.Value.RustLightningConfig;
                    var logger = new NativeLogger(_loggerFactory.CreateLogger <NativeLogger>());
                    var repo   = _repositoryProvider.GetRepository(n);

                    uint currentBlockHeight;
                    int  tried0 = 0;
retry0:
                    try
                    {
                        currentBlockHeight = (uint)await nbx.RPCClient.GetBlockCountAsync();
                    }
                    catch when(tried0 < 4)
                    {
                        tried0++;
                        await Task.Delay(1000, cancellationToken);

                        goto retry0;
                    }
Beispiel #3
0
        public RepositoryProvider(NRustLightningNetworkProvider networks, IOptions <Config> config, IServiceProvider serviceProvider)
        {
            Config = config.Value;
            var directory = Path.Combine(Config.DataDir, "db");

            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            foreach (var n in networks.GetAll())
            {
                var settings = GetChainSetting(n);
                if (settings != null)
                {
                    var keysRepository = serviceProvider.GetRequiredService <IKeysRepository>();
                    var serializer     = new RepositorySerializer(n);
                    keysRepository.Serializer = serializer;
                    _keysRepositories.Add(n.CryptoCode, keysRepository);
                    _repositorySerializers.Add(n.CryptoCode, serializer);

                    var invoiceRepository = serviceProvider.GetRequiredService <IInvoiceRepository>();
                    _invoiceRepositories.Add(n.CryptoCode, invoiceRepository);
                }
            }
        }
 public ChannelProvider(INBXplorerClientProvider clientProvider, NRustLightningNetworkProvider networkProvider)
 {
     foreach (var n in networkProvider.GetAll())
     {
         var maybeClient = clientProvider.TryGetClient(n.CryptoCode);
         if (maybeClient != null)
         {
             _feeRateChannels.Add(n.CryptoCode, Channel.CreateBounded <FeeRateSet>(50));
         }
     }
 }
Beispiel #5
0
 public DataFlowProvider(INBXplorerClientProvider clientProvider, NRustLightningNetworkProvider networkProvider)
 {
     foreach (var n in networkProvider.GetAll())
     {
         var maybeClient = clientProvider.TryGetClient(n.CryptoCode);
         if (maybeClient != null)
         {
             var inputBuffer = new BufferBlock <FeeRateSet>();
             _feeRateSourceBlock.Add(n.CryptoCode, inputBuffer);
             throw new NotImplementedException();
         }
     }
 }
Beispiel #6
0
 public ChannelProvider(INBXplorerClientProvider clientProvider, NRustLightningNetworkProvider networkProvider)
 {
     foreach (var n in networkProvider.GetAll())
     {
         var maybeClient = clientProvider.TryGetClient(n.CryptoCode);
         if (maybeClient != null)
         {
             _feeRateChannels.Add(n.CryptoCode, Channel.CreateBounded <FeeRateSet>(50));
             _outboundConnectionRequestChannel.Add(n.CryptoCode, Channel.CreateBounded <PeerConnectionString>(1000));
             _spendableOutputDescriptorChannel.Add(n.CryptoCode, Channel.CreateBounded <SpendableOutputDescriptor>(100000));
         }
     }
 }
 public NBXplorerListeners(NRustLightningNetworkProvider networkProvider, INBXplorerClientProvider clientProvider, PeerManagerProvider peerManagerProvider, ILoggerFactory loggerFactory,
                           ChannelProvider channelProvider)
 {
     foreach (var n in networkProvider.GetAll())
     {
         var cli = clientProvider.TryGetClient(n);
         if (cli != null)
         {
             var listener = new NBXplorerListener(cli, peerManagerProvider, loggerFactory.CreateLogger <NBXplorerListener>(), channelProvider.GetFeeRateChannel(n).Writer, n);
             _listeners.TryAdd(n.CryptoCode, listener);
         }
     }
 }
        public NBXplorerClientProvider(IOptions <Config> config, IOptionsMonitor <ChainConfiguration> chainConfig, NRustLightningNetworkProvider networkProvider, IHttpClientFactory httpClientFactory, ILogger <NBXplorerClientProvider> logger)
        {
            _logger = logger;
            foreach (var n in networkProvider.GetAll())
            {
                var chainConf = chainConfig.Get(n.CryptoCode);
                if (!(chainConf is null))
                {
                    var c = new ExplorerClient(n.NbXplorerNetwork, config.Value.NBXplorerUri);
                    if (!string.IsNullOrEmpty(config.Value.NBXCookieFile))
                    {
                        c.SetCookieAuth(config.Value.NBXCookieFile);
                    }
                    c.SetClient(httpClientFactory.CreateClient(nameof(NBXplorerClientProvider)));
                    // check the connection by getting status.
                    // TODO: Prepare HostedService for waiting NBXplorer and bitcoind gets ready?

                    int       sleepMs  = 50;
                    Exception e        = null;
                    int       maxRetry = 6;
                    for (int count = 0; count <= maxRetry; count++)
                    {
                        try
                        {
                            var _ = c.GetStatus();
                            e = null;
                        }
                        catch (Exception ex)
                        {
                            _logger.LogWarning($"Failed to connect to nbxplorer. retrying in {sleepMs} milliseconds...");
                            e = ex;
                            Thread.Sleep(sleepMs);
                            sleepMs *= 2;
                        }
                    }

                    if (e != null)
                    {
                        _logger.LogCritical($"Failed to connect nbxplorer. check your settings.");
                        throw e;
                    }

                    explorerClients.Add(n.CryptoCode, c);
                }
            }

            if (explorerClients.Count == 0)
            {
                throw new NRustLightningException("Found zero valid nbxplorer instance to connect");
            }
        }
Beispiel #9
0
        public RepositoryProvider(NRustLightningNetworkProvider networks, IOptions <Config> config, IServiceProvider serviceProvider)
        {
            Config = config.Value;
            foreach (var n in networks.GetAll())
            {
                var settings = GetChainSetting(n);
                if (settings != null)
                {
                    var keysRepository = serviceProvider.GetRequiredService <IKeysRepository>();
                    var serializer     = new RepositorySerializer(n);
                    keysRepository.Serializer = serializer;
                    _keysRepositories.Add(n.CryptoCode, keysRepository);
                    _repositorySerializers.Add(n.CryptoCode, serializer);

                    var repository = serviceProvider.GetRequiredService <IRepository>();
                    _repos.Add(n.CryptoCode, repository);
                }
            }
        }
Beispiel #10
0
 public RustLightningEventReactors(NRustLightningNetworkProvider networkProvider, INBXplorerClientProvider clientProvider, IServiceProvider serviceProvider, ILoggerFactory loggerFactory)
 {
     foreach (var n in networkProvider.GetAll())
     {
         var cli = clientProvider.TryGetClient(n);
         if (cli != null) // it means we want  to support that chain.
         {
             var reactor = new RustLightningEventReactor(
                 serviceProvider.GetRequiredService <P2PConnectionHandler>(),
                 serviceProvider.GetRequiredService <IPeerManagerProvider>(),
                 serviceProvider.GetRequiredService <IWalletService>(),
                 n,
                 serviceProvider.GetRequiredService <EventAggregator>(),
                 loggerFactory.CreateLogger(nameof(RustLightningEventReactor) + $":{n.CryptoCode}"),
                 serviceProvider.GetRequiredService <IInvoiceRepository>()
                 );
             Reactors.Add(n.CryptoCode, reactor);
         }
     }
 }
 public WorkQueueProcessors(RepositoryProvider repositoryProvider, NRustLightningNetworkProvider networkProvider,
                            IServiceProvider serviceProvider, ILoggerFactory loggerFactory)
 {
     _networkProvider = networkProvider;
     foreach (var n in networkProvider.GetAll())
     {
         var repo = repositoryProvider.TryGetRepository(n);
         if (repo is null)
         {
             continue;
         }
         var p = new WorkQueueProcessor(
             serviceProvider.GetRequiredService <ChannelProvider>(),
             serviceProvider.GetRequiredService <P2PConnectionHandler>(),
             loggerFactory.CreateLogger <WorkQueueProcessor>(),
             serviceProvider.GetRequiredService <PeerManagerProvider>(),
             n,
             serviceProvider.GetRequiredService <IWalletService>(),
             repo
             );
         _processors.Add(n.CryptoCode, p);
     }
 }
        public NBXplorerClientProvider(IOptions <Config> config, IOptionsMonitor <ChainConfiguration> chainConfig, NRustLightningNetworkProvider networkProvider, IHttpClientFactory httpClientFactory, ILogger <NBXplorerClientProvider> logger)
        {
            _logger = logger;
            foreach (var n in networkProvider.GetAll())
            {
                var chainConf = chainConfig.Get(n.CryptoCode);
                if (!(chainConf is null))
                {
                    var c = new ExplorerClient(n.NbXplorerNetwork, config.Value.NBXplorerUri);
                    if (!string.IsNullOrEmpty(config.Value.NBXCookieFile))
                    {
                        c.SetCookieAuth(config.Value.NBXCookieFile);
                    }
                    c.SetClient(httpClientFactory.CreateClient(nameof(NBXplorerClientProvider)));

                    var timeout = new CancellationTokenSource(4000);
                    try
                    {
                        c.WaitServerStarted(timeout.Token);
                        c.GetStatus();
                    }
                    catch (Exception)
                    {
                        _logger.LogError($"Failed to connect to nbxplorer! cryptoCode: {n.CryptoCode} url: {config.Value.NBXplorerUri}. cookiefile: {config.Value.NBXCookieFile}");
                        throw;
                    }

                    explorerClients.Add(n.CryptoCode, c);
                }
            }

            if (explorerClients.Count == 0)
            {
                throw new NRustLightningException("Found zero valid nbxplorer instance to connect");
            }
        }
Beispiel #13
0
        public Config LoadArgs(IConfiguration config, ILogger logger)
        {
            var networkType = config.GetNetworkType();

            logger.LogInformation($"Network type: {networkType}");
            NetworkProvider = new NRustLightningNetworkProvider(networkType);
            var defaultSettings = NRustLightningDefaultSettings.GetDefaultSettings(NetworkProvider.NetworkType);

            DataDir = config.GetOrDefault <string>("datadir", null);
            if (DataDir is null)
            {
                DataDir = Path.GetDirectoryName(defaultSettings.DefaultDataDir);
                if (!Directory.Exists(DataDir))
                {
                    Directory.CreateDirectory(DataDir);
                }
                if (!Directory.Exists(defaultSettings.DefaultDataDir))
                {
                    Directory.CreateDirectory(defaultSettings.DefaultDataDir);
                }
            }

            var nbxConfig     = config.GetSection("nbx");
            var nbxCookieFile =
                nbxConfig.GetOrDefault("cookiefile",
                                       Constants.DefaultNBXplorerCookieFile(NetworkProvider.NetworkType));

            NBXplorerUri = new Uri(nbxConfig.GetOrDefault("rpcurl", Constants.DefaultNBXplorerUri));

            if (!File.Exists(nbxCookieFile))
            {
                logger.LogWarning($"cookie file for nbxplorer does not exist in {nbxCookieFile}" +
                                  " Make sure you are running nbx with --noauth.");
            }

            logger.LogInformation($"nbxplorer url {NBXplorerUri}");
            NBXCookieFile = nbxCookieFile;

            var p2pExternalIp = config.GetOrDefault("externalip", Constants.DefaultP2PExternalIpStr);

            if (IPEndPoint.TryParse(p2pExternalIp, out var ip))
            {
                P2PExternalIp = ip;
            }
            else if (p2pExternalIp.Contains(":"))
            {
                var s = p2pExternalIp.Split(":", StringSplitOptions.RemoveEmptyEntries);
                if (s.Length != 2)
                {
                    throw new ConfigException($"Invalid external ip {p2pExternalIp}");
                }

                if (Int32.TryParse(s[1], out var port))
                {
                    P2PExternalIp = new DnsEndPoint(s[0], port);
                }
                else
                {
                    throw new ConfigException($"Invalid external ip {p2pExternalIp}");
                }
            }
            else
            {
                throw new ConfigException($"Invalid external ip {p2pExternalIp}");
            }

            logger.LogInformation($"Advertising external ip: {P2PExternalIp.ToEndpointString()}");
            logger.LogDebug($"Network: {NetworkProvider.NetworkType.ToString()}");
            var supportedChains = config.GetOrDefault <string>("chains", "BTC")
                                  .Split(',', StringSplitOptions.RemoveEmptyEntries)
                                  .Select(t => t.ToLowerInvariant());
            var validChains = new List <string>();

            foreach (var n in NetworkProvider.GetAll())
            {
                if (supportedChains.Contains(n.CryptoCode))
                {
                    validChains.Add(n.CryptoCode);
                    var chainConfiguration = new ChainConfiguration();
                    chainConfiguration.CryptoCode = n.CryptoCode;
                    var args = RPCArgs.Parse(config, n.NBitcoinNetwork, n.CryptoCode);
                    chainConfiguration.Rpc = args.ConfigureRPCClient(n, logger);
                    if (chainConfiguration.Rpc.Address.Port == n.NBitcoinNetwork.DefaultPort)
                    {
                        logger.LogWarning($"{n.CryptoCode}: It seems that the1 RPC port ({chainConfiguration.Rpc.Address.Port}) is equal to the default P2P port ({n.NBitcoinNetwork.DefaultPort}, this is probably a misconfiguration)");
                    }
                    if ((chainConfiguration.Rpc.CredentialString.CookieFile != null || chainConfiguration.Rpc.CredentialString.UseDefault) && !n.SupportCookieAuthentication)
                    {
                        throw new ConfigException($"Chain {n.CryptoCode} does not support cookie file authentication,\n" +
                                                  $"Please use {n.CryptoCode.ToLowerInvariant()}rpcuser and {n.CryptoCode.ToLowerInvariant()}rpcpassword settings in NRustLightning" +
                                                  $"And configure rpcuser and rpcpassword in the configuration file or in commandline or your node");
                    }
                    ChainConfiguration.Add(chainConfiguration);
                }
            }
            var invalidChains = String.Join(',', supportedChains.Where(s => !validChains.Contains(s)));

            if (!string.IsNullOrEmpty(invalidChains))
            {
                throw new ConfigException($"Invalid chains {invalidChains}");
            }

            config.GetSection("ln").Bind(RustLightningConfig);

            string?seed     = null;
            var    filePath = Path.Join(DataDir, "node_secret");

            if (File.Exists(filePath))
            {
                logger.LogDebug($"reading seed from {filePath}");
                seed = File.ReadAllText(filePath);
            }
            if (seed is null)
            {
                seed = config.GetOrDefault("seed", String.Empty);
            }
            if (String.IsNullOrEmpty(seed))
            {
                logger.LogWarning($"seed not found in {filePath}! You can specify it with --seed option.");
                logger.LogInformation("generating new seed...");
                seed = RandomUtils.GetUInt256().ToString();
            }

            InvoiceDBFilePath = Path.Combine(DataDir, "InvoiceDb");
            if (!Directory.Exists(InvoiceDBFilePath))
            {
                Directory.CreateDirectory(InvoiceDBFilePath);
            }

            var h = new HexEncoder();

            if (!(h.IsValid(seed) && seed.Length == 64))
            {
                throw new NRustLightningException($"Seed corrupted {seed}");
            }
            File.WriteAllText(filePath, seed);
            GetSeed = async() => {
                var s = await File.ReadAllTextAsync(filePath);

                return(h.DecodeData(s));
            };

            PaymentTimeoutSec = config.GetOrDefault("paymenttimeout", Constants.DefaultPaymentTimeoutSec);

            DBCacheMB = config.GetOrDefault("dbcache", Constants.DefaultDBCacheMB);
            return(this);
        }
Beispiel #14
0
 public IEnumerable <ExplorerClient> GetAll()
 {
     return(_networkProvider.GetAll().Select(n => new ExplorerClient(n.NbXplorerNetwork)));
 }
Beispiel #15
0
        public Config LoadArgs(IConfiguration config, ILogger?logger)
        {
            _logger = logger;
            var networkType = config.GetNetworkType();

            logger?.LogInformation($"Network type: {networkType}");
            NetworkProvider = new NRustLightningNetworkProvider(networkType);
            var defaultSettings = NRustLightningDefaultSettings.GetDefaultSettings(NetworkProvider.NetworkType);
            var d = config.GetOrDefault <string>("datadir", null);

            DataDir = d is null?Path.GetDirectoryName(defaultSettings.DefaultDataDir) : Path.Join(d, NRustLightningDefaultSettings.GetFolderName(networkType));

            if (!Directory.Exists(DataDir))
            {
                Directory.CreateDirectory(DataDir ?? throw new Exception("Unreachable"));
            }

            var nbxConfig     = config.GetSection("nbx");
            var nbxCookieFile =
                nbxConfig.GetOrDefault("cookiefile",
                                       Constants.DefaultNbXplorerCookieFile(NetworkProvider.NetworkType));

            NBXplorerUri = new Uri(nbxConfig.GetOrDefault("rpcurl", Constants.DefaultNBXplorerUri));

            if (!File.Exists(nbxCookieFile))
            {
                logger?.LogWarning($"cookie file for nbxplorer does not exist in {nbxCookieFile}" +
                                   " Make sure you are running nbx with --noauth.");
            }

            logger?.LogInformation($"nbxplorer url {NBXplorerUri}");
            NBXCookieFile = nbxCookieFile;

            var p2pExternalIp = config.GetOrDefault("externalip", Constants.DefaultP2PExternalIpStr);

            if (NBitcoin.Utils.TryParseEndpoint(p2pExternalIp, Constants.DefaultP2PPort, out var ip))
            {
                P2PExternalIp = ip;
            }
            else if (p2pExternalIp.Contains(":"))
            {
                var s = p2pExternalIp.Split(":", StringSplitOptions.RemoveEmptyEntries);
                if (s.Length != 2)
                {
                    throw new ConfigException($"Invalid external ip {p2pExternalIp}");
                }

                if (Int32.TryParse(s[1], out var port))
                {
                    P2PExternalIp = new DnsEndPoint(s[0], port);
                }
                else
                {
                    throw new ConfigException($"Invalid external ip {p2pExternalIp}");
                }
            }
            else
            {
                throw new ConfigException($"Invalid external ip {p2pExternalIp}");
            }

            logger?.LogInformation($"Advertising external ip: {P2PExternalIp.ToEndpointString()}");
            logger?.LogDebug($"Network: {NetworkProvider.NetworkType.ToString()}");
            var supportedChains = config.GetOrDefault <string>("chains", "BTC")
                                  .Split(',', StringSplitOptions.RemoveEmptyEntries)
                                  .Select(t => t.ToLowerInvariant());
            var validChains = new List <string>();

            foreach (var n in NetworkProvider.GetAll())
            {
                if (supportedChains.Contains(n.CryptoCode))
                {
                    validChains.Add(n.CryptoCode);
                    var chainConfiguration = new ChainConfiguration();
                    chainConfiguration.CryptoCode = n.CryptoCode;
                    var args = RPCArgs.Parse(config, n.NBitcoinNetwork, n.CryptoCode);
                    chainConfiguration.Rpc = args.ConfigureRPCClient(n, logger);
                    if (chainConfiguration.Rpc.Address.Port == n.NBitcoinNetwork.DefaultPort)
                    {
                        logger?.LogWarning($"{n.CryptoCode}: It seems that the1 RPC port ({chainConfiguration.Rpc.Address.Port}) is equal to the default P2P port ({n.NBitcoinNetwork.DefaultPort}, this is probably a misconfiguration)");
                    }
                    if ((chainConfiguration.Rpc.CredentialString.CookieFile != null || chainConfiguration.Rpc.CredentialString.UseDefault) && !n.SupportCookieAuthentication)
                    {
                        throw new ConfigException($"Chain {n.CryptoCode} does not support cookie file authentication,\n" +
                                                  $"Please use {n.CryptoCode.ToLowerInvariant()}rpcuser and {n.CryptoCode.ToLowerInvariant()}rpcpassword settings in NRustLightning" +
                                                  $"And configure rpcuser and rpcpassword in the configuration file or in commandline or your node");
                    }
                    ChainConfiguration.Add(chainConfiguration);
                }
            }
            var invalidChains = String.Join(',', supportedChains.Where(s => !validChains.Contains(s)));

            if (!string.IsNullOrEmpty(invalidChains))
            {
                throw new ConfigException($"Invalid chains {invalidChains}");
            }

            config.GetSection("ln").Bind(RustLightningConfig);


            DBFilePath = Path.Combine(DataDir, "Db.dat");
            if (!Directory.Exists(DBFilePath))
            {
                Directory.CreateDirectory(DBFilePath);
            }

            PaymentTimeoutSec = config.GetOrDefault("paymenttimeout", Constants.DefaultPaymentTimeoutSec);

            DBCacheMB       = config.GetOrDefault("dbcache", Constants.DefaultDBCacheMB);
            _seedFromConfig = config.GetOrDefault("seed", string.Empty);
            _pin            = config.GetOrDefault("pin", string.Empty);
            SeedFilePath    = Path.Join(DataDir, "node_secret");
            return(this);
        }