예제 #1
0
        private void RunBloomMigration(CancellationToken token)
        {
            BlockHeader GetMissingBlockHeader(long i)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn(GetLogMessage("warning", $"Header for block {i} not found. Logs will not be searchable for this block."));
                }
                return(EmptyHeader);
            }

            if (_api.BloomStorage == null)
            {
                throw new StepDependencyException(nameof(_api.BloomStorage));
            }
            if (_api.BlockTree == null)
            {
                throw new StepDependencyException(nameof(_api.BlockTree));
            }
            if (_api.ChainLevelInfoRepository == null)
            {
                throw new StepDependencyException(nameof(_api.ChainLevelInfoRepository));
            }

            IBlockTree    blockTree = _api.BlockTree;
            IBloomStorage storage   = _api.BloomStorage;
            long          to        = MinBlockNumber;
            long          synced    = storage.MigratedBlockNumber + 1;
            long          from      = synced;

            _migrateCount = to + 1;
            _averages     = _api.BloomStorage.Averages.ToArray();
            IChainLevelInfoRepository?chainLevelInfoRepository = _api.ChainLevelInfoRepository;

            _progress.Update(synced);

            if (_logger.IsInfo)
            {
                _logger.Info(GetLogMessage("started"));
            }

            using (var timer = new Timer(1000)
            {
                Enabled = true
            })
            {
                timer.Elapsed += (ElapsedEventHandler)((o, e) =>
                {
                    if (_logger.IsInfo)
                    {
                        _logger.Info(GetLogMessage("in progress"));
                    }
                });

                try
                {
                    storage.Migrate(GetHeadersForMigration());
                }
                finally
                {
                    _progress.MarkEnd();
                    _stopwatch?.Stop();
                }

                IEnumerable <BlockHeader> GetHeadersForMigration()
                {
                    bool TryGetMainChainBlockHashFromLevel(long number, out Keccak?blockHash)
                    {
                        using var batch = chainLevelInfoRepository.StartBatch();
                        var level = chainLevelInfoRepository.LoadLevel(number);

                        if (level != null)
                        {
                            if (!level.HasBlockOnMainChain)
                            {
                                if (level.BlockInfos.Length > 0)
                                {
                                    level.HasBlockOnMainChain = true;
                                    chainLevelInfoRepository.PersistLevel(number, level, batch);
                                }
                            }

                            blockHash = level.MainChainBlock?.BlockHash;
                            return(blockHash != null);
                        }
                        else
                        {
                            blockHash = null;
                            return(false);
                        }
                    }

                    for (long i = from; i <= to; i++)
                    {
                        if (token.IsCancellationRequested)
                        {
                            timer.Stop();
                            if (_logger.IsInfo)
                            {
                                _logger.Info(GetLogMessage("cancelled"));
                            }
                            yield break;
                        }

                        if (TryGetMainChainBlockHashFromLevel(i, out Keccak? blockHash))
                        {
                            var header = blockTree.FindHeader(blockHash, BlockTreeLookupOptions.None);
                            yield return(header ?? GetMissingBlockHeader(i));
                        }
                        else
                        {
                            yield return(GetMissingBlockHeader(i));
                        }

                        _progress.Update(++synced);
                    }
                }
            }

            if (!token.IsCancellationRequested)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info(GetLogMessage("finished"));
                }
            }
        }
예제 #2
0
        private void RunBloomMigration(CancellationToken token)
        {
            if (_context.BloomStorage == null)
            {
                throw new StepDependencyException(nameof(_context.BloomStorage));
            }
            if (_context.BlockTree == null)
            {
                throw new StepDependencyException(nameof(_context.BlockTree));
            }

            IBlockTree    blockTree = _context.BlockTree;
            IBloomStorage storage   = _context.BloomStorage;
            long          to        = MinBlockNumber;
            long          synced    = storage.MigratedBlockNumber + 1;
            long          from      = synced;

            _migrateCount = to + 1;
            _averages     = _context.BloomStorage.Averages.ToArray();

            _progress.Update(synced);

            if (_logger.IsInfo)
            {
                _logger.Info(GetLogMessage("started"));
            }

            using (var timer = new Timer(1000)
            {
                Enabled = true
            })
            {
                timer.Elapsed += (ElapsedEventHandler)((o, e) =>
                {
                    if (_logger.IsInfo)
                    {
                        _logger.Info(GetLogMessage("in progress"));
                    }
                });

                try
                {
                    storage.Migrate(GetHeadersForMigration());
                }
                finally
                {
                    _progress.MarkEnd();
                    _stopwatch?.Stop();
                }

                IEnumerable <BlockHeader> GetHeadersForMigration()
                {
                    for (long i = from; i <= to; i++)
                    {
                        if (token.IsCancellationRequested)
                        {
                            timer.Stop();
                            if (_logger.IsInfo)
                            {
                                _logger.Info(GetLogMessage("cancelled"));
                            }
                            yield break;
                        }

                        var header = blockTree.FindHeader(i);
                        yield return(header ?? new BlockHeader(Keccak.Zero, Keccak.Zero, Address.Zero, UInt256.Zero, 0L, 0L, UInt256.Zero, Bytes.Empty));

                        synced++;
                        _progress.Update(synced);
                    }
                }
            }

            if (!token.IsCancellationRequested)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info(GetLogMessage("finished"));
                }
            }
        }