Ejemplo n.º 1
0
        public void ApplyCommand(IpTablesCommand command)
        {
            var chain = Chains.GetChain(command.ChainName, command.Table);

            switch (command.Type)
            {
            case IpTablesCommandType.Add:
                chain.AddRule(command.Rule);
                return;

            case IpTablesCommandType.Delete:
                chain.DeleteRule(command.Offset);
                return;

            case IpTablesCommandType.Replace:
                chain.ReplaceRule(command.Offset, command.Rule);
                return;

            case IpTablesCommandType.Insert:
                chain.InsertRule(command.Offset, command.Rule);
                return;
            }

            throw new IpTablesNetException("Unknown command");
        }
Ejemplo n.º 2
0
        private async Task Listen()
        {
            try
            {
                while (await _Channel.Reader.WaitToReadAsync(_Cts.Token) && _Channel.Reader.TryRead(out var item))
                {
                    if (!_Progress.TryGetValue(item, out var workItem))
                    {
                        Logs.Explorer.LogError($"{workItem.Network.CryptoCode}: Work has been scheduled for {item}, but the work has not been found in _Progress dictionary. This is likely a bug, contact NBXplorer developers.");
                        continue;
                    }
                    Logs.Explorer.LogInformation($"{workItem.Network.CryptoCode}: Start scanning {workItem.DerivationStrategy.ToPrettyString()} from index {workItem.Options.From} with gap limit {workItem.Options.GapLimit}, batch size {workItem.Options.BatchSize}");
                    var rpc   = RpcClients.GetRPCClient(workItem.Network);
                    var chain = Chains.GetChain(workItem.Network);
                    try
                    {
                        var repo = Repositories.GetRepository(workItem.Network);
                        workItem.State.Progress = new ScanUTXOProgress()
                        {
                            Count     = Math.Max(1, Math.Min(workItem.Options.BatchSize, workItem.Options.GapLimit)),
                            From      = workItem.Options.From,
                            StartedAt = DateTimeOffset.UtcNow
                        };
                        foreach (var feature in workItem.Options.DerivationFeatures)
                        {
                            workItem.State.Progress.HighestKeyIndexFound.Add(feature, null);
                        }
                        workItem.State.Progress.UpdateRemainingBatches(workItem.Options.GapLimit);
                        workItem.State.Status = ScanUTXOStatus.Pending;
                        var scannedItems = GetScannedItems(workItem, workItem.State.Progress);
                        var scanning     = rpc.StartScanTxoutSetAsync(scannedItems.Descriptors.ToArray());

                        while (true)
                        {
                            var progress = await rpc.GetStatusScanTxoutSetAsync();

                            if (progress != null)
                            {
                                workItem.State.Progress.CurrentBatchProgress = (int)Math.Round(progress.Value);
                                workItem.State.Progress.UpdateOverallProgress();
                            }
                            using (var cts = CancellationTokenSource.CreateLinkedTokenSource(_Cts.Token))
                            {
                                cts.CancelAfter(TimeSpan.FromSeconds(5.0));
                                try
                                {
                                    var result = await scanning.WithCancellation(cts.Token);

                                    var progressObj = workItem.State.Progress.Clone();
                                    progressObj.BatchNumber++;
                                    progressObj.From          += progressObj.Count;
                                    progressObj.Found         += result.Outputs.Length;
                                    progressObj.TotalSearched += scannedItems.Descriptors.Count;
                                    progressObj.UpdateRemainingBatches(workItem.Options.GapLimit);
                                    progressObj.UpdateOverallProgress();
                                    Logs.Explorer.LogInformation($"{workItem.Network.CryptoCode}: Scanning of batch {workItem.State.Progress.BatchNumber} for {workItem.DerivationStrategy.ToPrettyString()} complete with {result.Outputs.Length} UTXOs fetched");
                                    await UpdateRepository(workItem.DerivationStrategy, repo, chain, result.Outputs, scannedItems, progressObj);

                                    if (progressObj.RemainingBatches <= -1)
                                    {
                                        progressObj.BatchNumber--;
                                        progressObj.From -= progressObj.Count;
                                        progressObj.TotalSizeOfUTXOSet   = result.SearchedItems;
                                        progressObj.CompletedAt          = DateTimeOffset.UtcNow;
                                        progressObj.RemainingBatches     = 0;
                                        progressObj.CurrentBatchProgress = 100;
                                        progressObj.UpdateRemainingBatches(workItem.Options.GapLimit);
                                        progressObj.UpdateOverallProgress();
                                        workItem.State.Progress = progressObj;
                                        workItem.State.Status   = ScanUTXOStatus.Complete;
                                        Logs.Explorer.LogInformation($"{workItem.Network.CryptoCode}: Scanning {workItem.DerivationStrategy.ToPrettyString()} complete {progressObj.Found} UTXOs found in total");
                                        break;
                                    }
                                    else
                                    {
                                        scannedItems            = GetScannedItems(workItem, progressObj);
                                        workItem.State.Progress = progressObj;
                                        scanning = rpc.StartScanTxoutSetAsync(scannedItems.Descriptors.ToArray());
                                    }
                                }
                                catch (OperationCanceledException) when(cts.Token.IsCancellationRequested)
                                {
                                }
                            }
                        }
                    }
                    catch (Exception ex) when(!_Cts.IsCancellationRequested)
                    {
                        workItem.State.Status = ScanUTXOStatus.Error;
                        workItem.State.Error  = ex.Message;
                        var progress = workItem.State.Progress.Clone();

                        progress.CompletedAt    = DateTimeOffset.UtcNow;
                        workItem.State.Progress = progress;
                        Logs.Explorer.LogError(ex, $"{workItem.Network.CryptoCode}: Error while scanning {workItem.DerivationStrategy.ToPrettyString()}");
                    }
                    finally
                    {
                        await rpc.AbortScanTxoutSetAsync();
                    }
                    workItem.Finished = true;
                }
            }
            catch (OperationCanceledException) when(_Cts.IsCancellationRequested)
            {
            }
        }