Example #1
0
        public void AddNewBlock(Block block, Node nodeWhoSentTheBlock)
        {
            if (block.TotalDifficulty == null)
            {
                throw new InvalidOperationException("Cannot add a block with unknown total difficulty");
            }

            _pool.TryFind(nodeWhoSentTheBlock.Id, out PeerInfo peerInfo);
            if (peerInfo == null)
            {
                string errorMessage = $"Received a new block from an unknown peer {nodeWhoSentTheBlock:c} {nodeWhoSentTheBlock.Id} {_pool.PeerCount}";
                if (_logger.IsDebug)
                {
                    _logger.Debug(errorMessage);
                }
                return;
            }

            if ((block.TotalDifficulty ?? 0) > peerInfo.TotalDifficulty)
            {
                if (_logger.IsTrace)
                {
                    _logger.Trace($"ADD NEW BLOCK Updating header of {peerInfo} from {peerInfo.HeadNumber} {peerInfo.TotalDifficulty} to {block.Number} {block.TotalDifficulty}");
                }
                peerInfo.HeadNumber      = block.Number;
                peerInfo.HeadHash        = block.Hash;
                peerInfo.TotalDifficulty = block.TotalDifficulty ?? peerInfo.TotalDifficulty;
            }

            if ((block.TotalDifficulty ?? 0) < _blockTree.BestSuggestedHeader.TotalDifficulty)
            {
                return;
            }

            lock (_recentlySuggested)
            {
                if (_recentlySuggested.Get(block.Hash) != null)
                {
                    return;
                }
                _recentlySuggested.Set(block.Hash, _dummyValue);
            }

            if (block.Number > _blockTree.BestKnownNumber + 8)
            {
                // ignore blocks when syncing in a simple non-locking way
                _synchronizer.RequestSynchronization(SyncTriggerType.NewDistantBlock);
                return;
            }

            if (_logger.IsTrace)
            {
                _logger.Trace($"Adding new block {block.ToString(Block.Format.Short)}) from {nodeWhoSentTheBlock:c}");
            }

            if (!_sealValidator.ValidateSeal(block.Header))
            {
                throw new EthSynchronizationException("Peer sent a block with an invalid seal");
            }

            if (block.Number <= _blockTree.BestKnownNumber + 1)
            {
                if (_logger.IsInfo)
                {
                    string authorString = block.Author == null ? string.Empty : "sealed by " + (KnownAddresses.GoerliValidators.ContainsKey(block.Author) ? KnownAddresses.GoerliValidators[block.Author] : block.Author?.ToString());
                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Discovered a new block {string.Empty.PadLeft(9 - block.Number.ToString().Length, ' ')}{block.ToString(Block.Format.HashNumberAndTx)} {authorString}, sent by {nodeWhoSentTheBlock:s}");
                    }
                }

                if (_logger.IsTrace)
                {
                    _logger.Trace($"{block}");
                }

                if (_synchronizer.SyncMode == SyncMode.Full)
                {
                    AddBlockResult result = _blockTree.SuggestBlock(block);
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"{block.Hash} ({block.Number}) adding result is {result}");
                    }
                    if (result == AddBlockResult.UnknownParent)
                    {
                        _synchronizer.RequestSynchronization(SyncTriggerType.Reorganization);
                    }
                }
            }
            else
            {
                if (_logger.IsTrace)
                {
                    _logger.Trace($"Received a block {block.Hash} ({block.Number}) from {nodeWhoSentTheBlock} - need to resync");
                }
                _synchronizer.RequestSynchronization(SyncTriggerType.NewNearBlock);
            }
        }