Exemplo n.º 1
0
        public HeaderNode AddToBlockIndex(BlockHeader header)
        {
            using (GlobalLocks.WriteOnMainAsync().GetAwaiter().GetResult())
            {
                // Check for duplicate
                if (TryGetKnownHeaderNode(header.Hash, out HeaderNode? headerNode))
                {
                    return(headerNode);
                }

                if (!TryGetKnownHeaderNode(header.PreviousBlockHash, out HeaderNode? previousHeader))
                {
                    ThrowHelper.ThrowNotSupportedException("Previous hash not found (shouldn't happen).");
                }

                headerNode = new HeaderNode(header, previousHeader);

                if (BestHeader == null || BestHeader.ChainWork < headerNode.ChainWork)
                {
                    BestHeader = headerNode;
                }

                HeadersTree.Add(headerNode);
                _blockHeaderRepository.TryAdd(header);

                return(headerNode);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// The consumer that perform validation.
        /// </summary>
        /// <param name="cancellation">The cancellation.</param>
        private async Task ValidationWorkAsync(CancellationToken cancellation)
        {
            await foreach (HeadersToValidate request in _headersToValidate.Reader.ReadAllAsync(cancellation))
            {
                if (request.Headers.Count == 0)
                {
                    continue;                         //if there aren't headers to validate, ignore the request
                }
                _logger.LogDebug("Validating {HeadersCount} headers", request.Headers.Count);

                var newValidatedHeaderNodes = new List <HeaderNode>();

                HeaderNode?          lastValidatedHeaderNode  = null;
                BlockHeader?         lastValidatedBlockHeader = null;
                BlockValidationState?state = null;
                BlockHeader?         invalidBlockHeader = null;

                /// If during validation a new header is found, this will be set to true.
                /// Once a new header is found, every other new header is expected to be new too
                /// because we don't store unconnecting headers.
                //bool hasNewHeaders = false;

                int validatedHeaders = 0;

                using (await GlobalLocks.WriteOnMainAsync())
                {
                    foreach (BlockHeader header in request.Headers)
                    {
                        using (_logger.BeginScope("Validating header {ValidationRuleType}", header !.Hash))
                        {
                            if (!AcceptBlockHeaderLocked(header, out state, out HeaderNode? validatedHeaderNode, out bool newHeaderFound))
                            {
                                invalidBlockHeader = header;
                                break;
                            }

                            validatedHeaders++;
                            lastValidatedBlockHeader = header;
                            lastValidatedHeaderNode  = validatedHeaderNode;
                            if (newHeaderFound)
                            {
                                //hasNewHeaders = true;
                                newValidatedHeaderNodes.Add(validatedHeaderNode);
                            }
                        }
                    }
                }

                // publish events out of lock
                if (state !.IsInvalid())
                {
                    // signal header validation failed
                    _eventBus.Publish(new BlockHeaderValidationFailed(invalidBlockHeader !, state, request.Peer));
                }
Exemplo n.º 3
0
        /// <summary>
        /// The consumer that perform validation.
        /// </summary>
        /// <param name="cancellation">The cancellation.</param>
        private async Task ValidationWorkAsync(CancellationToken cancellation)
        {
            await foreach (BlockToValidate request in _blocksToValidate.Reader.ReadAllAsync(cancellation))
            {
                using (IDisposable logScope = _logger.BeginScope("Validating block {BlockHash}", request.Block.Header !.Hash))
                {
                    BlockValidationState?state = null;

                    bool isNew = false;
                    using (await GlobalLocks.WriteOnMainAsync())
                    {
                        AcceptBlockLocked(request.Block, out state, out isNew);
                    }

                    // publish events out of lock
                    if (state !.IsInvalid())
                    {
                        // signal header validation failed
                        _eventBus.Publish(new BlockValidationFailed(request.Block, state, request.Peer));
                    }