private static List <long> GetStaleBlockIds(BitcoinDataLayer bitcoinDataLayer) { SummaryBlockDataSet summaryBlockDataSet = bitcoinDataLayer.GetSummaryBlockDataSet(); // KEY: The 256-bit hash of the block // VALUE: The summary block data as represented by an instance of DBData.SummaryBlockDataSet.BlockRow. Dictionary <ParserData.ByteArray, SummaryBlockDataSet.SummaryBlockRow> blockDictionary = summaryBlockDataSet.SummaryBlock.ToDictionary( b => new ParserData.ByteArray(b.BlockHash), b => b); SummaryBlockDataSet.SummaryBlockRow lastBlock = summaryBlockDataSet.SummaryBlock.OrderByDescending(b => b.BlockId).First(); ParserData.ByteArray previousBlockHash = ParserData.ByteArray.Empty; ParserData.ByteArray currentBlockHash = new ParserData.ByteArray(lastBlock.BlockHash); // A hashset containing the IDs of all active blocks. Active as in not stale. HashSet <long> activeBlockIds = new HashSet <long>(); // Loop through blocks starting from the last one and going from one block to the next as indicated by PreviousBlockHash. // Collect all the block IDs for the blocks that we go through in activeBlockIds. // After this loop, blocks that we did not loop through are stale blocks. while (currentBlockHash.IsZeroArray() == false) { SummaryBlockDataSet.SummaryBlockRow summaryBlockRow; if (blockDictionary.TryGetValue(currentBlockHash, out summaryBlockRow)) { // The current block was found in the list of blocks. activeBlockIds.Add(summaryBlockRow.BlockId); previousBlockHash = currentBlockHash; currentBlockHash = new ParserData.ByteArray(summaryBlockRow.PreviousBlockHash); } else { // The current block was not found in the list of blocks. // This should never happen for a valid blockchain content. throw new InvalidBlockchainContentException(string.Format(CultureInfo.InvariantCulture, "Block with hash [{0}] makes a reference to an unknown block with hash: [{1}]", previousBlockHash, currentBlockHash)); } } // At this point activeBlockIds contains the IDs of all active blocks. // Parse the list of all blocks and collect those whose IDs are not in activeBlockIds. return((from sumaryBlockRow in summaryBlockDataSet.SummaryBlock where activeBlockIds.Contains(sumaryBlockRow.BlockId) == false select sumaryBlockRow.BlockId).ToList()); }
private static List<long> GetStaleBlockIds(BitcoinDataLayer bitcoinDataLayer) { SummaryBlockDataSet summaryBlockDataSet = bitcoinDataLayer.GetSummaryBlockDataSet(); // KEY: The 256-bit hash of the block // VALUE: The summary block data as represented by an instance of DBData.SummaryBlockDataSet.BlockRow. Dictionary<ParserData.ByteArray, SummaryBlockDataSet.SummaryBlockRow> blockDictionary = summaryBlockDataSet.SummaryBlock.ToDictionary( b => new ParserData.ByteArray(b.BlockHash), b => b); SummaryBlockDataSet.SummaryBlockRow lastBlock = summaryBlockDataSet.SummaryBlock.OrderByDescending(b => b.BlockId).First(); ParserData.ByteArray previousBlockHash = ParserData.ByteArray.Empty; ParserData.ByteArray currentBlockHash = new ParserData.ByteArray(lastBlock.BlockHash); // A hashset containing the IDs of all active blocks. Active as in not stale. HashSet<long> activeBlockIds = new HashSet<long>(); // Loop through blocks starting from the last one and going from one block to the next as indicated by PreviousBlockHash. // Collect all the block IDs for the blocks that we go through in activeBlockIds. // After this loop, blocks that we did not loop through are stale blocks. while (currentBlockHash.IsZeroArray() == false) { SummaryBlockDataSet.SummaryBlockRow summaryBlockRow; if (blockDictionary.TryGetValue(currentBlockHash, out summaryBlockRow)) { // The current block was found in the list of blocks. activeBlockIds.Add(summaryBlockRow.BlockId); previousBlockHash = currentBlockHash; currentBlockHash = new ParserData.ByteArray(summaryBlockRow.PreviousBlockHash); } else { // The current block was not found in the list of blocks. // This should never happen for a valid blockchain content. throw new InvalidBlockchainContentException(string.Format(CultureInfo.InvariantCulture, "Block with hash [{0}] makes a reference to an unknown block with hash: [{1}]", previousBlockHash, currentBlockHash)); } } // At this point activeBlockIds contains the IDs of all active blocks. // Parse the list of all blocks and collect those whose IDs are not in activeBlockIds. return (from sumaryBlockRow in summaryBlockDataSet.SummaryBlock where activeBlockIds.Contains(sumaryBlockRow.BlockId) == false select sumaryBlockRow.BlockId).ToList(); }