public void SetUp() { _stepDelay = TimeSpan.FromMilliseconds(20); _pendingTxSelector = Substitute.For <IPendingTxSelector>(); _blockchainProcessor = Substitute.For <IBlockchainProcessor>(); _sealer = Substitute.For <ISealer>(); _blockTree = Substitute.For <IBlockTree>(); _blockProcessingQueue = Substitute.For <IBlockProcessingQueue>(); _stateProvider = Substitute.For <IStateProvider>(); _timestamper = Substitute.For <ITimestamper>(); _auRaStepCalculator = Substitute.For <IAuRaStepCalculator>(); _auraConfig = Substitute.For <IAuraConfig>(); _nodeAddress = TestItem.AddressA; _auRaBlockProducer = new AuRaBlockProducer( _pendingTxSelector, _blockchainProcessor, _stateProvider, _sealer, _blockTree, _blockProcessingQueue, _timestamper, LimboLogs.Instance, _auRaStepCalculator, _auraConfig, _nodeAddress); _auraConfig.ForceSealing.Returns(true); _pendingTxSelector.SelectTransactions(Arg.Any <long>()).Returns(Array.Empty <Transaction>()); _sealer.CanSeal(Arg.Any <long>(), Arg.Any <Keccak>()).Returns(true); _sealer.SealBlock(Arg.Any <Block>(), Arg.Any <CancellationToken>()).Returns(c => Task.FromResult(c.Arg <Block>())); _blockProcessingQueue.IsEmpty.Returns(true); _auRaStepCalculator.TimeToNextStep.Returns(_stepDelay); _blockTree.BestKnownNumber.Returns(1); _blockTree.Head.Returns(Build.A.BlockHeader.WithAura(10, Bytes.Empty).TestObject); _blockchainProcessor.Process(Arg.Any <Block>(), ProcessingOptions.ProducingBlock, Arg.Any <IBlockTracer>()).Returns(c => c.Arg <Block>()); }
private Task <bool> ProduceNewBlock(BlockHeader parent, CancellationToken token) { _stateProvider.StateRoot = parent.StateRoot; Block block = PrepareBlock(parent); if (PreparedBlockCanBeMined(block)) { var processedBlock = ProcessPreparedBlock(block); if (processedBlock == null) { if (Logger.IsError) { Logger.Error("Block prepared by block producer was rejected by processor."); } } else { return(_sealer.SealBlock(processedBlock, token).ContinueWith((Func <Task <Block>, bool>)(t => { if (t.IsCompletedSuccessfully) { if (t.Result != null) { if (Logger.IsInfo) { Logger.Info($"Sealed block {t.Result.ToString(Block.Format.HashNumberDiffAndTx)}"); } BlockTree.SuggestBlock(t.Result); return true; } else { if (Logger.IsInfo) { Logger.Info($"Failed to seal block {processedBlock.ToString(Block.Format.HashNumberDiffAndTx)} (null seal)"); } } } else if (t.IsFaulted) { if (Logger.IsError) { Logger.Error("Mining failed", t.Exception); } } else if (t.IsCanceled) { if (Logger.IsInfo) { Logger.Info($"Sealing block {processedBlock.Number} cancelled"); } } return false; }), token)); } } return(Task.FromResult(false)); }
protected ValueTask ProduceNewBlock(BlockHeader parent, CancellationToken token) { _stateProvider.StateRoot = parent.StateRoot; Block block = PrepareBlock(parent); if (PreparedBlockCanBeMined(block)) { Block processedBlock = Processor.Process(block, ProcessingOptions.ProducingBlock, NullBlockTracer.Instance); if (processedBlock == null) { if (Logger.IsError) { Logger.Error("Block prepared by block producer was rejected by processor."); } } else { _sealer.SealBlock(processedBlock, token).ContinueWith(t => { if (t.IsCompletedSuccessfully) { if (t.Result != null) { if (Logger.IsInfo) { Logger.Info($"Sealed block {t.Result.ToString(Block.Format.HashNumberDiffAndTx)}"); } BlockTree.SuggestBlock(t.Result); } else { if (Logger.IsInfo) { Logger.Info($"Failed to seal block {processedBlock.ToString(Block.Format.HashNumberDiffAndTx)} (null seal)"); } } } else if (t.IsFaulted) { if (Logger.IsError) { Logger.Error("Mining failed", t.Exception); } } else if (t.IsCanceled) { if (Logger.IsInfo) { Logger.Info($"Sealing block {processedBlock.Number} cancelled"); } } }, token); } } return(default);
private void OnBlockProcessorQueueEmpty(object sender, EventArgs e) { CancellationToken token; lock (_syncToken) { _cancellationTokenSource = new CancellationTokenSource(); token = _cancellationTokenSource.Token; } Block block = PrepareBlock(); if (block == null) { if (_logger.IsError) { _logger.Error("Failed to prepare block for mining."); } return; } Block processedBlock = _processor.Process(block, ProcessingOptions.NoValidation | ProcessingOptions.ReadOnlyChain | ProcessingOptions.WithRollback, NullBlockTracer.Instance); _sealer.SealBlock(processedBlock, token).ContinueWith(t => { if (t.IsCompletedSuccessfully) { _blockTree.SuggestBlock(t.Result); } else if (t.IsFaulted) { _logger.Error("Mining failer", t.Exception); } else if (t.IsCanceled) { if (_logger.IsDebug) { _logger.Debug($"Mining block {processedBlock.ToString(Block.Format.FullHashAndNumber)} cancelled"); } } }, token); }
private void ConsumeSignal() { foreach (Block signal in _signalsQueue.GetConsumingEnumerable(_cancellationTokenSource.Token)) { Block parentBlock = signal; while (_signalsQueue.TryTake(out Block nextSignal)) { if (parentBlock.Number <= nextSignal.Number) { parentBlock = nextSignal; } } try { Block block = PrepareBlock(parentBlock); if (block == null) { if (_logger.IsTrace) { _logger.Trace("Skipping block production or block production failed"); } continue; } if (_logger.IsInfo) { _logger.Info($"Processing prepared block {block.Number}"); } Block processedBlock = _processor.Process(block, ProcessingOptions.NoValidation | ProcessingOptions.ReadOnlyChain | ProcessingOptions.WithRollback, NullBlockTracer.Instance); if (processedBlock == null) { if (_logger.IsInfo) { _logger.Info($"Prepared block has lost the race"); } continue; } if (_logger.IsDebug) { _logger.Debug($"Sealing prepared block {processedBlock.Number}"); } _sealer.SealBlock(processedBlock, _cancellationTokenSource.Token).ContinueWith(t => { if (t.IsCompletedSuccessfully) { if (t.Result != null) { if (_logger.IsInfo) { _logger.Info($"Sealed block {t.Result.ToString(Block.Format.HashNumberDiffAndTx)}"); } _scheduledBlock = t.Result; } else { if (_logger.IsInfo) { _logger.Info($"Failed to seal block {processedBlock.ToString(Block.Format.HashNumberDiffAndTx)} (null seal)"); } } } else if (t.IsFaulted) { if (_logger.IsError) { _logger.Error("Mining failed", t.Exception); } } else if (t.IsCanceled) { if (_logger.IsInfo) { _logger.Info($"Sealing block {processedBlock.Number} cancelled"); } } }, _cancellationTokenSource.Token); } catch (Exception e) { if (_logger.IsError) { _logger.Error($"Block producer could not produce block on top of {parentBlock.ToString(Block.Format.Short)}", e); } } } }
private void ProduceNewBlock(BlockHeader parentHeader) { _stateProvider.StateRoot = parentHeader.StateRoot; Block block = PrepareBlock(parentHeader); if (block == null) { if (_logger.IsError) { _logger.Error("Failed to prepare block for mining."); } return; } if (block.Transactions.Length == 0) { if (_config.ForceSealing) { if (_logger.IsDebug) { _logger.Debug($"Force sealing block {block.Number} without transactions."); } } else { if (_logger.IsDebug) { _logger.Debug($"Skip seal block {block.Number}, no transactions pending."); } return; } } Block processedBlock = _processor.Process(block, ProcessingOptions.NoValidation | ProcessingOptions.ReadOnlyChain | ProcessingOptions.WithRollback, NullBlockTracer.Instance); if (_logger.IsInfo) { _logger.Info($"Mined a DEV block {processedBlock.ToString(Block.Format.FullHashAndNumber)} State Root: {processedBlock.StateRoot}"); } if (processedBlock == null) { if (_logger.IsError) { _logger.Error("Block prepared by block producer was rejected by processor"); } return; } _sealer.SealBlock(processedBlock, _cancellationTokenSource.Token).ContinueWith(t => { if (t.IsCompletedSuccessfully) { if (t.Result != null) { if (_logger.IsInfo) { _logger.Info($"Sealed block {t.Result.ToString(Block.Format.HashNumberDiffAndTx)}"); } _blockTree.SuggestBlock(t.Result); } else { if (_logger.IsInfo) { _logger.Info($"Failed to seal block {processedBlock.ToString(Block.Format.HashNumberDiffAndTx)} (null seal)"); } } } else if (t.IsFaulted) { if (_logger.IsError) { _logger.Error("Mining failed", t.Exception); } } else if (t.IsCanceled) { if (_logger.IsInfo) { _logger.Info($"Sealing block {processedBlock.Number} cancelled"); } } }, _cancellationTokenSource.Token); }
protected virtual Task <Block> SealBlock(Block block, BlockHeader parent, CancellationToken token) => _sealer.SealBlock(block, token);
public Task <Block> SealBlock(Block block, CancellationToken cancellationToken) => _sealer.SealBlock(block, cancellationToken);