Ejemplo n.º 1
0
        public void RepositorySerializerTest(string cryptoCode)
        {
            var networkProvider = new NRustLightningNetworkProvider(NetworkType.Regtest);
            var ser             = new RepositorySerializer(networkProvider.GetByCryptoCode(cryptoCode));
            // utxo response
            var resp        = new UTXOChangesWithMetadata();
            var confirmed   = new UTXOChangeWithSpentOutput();
            var unconfirmed = new UTXOChangeWithSpentOutput();

            confirmed.SpentOutPoint = new List <OutPoint>()
            {
                OutPoint.Zero
            };
            var coinBaseTx =
                Transaction.Parse(
                    "020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401750101ffffffff0200f2052a0100000017a914d4bb8bf5f987cd463a2f5e6e4f04618c7aaed1b5870000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", Network.RegTest);
            var utxo = new UTXO(new NBXplorer.Models.UTXO(coinBaseTx.Outputs.AsCoins().First()));

            Assert.NotNull(JsonSerializer.Serialize(utxo, ser.Options));
            confirmed.UTXO = new List <UTXOChangeWithMetadata>()
            {
                new UTXOChangeWithMetadata(utxo, UTXOKind.UserDeposit, new AddressTrackedSource(coinBaseTx.Outputs[0].ScriptPubKey.GetDestinationAddress(Network.RegTest)))
            };
            resp.Confirmed   = confirmed;
            resp.UnConfirmed = unconfirmed;
            var res = JsonSerializer.Serialize(resp, ser.Options);

            Assert.NotNull(res);
        }
Ejemplo n.º 2
0
 public ChannelController(IPeerManagerProvider peerManagerProvider, NRustLightningNetworkProvider networkProvider, ILogger <ChannelController> logger)
 {
     _peerManagerProvider = peerManagerProvider;
     _networkProvider     = networkProvider;
     _logger = logger;
     _pool   = MemoryPool <byte> .Shared;
 }
Ejemplo n.º 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);
                }
            }
        }
Ejemplo n.º 4
0
 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 PaymentController(
     NRustLightningNetworkProvider networkProvider, RepositoryProvider repositoryProvider, InvoiceService invoiceService)
 {
     _networkProvider    = networkProvider;
     _repositoryProvider = repositoryProvider;
     _invoiceService     = invoiceService;
 }
Ejemplo n.º 6
0
        /// <summary>
        ///  Start bitcoind and nbxplorer in the backgroud.
        /// </summary>
        /// <param name="dockerFixture"></param>
        /// <param name="output"></param>
        /// <param name="caller"></param>
        /// <returns></returns>
        public static async Task <ExplorerClient> StartExplorerFixtureAsync(this DockerFixture dockerFixture, string caller)
        {
            var ports = new int[2];

            Support.Utils.FindEmptyPort(ports);
            var dataPath = Path.GetFullPath(caller);

            if (!Directory.Exists(dataPath))
            {
                Directory.CreateDirectory(dataPath);
            }
            else
            {
                Directory.Delete(dataPath, true);
                Directory.CreateDirectory(dataPath);
            }
            var env = new Dictionary <string, object>()
            {
                {
                    "BITCOIND_RPC_AUTH",
                    Constants.BitcoindRPCAuth
                },
                { "BITCOIND_RPC_USER", Constants.BitcoindRPCUser },
                { "BITCOIND_RPC_PASS", Constants.BitcoindRPCPass },
                { "BITCOIND_RPC_PORT", ports[0] },
                { "NBXPLORER_PORT", ports[1] },
                { "DATA_PATH", dataPath }
            };
            var envFile = Path.Join(dataPath, "env.sh");

            using (TextWriter w = File.AppendText(envFile))
            {
                foreach (var kv in env)
                {
                    w.WriteLine($"export {kv.Key}='{kv.Value}'");
                }
            }
            await dockerFixture.InitAsync(() => new DockerFixtureOptions
            {
                DockerComposeFiles    = new[] { "docker-compose.base.yml" },
                EnvironmentVariables  = env,
                DockerComposeDownArgs = "--remove-orphans --volumes",
                // we need this because c-lightning is not working well with bind mount.
                // If we use volume mount instead, this is the only way to recreate the volume at runtime.
                DockerComposeUpArgs = "--renew-anon-volumes",
                StartupTimeoutSecs  = 400,
                LogFilePath         = Path.Join(dataPath, "docker-compose.log"),
                CustomUpTest        = o =>
                {
                    return
                    (o.Any(x => x.Contains("BTC: Node state changed: NBXplorerSynching => Ready")));   // nbx is up
                }
            });

            var networkProvider = new NRustLightningNetworkProvider(NetworkType.Regtest);
            var btcNetwork      = networkProvider.GetByCryptoCode("BTC");

            return(new ExplorerClient(btcNetwork.NbXplorerNetwork, new Uri($"http://localhost:{ports[1]}")));
        }
Ejemplo n.º 7
0
 public InfoController(IKeysRepository keysRepository, IOptions <Config> config, P2PConnectionHandler connectionHandler, NRustLightningNetworkProvider networkProvider, RepositoryProvider repositoryProvider)
 {
     this.keysRepository = keysRepository;
     _connectionHandler  = connectionHandler;
     _networkProvider    = networkProvider;
     _repositoryProvider = repositoryProvider;
     this.config         = config.Value;
 }
Ejemplo n.º 8
0
        public static void ConfigureNRustLightning(this IServiceCollection services, IConfiguration configuration, ILogger logger)
        {
            var network         = configuration.GetNetworkType();
            var networkProvider = new NRustLightningNetworkProvider(network);

            services.AddSingleton(networkProvider);
            services.AddLogging();
            services.Configure <Config>(o => { o.LoadArgs(configuration, logger); });
        }
Ejemplo n.º 9
0
 public InvoiceService(IInvoiceRepository invoiceRepository, EventAggregator eventAggregator, IPeerManagerProvider peerManagerProvider, NRustLightningNetworkProvider networkProvider, ILogger <InvoiceService> logger, IOptions <Config> config)
 {
     _invoiceRepository   = invoiceRepository;
     _eventAggregator     = eventAggregator;
     _peerManagerProvider = peerManagerProvider;
     _networkProvider     = networkProvider;
     _logger = logger;
     _config = config;
 }
Ejemplo n.º 10
0
 public DBTrieInvoiceRepository(IOptions <Config> conf, IKeysRepository keysRepository, ISystemClock systemClock, NRustLightningNetworkProvider networkProvider, ILogger <DBTrieInvoiceRepository> logger)
 {
     _dbPath          = conf.Value.InvoiceDBFilePath;
     _keysRepository  = keysRepository;
     _systemClock     = systemClock;
     _networkProvider = networkProvider;
     _logger          = logger;
     _engine          = DBTrieEngine.OpenFromFolder(_dbPath).Result;
     _engine.ConfigurePagePool(new PagePool(pageSize: conf.Value.DBCacheMB));
 }
Ejemplo n.º 11
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));
         }
     }
 }
Ejemplo n.º 12
0
 public WalletController(NRustLightningNetworkProvider networkProvider,
                         IWalletService walletService,
                         IPeerManagerProvider peerManagerProvider,
                         RepositoryProvider repositoryProvider)
 {
     _networkProvider     = networkProvider;
     _walletService       = walletService;
     _peerManagerProvider = peerManagerProvider;
     _repositoryProvider  = repositoryProvider;
     _pool = MemoryPool <byte> .Shared;
 }
Ejemplo n.º 13
0
 public InvoiceService(IRepository repository, EventAggregator eventAggregator, PeerManagerProvider peerManagerProvider, NRustLightningNetworkProvider networkProvider, ILogger <InvoiceService> logger, IOptions <Config> config, IKeysRepository keysRepository)
 {
     _repository          = repository;
     _eventAggregator     = eventAggregator;
     _peerManagerProvider = peerManagerProvider;
     _networkProvider     = networkProvider;
     _logger         = logger;
     _config         = config;
     _keysRepository = keysRepository;
     _pool           = MemoryPool <byte> .Shared;
 }
Ejemplo n.º 14
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));
         }
     }
 }
Ejemplo n.º 15
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();
         }
     }
 }
Ejemplo n.º 16
0
 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);
         }
     }
 }
Ejemplo n.º 17
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);
                }
            }
        }
Ejemplo n.º 18
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 PeerManagerProvider(
     INBXplorerClientProvider nbXplorerClientProvider,
     NRustLightningNetworkProvider networkProvider,
     IKeysRepository keysRepository,
     ILoggerFactory loggerFactory,
     ChannelProvider channelProvider,
     IOptions <Config> config,
     RepositoryProvider repositoryProvider,
     EventAggregator eventAggregator
     )
 {
     _nbXplorerClientProvider = nbXplorerClientProvider;
     _networkProvider         = networkProvider;
     _keysRepository          = keysRepository;
     _loggerFactory           = loggerFactory;
     _logger             = loggerFactory.CreateLogger <PeerManagerProvider>();
     _channelProvider    = channelProvider;
     _config             = config;
     _repositoryProvider = repositoryProvider;
     _eventAggregator    = eventAggregator;
 }
 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);
     }
 }
Ejemplo n.º 21
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);
        }
Ejemplo n.º 22
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);
        }
Ejemplo n.º 23
0
 public StubNBXplorerClientProvider(NRustLightningNetworkProvider networkProvider)
 {
     _networkProvider = networkProvider;
 }
Ejemplo n.º 24
0
        public async Task RepositoryTest()
        {
            using var tester = DBTrieRepositoryTester.Create();

            // 1. Check invoice Equality
            var networkProvider = new NRustLightningNetworkProvider(NetworkType.Regtest);
            var network         = networkProvider.GetByCryptoCode("BTC");
            var nodeSecret      = new Key();
            var nodeId          = Primitives.NodeId.NewNodeId(nodeSecret.PubKey);

            Primitives.PaymentPreimage paymentPreimage = Primitives.PaymentPreimage.Create(RandomUtils.GetBytes(32));
            var taggedFields =
                new List <TaggedField>
            {
                TaggedField.NewPaymentHashTaggedField(paymentPreimage.Hash),
                TaggedField.NewNodeIdTaggedField((nodeId)),
                TaggedField.NewDescriptionTaggedField("Test invoice")
            };
            var t        = new TaggedFields(taggedFields.ToFSharpList());
            var invoiceR = PaymentRequest.TryCreate(network.BOLT11InvoicePrefix, FSharpOption <LNMoney> .None, DateTimeOffset.UtcNow, nodeId, t, nodeSecret);

            if (invoiceR.IsError)
            {
                throw new Exception(invoiceR.ErrorValue);
            }
            var invoice = invoiceR.ResultValue;
            await tester.Repository.SetInvoice(invoice);

            var invoice2 = await tester.Repository.GetInvoice(paymentPreimage.Hash);

            Assert.Equal(invoice.ToString(), invoice2.ToString());

            // 2. preimage
            await tester.Repository.SetPreimage(paymentPreimage);

            var preimage2 = await tester.Repository.GetPreimage(paymentPreimage.Hash);

            Assert.Equal(paymentPreimage, preimage2);

            // 3. remote endpoint
            var ipEndpoint   = IPEndPoint.Parse("192.168.0.1:9735");
            var dnsEndPointA = NBitcoin.Utils.ParseEndpoint("lightningd-a:9735", 9735);
            var dnsEndPointB = NBitcoin.Utils.ParseEndpoint("lightningd-b:8888", 9735);
            await tester.Repository.SetRemoteEndPoint(ipEndpoint);

            await tester.Repository.SetRemoteEndPoint(dnsEndPointA);

            await tester.Repository.SetRemoteEndPoint(dnsEndPointB);

            var endpoints = await tester.Repository.GetAllRemoteEndPoint().ToListAsync();

            Assert.Contains(ipEndpoint, endpoints);
            Assert.Contains(dnsEndPointA, endpoints);
            Assert.Contains(dnsEndPointB, endpoints);

            var(chanMan, readArgs, chanMon, monitorReadArgs) = GetTestChannelManager();
            // 4. channel manager
            await tester.Repository.SetChannelManager(chanMan, CancellationToken.None);

            var items = await tester.Repository.GetChannelManager(readArgs);

            Assert.True(items.HasValue);
            var(_, chanMan2) = items.Value;
            Assert.True(chanMan.Serialize(_pool).SequenceEqual(chanMan2.Serialize(_pool)));

            // 5. channel monitor
            await tester.Repository.SetManyChannelMonitor(chanMon);

            var items2 = await tester.Repository.GetManyChannelMonitor(monitorReadArgs);

            Assert.True(items2.HasValue);
            var(chanMon2, _) = items2.Value;
            Assert.True(chanMon.Serialize(_pool).SequenceEqual(chanMon2.Serialize(_pool)));
        }
        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");
            }
        }
Ejemplo n.º 26
0
        public static async Task <Clients> StartLNTestFixtureAsync(this DockerFixture dockerFixture, string caller, bool useCachedData = false)
        {
            var ports = new int[5];

            Support.Utils.FindEmptyPort(ports);
            var dataPath = Path.GetFullPath(caller);

            if (Directory.Exists(dataPath) && !useCachedData)
            {
                Directory.Delete(dataPath, true);
            }
            Directory.CreateDirectory(dataPath);

            var env = new Dictionary <string, object>()
            {
                {
                    "BITCOIND_RPC_AUTH",
                    Constants.BitcoindRPCAuth
                },
                { "BITCOIND_RPC_USER", Constants.BitcoindRPCUser },
                { "BITCOIND_RPC_PASS", Constants.BitcoindRPCPass },
                { "BITCOIND_RPC_PORT", ports[0] },
                { "LND_REST_PORT", ports[1] },
                { "LIGHTNINGD_RPC_PORT", ports[2] },
                { "HTTP_PORT", ports[3] },
                { "NBXPLORER_PORT", ports[4] },
                { "DATA_PATH", dataPath }
            };
            var envFile = Path.Join(dataPath, "env.sh");

            using (TextWriter w = File.AppendText(envFile))
            {
                foreach (var kv in env)
                {
                    w.WriteLine($"export {kv.Key}='{kv.Value}'");
                }
            }
            await dockerFixture.InitAsync(() => new DockerFixtureOptions
            {
                DockerComposeFiles    = new[] { "docker-compose.yml" },
                EnvironmentVariables  = env,
                DockerComposeDownArgs = "--remove-orphans --volumes",
                // we need this because c-lightning is not working well with bind mount.
                // If we use volume mount instead, this is the only way to recreate the volume at runtime.
                DockerComposeUpArgs = "--renew-anon-volumes",
                StartupTimeoutSecs  = 400,
                LogFilePath         = Path.Join(dataPath, "docker-compose.log"),
                CustomUpTest        = o =>
                {
                    return
                    (o.Any(x => x.Contains("Now listening on: http://0.0.0.0:9735")) && // nrustlightning is up
                     o.Any(x => x.Contains("PeerManagerProvider started")) &&    // ditto
                     o.Any(x => x.Contains("Server started with public key")) &&    // lightningd is up
                     o.Any(x => x.Contains("BTC: Node state changed: NBXplorerSynching => Ready")) &&    // nbx is up
                     o.Any(x => x.Contains("BTCN: Server listening on")));      // lnd is up
                }
            });

            var networkProvider      = new NRustLightningNetworkProvider(NetworkType.Regtest);
            var btcNetwork           = networkProvider.GetByCryptoCode("BTC");
            var lndMacaroonPath      = Path.Join(dataPath, ".lnd", "chain", "bitcoin", "regtest", "admin.macaroon");
            var lndTlsCertThumbPrint = GetCertificateFingerPrintHex(Path.Join(dataPath, ".lnd", "tls.cert"));
            var clients = new Clients(
                new RPCClient($"{Constants.BitcoindRPCUser}:{Constants.BitcoindRPCPass}", new Uri($"http://localhost:{ports[0]}"), NBitcoin.Network.RegTest),
                (LndClient)LightningClientFactory.CreateClient($"type=lnd-rest;macaroonfilepath={lndMacaroonPath};certthumbprint={lndTlsCertThumbPrint};server=https://localhost:{ports[1]}", NBitcoin.Network.RegTest),
                (CLightningClient)LightningClientFactory.CreateClient($"type=clightning;server=tcp://127.0.0.1:{ports[2]}", NBitcoin.Network.RegTest),
                new NRustLightningClient($"http://localhost:{ports[3]}", btcNetwork),
                new ExplorerClient(btcNetwork.NbXplorerNetwork, new Uri($"http://localhost:{ports[4]}"))
                );

            return(clients);
        }
Ejemplo n.º 27
0
        static async Task Main(string[] args)
        {
            var command = CommandLine.GetRootCommand();

            command.Handler = CommandHandler.Create((ParseResult pr) =>
            {
                Console.WriteLine($"Calling handler");
                Network?network;
                var n   = pr.RootCommandResult.ValueForOption <string>("network");
                network = n == "mainnet" ? Network.Main :
                          n == "testnet" ? Network.TestNet :
                          n == "regtest" ? Network.RegTest : null;
                if (network is null)
                {
                    if (pr.RootCommandResult.ValueForOption <bool>("testnet"))
                    {
                        network = Network.TestNet;
                    }
                    else if (pr.RootCommandResult.ValueForOption <bool>("regtest"))
                    {
                        network = Network.RegTest;
                    }
                }
                if (network is null)
                {
                    network = Network.Main;
                }

                var ip = pr.RootCommandResult.ValueForOption <string>("rpcip");
                if (String.IsNullOrEmpty(ip))
                {
                    ip = "127.0.0.1";
                }

                var networkProvider       = new NRustLightningNetworkProvider(network.NetworkType);
                var nrustLightningNetwork = networkProvider.GetByCryptoCode(pr.RootCommandResult.ValueForOption <string>("cryptocode") ?? "btc");

                var port = pr.RootCommandResult.ValueForOption <int>("rpcport");
                if (port == 0)
                {
                    port = 80;
                }
                var baseUrl = $"http://{ip}:{port}";
                var client  = new NRustLightningClient(baseUrl, nrustLightningNetwork);

                var subCommand = pr.CommandResult.Symbol.Name;
                Console.WriteLine($"Subcomamnd is {subCommand}");
                if (subCommand == SubCommands.GetInfo)
                {
                    var nodeInfo = client.GetInfoAsync().Result;
                    Console.WriteLine(nodeInfo.ConnectionString);
                }
                else
                {
                    throw new ArgumentException($"Unknown sub command {subCommand}");
                }
                return;
            });
            var commandLine = new CommandLineBuilder(command).UseDefaults()
                              .Build();
            await commandLine.InvokeAsync(args);
        }
        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");
            }
        }
Ejemplo n.º 29
0
        public void CanConvertJsonTypes()
        {
            var invoice =
                "lnbc1p0vhtzvpp5akajlfqdj6ek7eeh4kae6gc05fz9j99n8jadatqt4fmlwwxwx4zsnp4q2uqg2j52gxtxg5d0v928h5pll95ynsaek2csgfg26tvuzydgjrwgdqhdehjqer9wd3hy6tsw35k7msna3vtx";
            var paymentRequest = PaymentRequest.Parse(invoice);
            var resp           = new InvoiceResponse()
            {
                Invoice = paymentRequest.ResultValue
            };
            var j = JsonSerializer.Serialize(resp);

            JsonSerializer.Deserialize <InvoiceResponse>(j);
            var invoiceResponseRaw = "{\"invoice\":\"lnbc1p0vma42pp5t2v5ehyay3x9g8769gqkrhmdlqjq0kc8ksqfxu3xjw7s2y96jegqnp4q2uqg2j52gxtxg5d0v928h5pll95ynsaek2csgfg26tvuzydgjrwgdqhdehjqer9wd3hy6tsw35k7ms3xhenl\"}";

            JsonSerializer.Deserialize <InvoiceResponse>(invoiceResponseRaw);


            var conf = UserConfig.GetDefault();

            j = JsonSerializer.Serialize(conf);
            var v = JsonSerializer.Deserialize <UserConfig>(j);

            Assert.Equal(conf.ChannelOptions.AnnouncedChannel, v.ChannelOptions.AnnouncedChannel);

            var openChannelRequest = new OpenChannelRequest();

            j = JsonSerializer.Serialize(openChannelRequest);
            var conv = JsonSerializer.Deserialize <OpenChannelRequest>(j);

            Assert.Equal(openChannelRequest.OverrideConfig, conv.OverrideConfig);

            // with custom config
            openChannelRequest.OverrideConfig = UserConfig.GetDefault();
            j = JsonSerializer.Serialize(openChannelRequest);
            // Don't know why but we must specify option here.
            var opt = new JsonSerializerOptions();

            opt.Converters.Add(new NullableStructConverterFactory());
            conv = JsonSerializer.Deserialize <OpenChannelRequest>(j, opt);

            Assert.True(conv.OverrideConfig.HasValue);
            Assert.Equal(openChannelRequest.OverrideConfig.Value.ChannelOptions.AnnouncedChannel, conv.OverrideConfig.Value.ChannelOptions.AnnouncedChannel);
            j =
                "{\"TheirNetworkKey\":\"024a8b7fc86957537bb365cc0242255582d3d40a5532489f67e700a89bcac2f010\",\"ChannelValueSatoshis\":100000,\"PushMSat\":1000,\"OverrideConfig\":null}";
            openChannelRequest = JsonSerializer.Deserialize <OpenChannelRequest>(j, new JsonSerializerOptions()
            {
                Converters = { new HexPubKeyConverter() }
            });
            Assert.Equal(100000UL, openChannelRequest.ChannelValueSatoshis);
            Assert.Equal(1000UL, openChannelRequest.PushMSat);
            Assert.NotNull(openChannelRequest.TheirNetworkKey);

            // wallet info
            j =
                "{\"DerivationStrategy\":\"tpubDBte1PdX36pt167AFbKpHwFJqZAVVRuJSadZ49LdkX5JJbJCNDc8JQ7w5GdaDZcUXm2SutgwjRuufwq4q4soePD4fPKSZCUhqDDarKRCUen\",\"OnChainBalanceSatoshis\":0}";
            var networkProvider = new NRustLightningNetworkProvider(NetworkType.Regtest);
            var btcNetwork      = networkProvider.GetByCryptoCode("BTC");
            var walletInfo      = JsonSerializer.Deserialize <WalletInfo>(j, new JsonSerializerOptions {
                Converters = { new DerivationStrategyJsonConverter(btcNetwork.NbXplorerNetwork.DerivationStrategyFactory) }
            });

            // FeatureBit
            var featureBit = FeatureBit.TryParse("0b000000100100000100000000").ResultValue;
            var opts       = new JsonSerializerOptions()
            {
                Converters = { new FeatureBitJsonConverter() }
            };

            j = JsonSerializer.Serialize(featureBit, opts);
            Assert.Contains("prettyPrint", j);
            var featureBit2 = JsonSerializer.Deserialize <FeatureBit>(j, opts);

            Assert.Equal(featureBit, featureBit2);
        }