Example #1
0
        /// <summary>
        /// Processes the headers.
        /// It's invoked because of "headers" or "cmpctblock" message
        /// </summary>
        /// <param name="headers">The headers.</param>
        /// <returns></returns>
        private async Task <bool> ProcessHeadersAsync(BlockHeader[] headers)
        {
            int protocolVersion = PeerContext.NegotiatedProtocolVersion.Version;
            int headersCount    = headers.Length;

            if (headersCount == 0)
            {
                logger.LogDebug("Peer didn't returned any headers, let's assume we reached its tip.");
                return(true);
            }

            using (GlobalLocks.ReadOnMainAsync().GetAwaiter().GetResult())
            {
                if (await HandleAsNotConnectingAnnouncementAsync(headers).ConfigureAwait(false))
                {
                    // fully handled as non connecting announcement
                    return(true);
                }

                // compute hashes in parallel to speed up the operation and check sent headers are sequential.
                Parallel.ForEach(headers, header =>
                {
                    header.Hash = _blockHeaderHashCalculator.ComputeHash(header, protocolVersion);
                });
            }

            // Ensure headers are consecutive.
            for (int i = 1; i < headersCount; i++)
            {
                if (headers[i].PreviousBlockHash != headers[i - 1].Hash)
                {
                    Misbehave(20, "Non continuous headers sequence.");
                    return(false);
                }
            }

            //enqueue headers for validation
            await _headerValidator.RequestValidationAsync(new HeadersToValidate(headers, PeerContext)).ConfigureAwait(false);

            return(true);
        }
 protected UInt256 ComputeHash(BlockHeader header)
 {
     return(_blockHeaderHashCalculator.ComputeHash(header, protocolVersion: 0)); //protocol version doesn't matter for hash
 }