Example #1
0
        private TxReceipt[] ProcessTransactions(Block block, ProcessingOptions processingOptions, IBlockTracer blockTracer)
        {
            _receiptsTracer.SetOtherTracer(blockTracer);
            _receiptsTracer.StartNewBlockTrace(block);

            for (int i = 0; i < block.Transactions.Length; i++)
            {
                Transaction currentTx = block.Transactions[i];
                if ((processingOptions & ProcessingOptions.DoNotVerifyNonce) != 0)
                {
                    currentTx.Nonce = _stateProvider.GetNonce(currentTx.SenderAddress);
                }

                _receiptsTracer.StartNewTxTrace(currentTx.Hash);
                _transactionProcessor.Execute(currentTx, block.Header, _receiptsTracer);
                _receiptsTracer.EndTxTrace();

                TransactionProcessed?.Invoke(this, new TxProcessedEventArgs(i, currentTx, _receiptsTracer.TxReceipts[i]));
            }

            return(_receiptsTracer.TxReceipts);
        }
Example #2
0
        public Block[] Process(Keccak branchStateRoot, Block[] suggestedBlocks, ProcessingOptions options, IBlockTracer blockTracer)
        {
            if (_logger.IsTrace)
            {
                _logger.Trace($"Processing block {suggestedBlocks[0].Number} from state root: {branchStateRoot}");
            }

            if (suggestedBlocks.Length == 0)
            {
                return(Array.Empty <Block>());
            }

            int stateSnapshot = _stateDb.TakeSnapshot();
            int codeSnapshot  = _codeDb.TakeSnapshot();

            if (stateSnapshot != -1 || codeSnapshot != -1)
            {
                if (_logger.IsError)
                {
                    _logger.Error($"Uncommitted state ({stateSnapshot}, {codeSnapshot}) when processing from a branch root {branchStateRoot} starting with block {suggestedBlocks[0].ToString(Block.Format.Short)}");
                }
            }

            Keccak snapshotStateRoot = _stateProvider.StateRoot;

            if (branchStateRoot != null && _stateProvider.StateRoot != branchStateRoot)
            {
                /* discarding the other branch data - chain reorganization */
                Metrics.Reorganizations++;
                _storageProvider.Reset();
                _stateProvider.Reset();
                _stateProvider.StateRoot = branchStateRoot;
            }

            var processedBlocks = new Block[suggestedBlocks.Length];

            try
            {
                for (int i = 0; i < suggestedBlocks.Length; i++)
                {
                    processedBlocks[i] = ProcessOne(suggestedBlocks[i], options, blockTracer);
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Committing trees - state root {_stateProvider.StateRoot}");
                    }
                    _stateProvider.CommitTree();
                    _storageProvider.CommitTrees();
                }

                if ((options & ProcessingOptions.ReadOnlyChain) != 0)
                {
                    Restore(stateSnapshot, codeSnapshot, snapshotStateRoot);
                }
                else
                {
                    _stateDb.Commit();
                    _codeDb.Commit();
                }

                return(processedBlocks);
            }
            catch (InvalidBlockException)
            {
                Restore(stateSnapshot, codeSnapshot, snapshotStateRoot);
                throw;
            }
        }
Example #3
0
 public void SetOtherTracer(IBlockTracer blockTracer)
 {
     _otherTracer = blockTracer;
 }
                public Block[] Process(Keccak branchStateRoot, Block[] suggestedBlocks, ProcessingOptions processingOptions, IBlockTracer blockTracer)
                {
                    _logger.Info($"Processing {suggestedBlocks.Last().ToString(Block.Format.Short)}");
                    while (true)
                    {
                        bool notYet = false;
                        for (int i = 0; i < suggestedBlocks.Length; i++)
                        {
                            Keccak hash = suggestedBlocks[i].Hash;
                            if (!_allowed.Contains(hash))
                            {
                                if (_allowedToFail.Contains(hash))
                                {
                                    _allowedToFail.Remove(hash);
                                    BlockProcessed?.Invoke(this, new BlockProcessedEventArgs(suggestedBlocks.Last()));
                                    throw new InvalidBlockException(hash);
                                }

                                notYet = true;
                                break;
                            }
                        }

                        if (notYet)
                        {
                            Thread.Sleep(20);
                        }
                        else
                        {
                            BlockProcessed?.Invoke(this, new BlockProcessedEventArgs(suggestedBlocks.Last()));
                            return(suggestedBlocks);
                        }
                    }
                }
Example #5
0
        private TxReceipt[] ProcessTransactions(Block block, ProcessingOptions processingOptions, IBlockTracer blockTracer)
        {
            _receiptsTracer.SetOtherTracer(blockTracer);
            _receiptsTracer.StartNewBlockTrace(block);

            for (int i = 0; i < block.Transactions.Length; i++)
            {
                if (_logger.IsTrace)
                {
                    _logger.Trace($"Processing transaction {i}");
                }
                Transaction currentTx = block.Transactions[i];
                _receiptsTracer.StartNewTxTrace(currentTx.Hash);
                _transactionProcessor.Execute(currentTx, block.Header, _receiptsTracer);
                _receiptsTracer.EndTxTrace();

                if ((processingOptions & ProcessingOptions.ReadOnlyChain) == 0)
                {
                    TransactionProcessed?.Invoke(this, new TxProcessedEventArgs(_receiptsTracer.TxReceipts[i]));
                }
            }

            return(_receiptsTracer.TxReceipts);
        }
Example #6
0
        public Block Process(Block suggestedBlock, ProcessingOptions options, IBlockTracer blockTracer)
        {
            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}");
            }
            UInt256 totalTransactions = suggestedBlock.TotalTransactions ?? 0;

            if (_logger.IsTrace)
            {
                _logger.Trace($"Total transactions of block {suggestedBlock.ToString(Block.Format.Short)} is {totalTransactions}");
            }

            Block[] processedBlocks = null;
            if (_blockTree.Head == null || totalDifficulty > _blockTree.Head.TotalDifficulty || (options & ProcessingOptions.ForceProcessing) != 0)
            {
                List <Block> blocksToBeAddedToMain = new List <Block>();
                Block        toBeProcessed         = suggestedBlock;
                do
                {
                    blocksToBeAddedToMain.Add(toBeProcessed);
                    toBeProcessed = toBeProcessed.Number == 0 ? null : _blockTree.FindParent(toBeProcessed);
                    if (toBeProcessed == null)
                    {
                        break;
                    }
                } while (!_blockTree.IsMainChain(toBeProcessed.Hash));

                BlockHeader branchingPoint = toBeProcessed?.Header;
                if (branchingPoint != null && branchingPoint.Hash != _blockTree.Head?.Hash)
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Head block was: {_blockTree.Head?.ToString(BlockHeader.Format.Short)}");
                    }
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Branching from: {branchingPoint.ToString(BlockHeader.Format.Short)}");
                    }
                }
                else
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace(branchingPoint == null ? "Setting as genesis block" : $"Adding on top of {branchingPoint.ToString(BlockHeader.Format.Short)}");
                    }
                }

                Keccak stateRoot = branchingPoint?.StateRoot;
                if (_logger.IsTrace)
                {
                    _logger.Trace($"State root lookup: {stateRoot}");
                }

                List <Block> blocksToProcess = new List <Block>();
                Block[]      blocks;
                if ((options & ProcessingOptions.ForceProcessing) != 0)
                {
                    blocksToBeAddedToMain.Clear();
                    blocks    = new Block[1];
                    blocks[0] = suggestedBlock;
                }
                else
                {
                    foreach (Block block in blocksToBeAddedToMain)
                    {
                        if (block.Hash != null && _blockTree.WasProcessed(block.Number, block.Hash))
                        {
                            stateRoot = block.Header.StateRoot;
                            if (_logger.IsTrace)
                            {
                                _logger.Trace($"State root lookup: {stateRoot}");
                            }
                            break;
                        }

                        blocksToProcess.Add(block);
                    }

                    blocks = new Block[blocksToProcess.Count];
                    for (int i = 0; i < blocksToProcess.Count; i++)
                    {
                        blocks[blocks.Length - i - 1] = blocksToProcess[i];
                    }
                }

                if (_logger.IsTrace)
                {
                    _logger.Trace($"Processing {blocks.Length} blocks from state root {stateRoot}");
                }

                for (int i = 0; i < blocks.Length; i++)
                {
                    /* this can happen if the block was loaded as an ancestor and did not go through the recovery queue */
                    _recoveryStep.RecoverData(blocks[i]);
                }

                try
                {
                    processedBlocks = _blockProcessor.Process(stateRoot, blocks, options, blockTracer);
                }
                catch (InvalidBlockException ex)
                {
                    for (int i = 0; i < blocks.Length; i++)
                    {
                        if (blocks[i].Hash == ex.InvalidBlockHash)
                        {
                            _blockTree.DeleteInvalidBlock(blocks[i]);
                            if (_logger.IsDebug)
                            {
                                _logger.Debug($"Skipped processing of {suggestedBlock.ToString(Block.Format.FullHashAndNumber)} because of {blocks[i].ToString(Block.Format.FullHashAndNumber)} is invalid");
                            }
                            return(null);
                        }
                    }
                }

                if ((options & ProcessingOptions.ReadOnlyChain) == 0)
                {
                    _blockTree.UpdateMainChain(blocksToBeAddedToMain.ToArray());
                }
            }
            else
            {
                if (_logger.IsDebug)
                {
                    _logger.Debug($"Skipped processing of {suggestedBlock.ToString(Block.Format.FullHashAndNumber)}, Head = {_blockTree.Head?.ToString(BlockHeader.Format.Short)}, total diff = {totalDifficulty}, head total diff = {_blockTree.Head?.TotalDifficulty}");
                }
            }

            Block lastProcessed = null;

            if (processedBlocks != null && processedBlocks.Length > 0)
            {
                lastProcessed = processedBlocks[processedBlocks.Length - 1];
                if (_logger.IsTrace)
                {
                    _logger.Trace($"Setting total on last processed to {lastProcessed.ToString(Block.Format.Short)}");
                }
                lastProcessed.TotalDifficulty   = suggestedBlock.TotalDifficulty;
                lastProcessed.TotalTransactions = suggestedBlock.TotalTransactions;
            }
            else
            {
                if (_logger.IsDebug)
                {
                    _logger.Debug($"Skipped processing of {suggestedBlock.ToString(Block.Format.FullHashAndNumber)}, last processed is null: {lastProcessed == null}, processedBlocks.Length: {processedBlocks?.Length}");
                }
            }

            return(lastProcessed);
        }
        private void RunProcessingLoop()
        {
            _stats.Start();
            if (_logger.IsDebug)
            {
                _logger.Debug($"Starting block processor - {_blockQueue.Count} blocks waiting in the queue.");
            }

            if (IsEmpty)
            {
                ProcessingQueueEmpty?.Invoke(this, EventArgs.Empty);
            }

            foreach (BlockRef blockRef in _blockQueue.GetConsumingEnumerable(_loopCancellationSource.Token))
            {
                if (blockRef.IsInDb || blockRef.Block == null)
                {
                    throw new InvalidOperationException("Processing loop expects only resolved blocks");
                }

                Block block = blockRef.Block;

                if (_logger.IsTrace)
                {
                    _logger.Trace($"Processing block {block.ToString(Block.Format.Short)}).");
                }

                IBlockTracer tracer = GetDefaultTracer();
                try
                {
                    Block processedBlock = Process(block, blockRef.ProcessingOptions, tracer);
                    if (processedBlock == null)
                    {
                        if (_logger.IsTrace)
                        {
                            _logger.Trace($"Failed / skipped processing {block.ToString(Block.Format.Full)}");
                        }
                    }
                    else
                    {
                        if (_logger.IsTrace)
                        {
                            _logger.Trace($"Processed block {block.ToString(Block.Format.Full)}");
                        }
                        _stats.UpdateStats(block, _recoveryQueue.Count, _blockQueue.Count);
                    }

                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Now {_blockQueue.Count} blocks waiting in the queue.");
                    }
                    if (IsEmpty)
                    {
                        ProcessingQueueEmpty?.Invoke(this, EventArgs.Empty);
                    }
                }
                finally
                {
                    LogDiagnosticTrace(tracer);
                }
            }

            if (_logger.IsInfo)
            {
                _logger.Info("Block processor queue stopped.");
            }
        }
Example #8
0
        // TODO: move to branch processor
        public Block[] Process(Keccak newBranchStateRoot, List <Block> suggestedBlocks, ProcessingOptions options, IBlockTracer blockTracer)
        {
            if (suggestedBlocks.Count == 0)
            {
                return(Array.Empty <Block>());
            }

            BlocksProcessing?.Invoke(this, new BlocksProcessingEventArgs(suggestedBlocks));

            /* We need to save the snapshot state root before reorganization in case the new branch has invalid blocks.
             * In case of invalid blocks on the new branch we will discard the entire branch and come back to
             * the previous head state.*/
            Keccak previousBranchStateRoot = CreateCheckpoint();

            InitBranch(newBranchStateRoot);

            bool readOnly    = (options & ProcessingOptions.ReadOnlyChain) != 0;
            var  blocksCount = suggestedBlocks.Count;

            Block[] processedBlocks = new Block[blocksCount];
            try
            {
                for (int i = 0; i < blocksCount; i++)
                {
                    if (blocksCount > 64 && i % 8 == 0)
                    {
                        if (_logger.IsInfo)
                        {
                            _logger.Info($"Processing part of a long blocks branch {i}/{blocksCount}");
                        }
                    }

                    _witnessCollector.Reset();

                    var(processedBlock, receipts) = ProcessOne(suggestedBlocks[i], options, blockTracer);
                    processedBlocks[i]            = processedBlock;

                    // be cautious here as AuRa depends on processing
                    PreCommitBlock(newBranchStateRoot, suggestedBlocks[i].Number);
                    if (!readOnly)
                    {
                        _witnessCollector.Persist(processedBlock.Hash !);
                        BlockProcessed?.Invoke(this, new BlockProcessedEventArgs(processedBlock, receipts));
                    }

                    // CommitBranch in parts if we have long running branch
                    bool isFirstInBatch = i == 0;
                    bool isLastInBatch  = i == blocksCount - 1;
                    bool isNotAtTheEdge = !isFirstInBatch && !isLastInBatch;
                    bool isCommitPoint  = i % MaxUncommittedBlocks == 0 && isNotAtTheEdge;
                    if (isCommitPoint && readOnly == false)
                    {
                        if (_logger.IsInfo)
                        {
                            _logger.Info($"Commit part of a long blocks branch {i}/{blocksCount}");
                        }
                        CommitBranch();
                        previousBranchStateRoot = CreateCheckpoint();
                        var newStateRoot = suggestedBlocks[i].StateRoot;
                        InitBranch(newStateRoot, false);
                    }
                }

                if (readOnly)
                {
                    RestoreBranch(previousBranchStateRoot);
                }
                else
                {
                    // TODO: move to branch processor
                    CommitBranch();
                }

                return(processedBlocks);
            }
            catch (Exception ex) // try to restore for all cost
            {
                _logger.Trace($"Encountered exception {ex} while processing blocks.");
                RestoreBranch(previousBranchStateRoot);
                throw;
            }
        }
Example #9
0
 public static void LogDiagnosticTrace(
     IBlockTracer blockTracer,
     Keccak blockHash,
     ILogger logger)
 {
Example #10
0
 public void Add(IBlockTracer tracer)
 {
     _childTracers.Add(tracer);
     IsTracingRewards |= tracer.IsTracingRewards;
 }
Example #11
0
        // TODO: block processor pipeline
        private (Block Block, TxReceipt[] Receipts) ProcessOne(Block suggestedBlock, ProcessingOptions options, IBlockTracer blockTracer)
        {
            if (_logger.IsTrace)
            {
                _logger.Trace($"Processing block {suggestedBlock.ToString(Block.Format.Short)} ({options})");
            }

            ApplyDaoTransition(suggestedBlock);
            Block block = PrepareBlockForProcessing(suggestedBlock);

            TxReceipt[] receipts = ProcessBlock(block, blockTracer, options);
            ValidateProcessedBlock(suggestedBlock, options, block, receipts);
            if ((options & ProcessingOptions.StoreReceipts) != 0)
            {
                StoreTxReceipts(block, receipts);
            }

            return(block, receipts);
        }
Example #12
0
 public void Remove(IBlockTracer tracer)
 {
     _childTracers.Remove(tracer);
     IsTracingRewards = _childTracers.Any(t => t.IsTracingRewards);
 }
Example #13
0
        private Block ProcessOne(Block suggestedBlock, ProcessingOptions options, IBlockTracer blockTracer)
        {
            if (_syncConfig.ValidateTree)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn("Collecting trie stats:");
                }
                TrieStats stats = _stateProvider.CollectStats();
                if (stats.MissingNodes > 0)
                {
                    if (_logger.IsError)
                    {
                        _logger.Error(stats.ToString());
                    }
                }
                else
                {
                    if (_logger.IsWarn)
                    {
                        _logger.Warn(stats.ToString());
                    }
                }
            }

            if (suggestedBlock.IsGenesis)
            {
                return(suggestedBlock);
            }

            if (_specProvider.DaoBlockNumber.HasValue && _specProvider.DaoBlockNumber.Value == suggestedBlock.Header.Number)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info("Applying DAO transition");
                }
                ApplyDaoTransition();
            }

            Block block    = PrepareBlockForProcessing(suggestedBlock);
            var   receipts = ProcessTransactions(block, options, blockTracer);

            SetReceiptsRootAndBloom(block, receipts);
            ApplyMinerRewards(block, blockTracer);

            _stateProvider.Commit(_specProvider.GetSpec(block.Number));

            block.Header.StateRoot = _stateProvider.StateRoot;
            block.Header.Hash      = BlockHeader.CalculateHash(block.Header);
            if ((options & ProcessingOptions.NoValidation) == 0 && !_blockValidator.ValidateProcessedBlock(block, receipts, suggestedBlock))
            {
                if (_logger.IsError)
                {
                    _logger.Error($"Processed block is not valid {suggestedBlock.ToString(Block.Format.FullHashAndNumber)}");
                }
                throw new InvalidBlockException(suggestedBlock.Hash);
            }

            if ((options & ProcessingOptions.StoreReceipts) != 0)
            {
                StoreTxReceipts(block, receipts);
            }

            if ((options & ProcessingOptions.StoreTraces) != 0)
            {
                StoreTraces(blockTracer as ParityLikeBlockTracer);
            }

            BlockProcessed?.Invoke(this, new BlockProcessedEventArgs(block));
            return(block);
        }
        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];
Example #15
0
        public Block[] Process(Keccak newBranchStateRoot, List <Block> suggestedBlocks, ProcessingOptions options, IBlockTracer blockTracer)
        {
            if (suggestedBlocks.Count == 0)
            {
                return(Array.Empty <Block>());
            }

            /* We need to save the snapshot state root before reorganization in case the new branch has invalid blocks.
             * In case of invalid blocks on the new branch we will discard the entire branch and come back to
             * the previous head state.*/
            Keccak previousBranchStateRoot = CreateCheckpoint();

            InitBranch(newBranchStateRoot);

            bool readOnly = (options & ProcessingOptions.ReadOnlyChain) != 0;

            Block[] processedBlocks = new Block[suggestedBlocks.Count];
            try
            {
                for (int i = 0; i < suggestedBlocks.Count; i++)
                {
                    processedBlocks[i] = ProcessOne(suggestedBlocks[i], options, blockTracer);

                    // be cautious here as AuRa depends on processing
                    PreCommitBlock(newBranchStateRoot); // only needed if we plan to read state root?
                    if (!readOnly)
                    {
                        BlockProcessed?.Invoke(this, new BlockProcessedEventArgs(processedBlocks[i]));
                    }
                }

                if (readOnly)
                {
                    RestoreBranch(previousBranchStateRoot);
                }
                else
                {
                    CommitBranch();
                }

                return(processedBlocks);
            }
            catch (Exception) // try to restore for all cost
            {
                RestoreBranch(previousBranchStateRoot);
                throw;
            }
        }
Example #16
0
 public static CancellationBlockTracer WithCancellation(this IBlockTracer txTracer, CancellationToken cancellationToken) =>
 new CancellationBlockTracer(txTracer, cancellationToken);
Example #17
0
        private void RunProcessingLoop()
        {
            _stats.Start();
            if (_logger.IsDebug)
            {
                _logger.Debug($"Starting block processor - {_blockQueue.Count} blocks waiting in the queue.");
            }

            if (_blockQueue.Count == 0)
            {
                ProcessingQueueEmpty?.Invoke(this, EventArgs.Empty);
            }

            foreach (BlockRef blockRef in _blockQueue.GetConsumingEnumerable(_loopCancellationSource.Token))
            {
                if (blockRef.IsInDb || blockRef.Block == null)
                {
                    throw new InvalidOperationException("Processing loop expects only resolved blocks");
                }

                Block block = blockRef.Block;

                if (_logger.IsTrace)
                {
                    _logger.Trace($"Processing block {block.ToString(Block.Format.Short)}).");
                }

                IBlockTracer tracer = NullBlockTracer.Instance;
                if ((blockRef.ProcessingOptions & ProcessingOptions.StoreTraces) != 0)
                {
                    tracer = new ParityLikeBlockTracer(ParityTraceTypes.Trace | ParityTraceTypes.StateDiff);
                }

                Block processedBlock = Process(block, blockRef.ProcessingOptions, tracer);
                if (processedBlock == null)
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Failed / skipped processing {block.ToString(Block.Format.Full)}");
                    }
                }
                else
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Processed block {block.ToString(Block.Format.Full)}");
                    }
                    _stats.UpdateStats(block, _recoveryQueue.Count, _blockQueue.Count);
                }

                if (_logger.IsTrace)
                {
                    _logger.Trace($"Now {_blockQueue.Count} blocks waiting in the queue.");
                }
                if (_blockQueue.Count == 0)
                {
                    ProcessingQueueEmpty?.Invoke(this, EventArgs.Empty);
                }
            }

            if (_logger.IsTrace)
            {
                _logger.Trace($"Return");
            }
        }
Example #18
0
        private (Block Block, TxReceipt[] Receipts) ProcessOne(Block suggestedBlock, ProcessingOptions options, IBlockTracer blockTracer)
        {
            ApplyDaoTransition(suggestedBlock);
            Block block = PrepareBlockForProcessing(suggestedBlock);

            TxReceipt[] receipts = ProcessBlock(block, blockTracer, options);
            ValidateProcessedBlock(suggestedBlock, options, block, receipts);
            if ((options & ProcessingOptions.StoreReceipts) != 0)
            {
                StoreTxReceipts(block, receipts);
            }

            return(block, receipts);
        }
                public Block[] Process(Keccak newBranchStateRoot, List <Block> suggestedBlocks, ProcessingOptions processingOptions, IBlockTracer blockTracer)
                {
                    if (blockTracer != NullBlockTracer.Instance)
                    {
                        // this is for block reruns on failure for diag tracing
                        throw new InvalidBlockException(Keccak.Zero);
                    }

                    _logger.Info($"Processing {suggestedBlocks.Last().ToString(Block.Format.Short)}");
                    while (true)
                    {
                        bool notYet = false;
                        for (int i = 0; i < suggestedBlocks.Count; i++)
                        {
                            Keccak hash = suggestedBlocks[i].Hash;
                            if (!_allowed.Contains(hash))
                            {
                                if (_allowedToFail.Contains(hash))
                                {
                                    _allowedToFail.Remove(hash);
                                    BlockProcessed?.Invoke(this, new BlockProcessedEventArgs(suggestedBlocks.Last(), Array.Empty <TxReceipt>()));
                                    throw new InvalidBlockException(hash);
                                }

                                notYet = true;
                                break;
                            }
                        }

                        if (notYet)
                        {
                            Thread.Sleep(20);
                        }
                        else
                        {
                            BlockProcessed?.Invoke(this, new BlockProcessedEventArgs(suggestedBlocks.Last(), Array.Empty <TxReceipt>()));
                            return(suggestedBlocks.ToArray());
                        }
                    }
                }
Example #20
0
 public Block[] Process(Keccak newBranchStateRoot, List <Block> suggestedBlocks, ProcessingOptions processingOptions, IBlockTracer blockTracer)
 {
     return(suggestedBlocks.ToArray());
 }