private async Task <Block?> TryProduceBlock(BlockHeader?parentHeader, CancellationToken cancellationToken = default)
        {
            Task <Block?>[] produceTasks = new Task <Block?> [_blockProducers.Length];
            for (int i = 0; i < _blockProducers.Length; i++)
            {
                T blockProducerInfo = _blockProducers[i];
                produceTasks[i] = blockProducerInfo.BlockProductionTrigger.BuildBlock(parentHeader, cancellationToken, blockProducerInfo.BlockTracer);
            }

            IEnumerable <(Block?Block, T BlockProducer)> blocksWithProducers;

            try
            {
                Block?[] blocks = await Task.WhenAll(produceTasks);

                blocksWithProducers = blocks.Zip(_blockProducers);
            }
            catch (OperationCanceledException)
            {
                blocksWithProducers = produceTasks
                                      .Zip(_blockProducers)
                                      .Where(t => t.First.IsCompletedSuccessfully)
                                      .Select(t => (t.First.Result, t.Second));
            }

            Block?bestBlock = _bestBlockPicker.GetBestBlock(blocksWithProducers);

            if (bestBlock is not null)
            {
                if (produceTasks.Count(t => t.IsCompletedSuccessfully && t.Result is not null) > 1)
                {
                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Picked block {bestBlock} to be included to the chain.");
                    }
                }

                BlockProduced?.Invoke(this, new BlockEventArgs(bestBlock));
            }

            return(bestBlock);
        }
Ejemplo n.º 2
0
 private void OnBlockProduced(object?sender, BlockEventArgs e)
 {
     BlockProduced?.Invoke(this, e);
 }