public Block Process(Block suggestedBlock, ProcessingOptions options, IBlockTracer tracer) { if (!RunSimpleChecksAheadOfProcessing(suggestedBlock, options)) { return(null); } UInt256 totalDifficulty = suggestedBlock.TotalDifficulty ?? 0; if (_logger.IsTrace) { _logger.Trace($"Total difficulty of block {suggestedBlock.ToString(Block.Format.Short)} is {totalDifficulty}"); } bool shouldProcess = suggestedBlock.IsGenesis || totalDifficulty > (_blockTree.Head?.TotalDifficulty ?? 0) // so above is better and more correct but creates an impression of the node staying behind on stats page // so we are okay to process slightly more // and below is less correct but potentially reporting well // || totalDifficulty >= (_blockTree.Head?.TotalDifficulty ?? 0) || (options & ProcessingOptions.ForceProcessing) == ProcessingOptions.ForceProcessing; if (!shouldProcess) { if (_logger.IsDebug) { _logger.Debug($"Skipped processing of {suggestedBlock.ToString(Block.Format.FullHashAndNumber)}, Head = {_blockTree.Head?.Header?.ToString(BlockHeader.Format.Short)}, total diff = {totalDifficulty}, head total diff = {_blockTree.Head?.TotalDifficulty}"); } return(null); } ProcessingBranch processingBranch = PrepareProcessingBranch(suggestedBlock, options); PrepareBlocksToProcess(suggestedBlock, options, processingBranch); Stopwatch stopwatch = Stopwatch.StartNew(); Block[] processedBlocks = ProcessBranch(processingBranch, options, tracer); stopwatch.Stop(); if (processedBlocks == null) { return(null); } if ((options & (ProcessingOptions.ReadOnlyChain | ProcessingOptions.DoNotUpdateHead)) == 0) { _blockTree.UpdateMainChain(processingBranch.Blocks.ToArray(), true); Metrics.LastBlockProcessingTimeInMs = stopwatch.ElapsedMilliseconds; } Block lastProcessed = null; if (processedBlocks.Length > 0) { lastProcessed = processedBlocks[^ 1];
public Block Process(Block suggestedBlock, ProcessingOptions options, IBlockTracer tracer) { if (!RunSimpleChecksAheadOfProcessing(suggestedBlock, options)) { return(null); } UInt256 totalDifficulty = suggestedBlock.TotalDifficulty ?? 0; if (_logger.IsTrace) { _logger.Trace($"Total difficulty of block {suggestedBlock.ToString(Block.Format.Short)} is {totalDifficulty}"); } Block[] processedBlocks = null; bool shouldProcess = suggestedBlock.IsGenesis || totalDifficulty > (_blockTree.Head?.TotalDifficulty ?? 0) // so above is better and more correct but creates an impression of the node staying behind on stats page // so we are okay to process slightly more // and below is less correct but potentially reporting well // || totalDifficulty >= (_blockTree.Head?.TotalDifficulty ?? 0) || (options & ProcessingOptions.ForceProcessing) == ProcessingOptions.ForceProcessing; if (!shouldProcess) { if (_logger.IsDebug) { _logger.Debug($"Skipped processing of {suggestedBlock.ToString(Block.Format.FullHashAndNumber)}, Head = {_blockTree.Head?.Header?.ToString(BlockHeader.Format.Short)}, total diff = {totalDifficulty}, head total diff = {_blockTree.Head?.TotalDifficulty}"); } return(null); } ProcessingBranch processingBranch = PrepareProcessingBranch(suggestedBlock, options); PrepareBlocksToProcess(suggestedBlock, options, processingBranch); try { processedBlocks = _blockProcessor.Process(processingBranch.Root, processingBranch.BlocksToProcess, options, tracer); } catch (InvalidBlockException ex) { for (int i = 0; i < processingBranch.BlocksToProcess.Count; i++) { if (processingBranch.BlocksToProcess[i].Hash == ex.InvalidBlockHash) { _blockTree.DeleteInvalidBlock(processingBranch.BlocksToProcess[i]); if (_logger.IsDebug) { _logger.Debug($"Skipped processing of {suggestedBlock.ToString(Block.Format.FullHashAndNumber)} because of {processingBranch.BlocksToProcess[i].ToString(Block.Format.FullHashAndNumber)} is invalid"); } return(null); } } } if ((options & (ProcessingOptions.ReadOnlyChain | ProcessingOptions.DoNotUpdateHead)) == 0) { _blockTree.UpdateMainChain(processingBranch.Blocks.ToArray(), true); } Block lastProcessed = null; if (processedBlocks != null && processedBlocks.Length > 0) { lastProcessed = processedBlocks[^ 1];