/// <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 }