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); }
public ChannelController(IPeerManagerProvider peerManagerProvider, NRustLightningNetworkProvider networkProvider, ILogger <ChannelController> logger) { _peerManagerProvider = peerManagerProvider; _networkProvider = networkProvider; _logger = logger; _pool = MemoryPool <byte> .Shared; }
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 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; }
/// <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]}"))); }
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; }
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); }); }
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; }
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)); }
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)); } } }
public WalletController(NRustLightningNetworkProvider networkProvider, IWalletService walletService, IPeerManagerProvider peerManagerProvider, RepositoryProvider repositoryProvider) { _networkProvider = networkProvider; _walletService = walletService; _peerManagerProvider = peerManagerProvider; _repositoryProvider = repositoryProvider; _pool = MemoryPool <byte> .Shared; }
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; }
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 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(); } } }
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 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); } } }
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); } }
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); }
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); }
public StubNBXplorerClientProvider(NRustLightningNetworkProvider networkProvider) { _networkProvider = networkProvider; }
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"); } }
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); }
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"); } }
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); }