public BlockHeader GetHeader(ChainedHeader chainedHeader, uint256 hash) { if (this.nearTipHeaders.TryGetValue(hash, out BlockHeader blockHeader)) { return(blockHeader); } if (this.recentHeaders.TryGetValue(hash, out blockHeader)) { return(blockHeader); } ReadOnlySpan <byte> bytes = hash.ToReadOnlySpan(); lock (this.locker) { bytes = this.leveldb.Get(DBH.Key(HeaderTableName, bytes)); } if (bytes == null) { throw new ApplicationException("Header must exist if requested"); } blockHeader = this.network.Consensus.ConsensusFactory.CreateBlockHeader(); blockHeader.FromBytes(bytes.ToArray(), this.network.Consensus.ConsensusFactory); // If the header is 500 blocks behind tip or 100 blocks ahead cache it. if ((chainedHeader.Height > this.ChainIndexer.Height - 500) && (chainedHeader.Height <= this.ChainIndexer.Height + 100)) { this.nearTipHeaders.AddOrUpdate(hash, blockHeader); } else { this.recentHeaders.AddOrUpdate(hash, blockHeader); } return(blockHeader); }