Exemplo n.º 1
0
                public Block[] Process(Keccak newBranchStateRoot, List <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.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()));
                                    throw new InvalidBlockException(hash);
                                }

                                notYet = true;
                                break;
                            }
                        }

                        if (notYet)
                        {
                            Thread.Sleep(20);
                        }
                        else
                        {
                            BlockProcessed?.Invoke(this, new BlockProcessedEventArgs(suggestedBlocks.Last()));
                            return(suggestedBlocks.ToArray());
                        }
                    }
                }
Exemplo n.º 2
0
        private Block ProcessOne(Block suggestedBlock, ProcessingOptions options, IBlockTracer blockTracer)
        {
            Block block;

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

                block = PrepareBlockForProcessing(suggestedBlock);
                _additionalBlockProcessor?.PreProcess(block, options);

                var receipts = ProcessTransactions(block, options, blockTracer);
                SetReceiptsRoot(block, receipts);
                ApplyMinerRewards(block, blockTracer);

                _stateProvider.Commit(_specProvider.GetSpec(block.Number));
                block.Header.StateRoot = _stateProvider.StateRoot;
                block.Header.Hash      = BlockHeader.CalculateHash(block.Header);

                _additionalBlockProcessor?.PostProcess(block, receipts, options);

                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)}");
                    }
                    // if (_logger.IsError) _logger.Error($"State: {_stateProvider.DumpState()}");
                    throw new InvalidBlockException(suggestedBlock.Hash);
                }

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

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

            if ((options & ProcessingOptions.ReadOnlyChain) == 0)
            {
                BlockProcessed?.Invoke(this, new BlockProcessedEventArgs(block));
            }

            return(block);
        }
Exemplo n.º 3
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>());
            }

            /* 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++)
                {
                    if (suggestedBlocks.Count > 64 && i % 8 == 0)
                    {
                        if (_logger.IsInfo)
                        {
                            _logger.Info($"Processing part of a long blocks branch {i}/{suggestedBlocks.Count}");
                        }
                    }

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

                    // 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(processedBlock, receipts));
                    }
                }

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

                return(processedBlocks);
            }
            catch (Exception) // try to restore for all cost
            {
                RestoreBranch(previousBranchStateRoot);
                throw;
            }
        }
Exemplo n.º 4
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 (InvalidBlockException)
            {
                RestoreBranch(previousBranchStateRoot);
                throw;
            }
        }
Exemplo n.º 5
0
                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(suggestedBlocks[0]);
                    }

                    _logger.Info($"Processing {suggestedBlocks.Last().ToString(Block.Format.Short)}");
                    while (true)
                    {
                        bool notYet = false;
                        for (int i = 0; i < suggestedBlocks.Count; i++)
                        {
                            BlocksProcessing?.Invoke(this, new BlocksProcessingEventArgs(suggestedBlocks));
                            Block  suggestedBlock = suggestedBlocks[i];
                            Keccak hash           = suggestedBlock.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(suggestedBlock);
                                }

                                notYet = true;
                                break;
                            }
                        }

                        if (notYet)
                        {
                            Thread.Sleep(20);
                        }
                        else
                        {
                            BlockProcessed?.Invoke(this, new BlockProcessedEventArgs(suggestedBlocks.Last(), Array.Empty <TxReceipt>()));
                            return(suggestedBlocks.ToArray());
                        }
                    }
                }
Exemplo n.º 6
0
        public Block[] Process(Keccak branchStateRoot, Block[] suggestedBlocks, ProcessingOptions options, IBlockTracer blockTracer)
        {
            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 readOnly        = (options & ProcessingOptions.ReadOnlyChain) != 0;
            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 (!readOnly)
                    {
                        BlockProcessed?.Invoke(this, new BlockProcessedEventArgs(processedBlocks[i]));
                    }
                }

                if (readOnly)
                {
                    _receiptsTracer.BeforeRestore(_stateProvider);
                    Restore(stateSnapshot, codeSnapshot, snapshotStateRoot);
                }
                else
                {
                    _stateDb.Commit();
                    _codeDb.Commit();
                }

                return(processedBlocks);
            }
            catch (InvalidBlockException)
            {
                Restore(stateSnapshot, codeSnapshot, snapshotStateRoot);
                throw;
            }
        }
Exemplo n.º 7
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;
            int  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}. Block: {suggestedBlocks[i]}");
                        }
                    }

                    _witnessCollector.Reset();
                    (Block processedBlock, TxReceipt[] 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();
                        Keccak?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;
            }
        }
Exemplo n.º 8
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);
        }