Exemple #1
0
        private async Task <bool> WarmupBlockchain()
        {
            if (await _RPC.GetBlockCountAsync() < 100)
            {
                Logs.Configuration.LogInformation($"{_Network.CryptoCode}: Less than 100 blocks, mining some block for regtest");
                await _RPC.GenerateAsync(101);

                return(true);
            }
            else
            {
                var hash = await _RPC.GetBestBlockHashAsync();

                BlockHeader header = null;
                try
                {
                    header = await _RPC.GetBlockHeaderAsync(hash);
                }
                catch (RPCException ex) when(ex.RPCCode == RPCErrorCode.RPC_METHOD_NOT_FOUND)
                {
                    header = (await _RPC.GetBlockAsync(hash)).Header;
                }
                if ((DateTimeOffset.UtcNow - header.BlockTime) > TimeSpan.FromSeconds(24 * 60 * 60))
                {
                    Logs.Configuration.LogInformation($"{_Network.CryptoCode}: It has been a while nothing got mined on regtest... mining 10 blocks");
                    await _RPC.GenerateAsync(10);

                    return(true);
                }
                return(false);
            }
        }
        public static async Task CreateChannel(RPCClient cashCow, ILightningClient sender, ILightningClient dest)
        {
            var destInfo = await dest.GetInfo();

            var destInvoice = await dest.CreateInvoice(1000, "EnsureConnectedToDestination", TimeSpan.FromSeconds(5000));

            while (true)
            {
                var result = await sender.Pay(destInvoice.BOLT11);

                if (result.Result == PayResult.CouldNotFindRoute)
                {
                    var openChannel = await sender.OpenChannel(new OpenChannelRequest()
                    {
                        NodeInfo      = destInfo.NodeInfoList[0],
                        ChannelAmount = Money.Satoshis(16777215),
                        FeeRate       = new FeeRate(1UL, 1)
                    });

                    if (openChannel.Result == OpenChannelResult.CannotAffordFunding)
                    {
                        var address = await sender.GetDepositAddress();

                        try
                        {
                            await cashCow.SendToAddressAsync(address, Money.Coins(1.0m), null, null, true);
                        }
                        catch (RPCException ex) when(ex.RPCCode == RPCErrorCode.RPC_WALLET_INSUFFICIENT_FUNDS || ex.RPCCode == RPCErrorCode.RPC_WALLET_ERROR)
                        {
                            await cashCow.GenerateAsync(1);

                            await cashCow.SendToAddressAsync(address, Money.Coins(1.0m), null, null, true);
                        }
                        await cashCow.GenerateAsync(10);
                        await WaitLNSynched(cashCow, sender);
                        await WaitLNSynched(cashCow, dest);
                    }
                    if (openChannel.Result == OpenChannelResult.PeerNotConnected)
                    {
                        await sender.ConnectTo(destInfo.NodeInfoList[0]);
                    }
                    if (openChannel.Result == OpenChannelResult.NeedMoreConf)
                    {
                        await cashCow.GenerateAsync(6);
                        await WaitLNSynched(cashCow, sender);
                        await WaitLNSynched(cashCow, dest);
                    }
                    if (openChannel.Result == OpenChannelResult.AlreadyExists)
                    {
                        await Task.Delay(1000);
                    }
                }
                else if (result.Result == PayResult.Ok)
                {
                    break;
                }
            }
        }
Exemple #3
0
        private async Task WarmupBlockchain()
        {
            if (await _RPC.GetBlockCountAsync() < 100)
            {
                Logs.Configuration.LogInformation($"{_Network.CryptoCode}: Less than 100 blocks, mining some block for regtest");
                await _RPC.GenerateAsync(101);
            }
            else
            {
                var header = await _RPC.GetBlockHeaderAsync(await _RPC.GetBestBlockHashAsync());

                if ((DateTimeOffset.UtcNow - header.BlockTime) > TimeSpan.FromSeconds(24 * 60 * 60))
                {
                    Logs.Configuration.LogInformation($"{_Network.CryptoCode}: It has been a while nothing got mined on regtest... mining 10 blocks");
                    await _RPC.GenerateAsync(10);
                }
            }
        }
Exemple #4
0
        public static async Task <uint256[]> EnsureGenerateAsync(this RPCClient client, int blockCount)
        {
            uint256[] blockIds  = new uint256[blockCount];
            int       generated = 0;

            while (generated < blockCount)
            {
                foreach (var id in await client.GenerateAsync(blockCount - generated).ConfigureAwait(false))
                {
                    blockIds[generated++] = id;
                }
            }
            return(blockIds);
        }
Exemple #5
0
        /// <summary>
        /// Create channels from all senders to all receivers while mining on cashCow
        /// </summary>
        /// <param name="cashCow">The miner and liquidity source</param>
        /// <param name="senders">Senders of payment on Lightning Network</param>
        /// <param name="receivers">Receivers of payment on Lightning Network</param>
        /// <returns></returns>
        public static async Task ConnectAll(RPCClient cashCow, IEnumerable <ILightningClient> senders, IEnumerable <ILightningClient> receivers)
        {
            if (await cashCow.GetBlockCountAsync() <= cashCow.Network.Consensus.CoinbaseMaturity)
            {
                await cashCow.GenerateAsync(cashCow.Network.Consensus.CoinbaseMaturity + 1);
            }


            foreach (var sender in senders)
            {
                foreach (var dest in receivers)
                {
                    await CreateChannel(cashCow, sender, dest);
                }
            }
        }
Exemple #6
0
        public async Task CreateEnoughTxToEstimateFee()
        {
            var txPerBlock = 6;
            var nBlock     = 6;

            for (int i = 0; i < nBlock; i++)
            {
                for (int j = 0; j < txPerBlock; j++)
                {
                    var addr = new Key().PubKey.GetSegwitAddress(Network.RegTest);
                    await this.BitcoinRPCClient.SendToAddressAsync(addr, Money.Coins(0.1m));
                }

                await BitcoinRPCClient.GenerateAsync(1);
            }

            await WaitChainSync();
        }
Exemple #7
0
        public static async Task CreateChannel(RPCClient cashCow, ILightningClient sender, ILightningClient dest)
        {
            var destInfo = await dest.GetInfo();

            var destInvoice = await dest.CreateInvoice(1000, "EnsureConnectedToDestination", TimeSpan.FromSeconds(5000));

            while (true)
            {
                int payErrors = 0;
                var result    = await Pay(sender, destInvoice.BOLT11);

                Logs.LogInformation($"Pay Result: {result.Result} {result.ErrorDetail}");
                if (result.Result == PayResult.Ok)
                {
                    break;
                }
                else if (result.Result == PayResult.CouldNotFindRoute)
                {
                    // check channels that are in process of opening, to prevent double channel open
                    await Task.Delay(100);

                    var pendingChannels = await sender.ListChannels();

                    if (pendingChannels.Any(a => a.RemoteNode == destInfo.NodeInfoList[0].NodeId))
                    {
                        Logs.LogInformation($"Channel to {destInfo.NodeInfoList[0]} is already open(ing)");

                        Logs.LogInformation($"Attempting to reconnect Result: {await sender.ConnectTo(destInfo.NodeInfoList.First())}");

                        await cashCow.GenerateAsync(1);
                        await WaitLNSynched(cashCow, sender);
                        await WaitLNSynched(cashCow, dest);

                        continue;
                    }

                    Logs.LogInformation($"Opening channel to {destInfo.NodeInfoList[0]}");
                    var openChannel = await sender.OpenChannel(new OpenChannelRequest()
                    {
                        NodeInfo      = destInfo.NodeInfoList[0],
                        ChannelAmount = Money.Satoshis(16777215),
                        FeeRate       = new FeeRate(1UL, 1)
                    });

                    Logs.LogInformation($"Channel opening result: {openChannel.Result}");
                    if (openChannel.Result == OpenChannelResult.CannotAffordFunding)
                    {
                        var address = await sender.GetDepositAddress();

                        try
                        {
                            await cashCow.SendToAddressAsync(address, Money.Coins(1.0m), new SendToAddressParameters()
                            {
                                Replaceable = true
                            });
                        }
                        catch (RPCException ex) when(ex.RPCCode == RPCErrorCode.RPC_WALLET_INSUFFICIENT_FUNDS || ex.RPCCode == RPCErrorCode.RPC_WALLET_ERROR)
                        {
                            await cashCow.GenerateAsync(1);

                            await cashCow.SendToAddressAsync(address, Money.Coins(1.0m), new SendToAddressParameters()
                            {
                                Replaceable = true
                            });
                        }
                        await cashCow.GenerateAsync(10);
                        await WaitLNSynched(cashCow, sender);
                        await WaitLNSynched(cashCow, dest);
                    }
                    if (openChannel.Result == OpenChannelResult.PeerNotConnected)
                    {
                        await sender.ConnectTo(destInfo.NodeInfoList[0]);
                    }
                    if (openChannel.Result == OpenChannelResult.NeedMoreConf)
                    {
                        await cashCow.GenerateAsync(6);
                        await WaitLNSynched(cashCow, sender);
                        await WaitLNSynched(cashCow, dest);
                    }
                    if (openChannel.Result == OpenChannelResult.AlreadyExists)
                    {
                        await Task.Delay(1000);
                    }
                    if (openChannel.Result == OpenChannelResult.Ok)
                    {
                        // generate one block and a bit more time to confirm channel opening
                        await cashCow.GenerateAsync(1);
                        await WaitLNSynched(cashCow, sender);
                        await WaitLNSynched(cashCow, dest);

                        await Task.Delay(500);
                    }
                }
                else
                {
                    if (payErrors++ > 10)
                    {
                        throw new Exception($"Couldn't establish payment channel after {payErrors} repeated tries");
                    }

                    await Task.Delay(1000);
                }
            }
        }
        public async Task StartAsync()
        {
            if (_Disposed)
            {
                throw new ObjectDisposedException(nameof(NBxplorerInitializer));
            }
            _Starting.Reset();
            try
            {
                if (_Network.IsRegTest)
                {
                    if (await _RPC.GetBlockCountAsync() < 100)
                    {
                        Logs.Configuration.LogInformation($"Less than 100 blocks, mining some block for regtest");
                        await _RPC.GenerateAsync(101);
                    }
                    else
                    {
                        var header = await _RPC.GetBlockHeaderAsync(await _RPC.GetBestBlockHashAsync());

                        if ((DateTimeOffset.UtcNow - header.BlockTime) > TimeSpan.FromSeconds(24 * 60 * 60))
                        {
                            Logs.Configuration.LogInformation($"It has been a while nothing got mined on regtest... mining 10 blocks");
                            await _RPC.GenerateAsync(10);
                        }
                    }
                }

                var cachePath = Path.Combine(_Configuration.DataDir, "chain.dat");
                if (_Configuration.CacheChain && File.Exists(cachePath))
                {
                    Logs.Configuration.LogInformation($"Loading chain from cache...");
                    _Chain.Load(File.ReadAllBytes(cachePath));
                    Logs.Configuration.LogInformation($"Height: " + _Chain.Height);
                }

                var heightBefore = _Chain.Height;
                Logs.Configuration.LogInformation($"Loading chain from node...");
                using (var node = Node.Connect(_Network.Network, _Configuration.NodeEndpoint))
                {
                    var cts = new CancellationTokenSource();
                    cts.CancelAfter(5000);
                    node.VersionHandshake(cts.Token);
                    node.SynchronizeChain(_Chain);
                }
                Logs.Configuration.LogInformation("Height: " + _Chain.Height);

                if (_Configuration.CacheChain && heightBefore != _Chain.Height)
                {
                    Logs.Configuration.LogInformation($"Saving chain to cache...");
                    var ms = new MemoryStream();
                    _Chain.WriteTo(ms);
                    File.WriteAllBytes(cachePath, ms.ToArray());
                    Logs.Configuration.LogInformation($"Saved");
                }


                AddressManager manager = new AddressManager();
                manager.Add(new NetworkAddress(_Configuration.NodeEndpoint), IPAddress.Loopback);
                NodesGroup group = new NodesGroup(_Network.Network, new NodeConnectionParameters()
                {
                    Services          = NodeServices.Nothing,
                    IsRelay           = true,
                    TemplateBehaviors =
                    {
                        new AddressManagerBehavior(manager)
                        {
                            PeersToDiscover = 1,
                            Mode            = AddressManagerBehaviorMode.None
                        },
                        new ExplorerBehavior(_Repository, _Chain, _Invoker, _Events)
                        {
                            StartHeight = _Configuration.StartHeight
                        },
                        new ChainBehavior(_Chain)
                        {
                            CanRespondToGetHeaders = false
                        }
                    }
                });
                group.AllowSameGroup        = true;
                group.MaximumNodeConnection = 1;
                group.Connect();
                _Group = group;
            }
            finally { _Starting.Set(); }
        }