internal void Index(ChainBase chain, int startHeight) { List <ChainPartEntry> entries = new List <ChainPartEntry>(((chain.Height - startHeight) / BlockHeaderPerRow) + 5); startHeight = startHeight - (startHeight % BlockHeaderPerRow); ChainPartEntry chainPart = null; for (int i = startHeight; i <= chain.Tip.Height; i++) { if (chainPart == null) { chainPart = new ChainPartEntry() { ChainOffset = i } } ; var block = chain.GetBlock(i); chainPart.BlockHeaders.Add(block.Header); if (chainPart.BlockHeaders.Count == BlockHeaderPerRow) { entries.Add(chainPart); chainPart = null; } } if (chainPart != null) { entries.Add(chainPart); } Index(entries); }
public IAsyncEnumerable <ChainBlockHeader> GetChainChangesUntilFork(ChainedBlock currentTip, bool forkIncluded, CancellationToken cancellation = default(CancellationToken)) { return(new AsyncEnumerable <ChainBlockHeader>(async yield => { var oldTip = currentTip; var table = Configuration.GetChainTable(); List <ChainBlockHeader> blocks = new List <ChainBlockHeader>(); async Task ProcessChainPart(ChainPartEntry chainPart) { int height = chainPart.ChainOffset + chainPart.BlockHeaders.Count - 1; foreach (var block in chainPart.BlockHeaders.Reverse <BlockHeader>()) { if (currentTip == null && oldTip != null) { throw new InvalidOperationException("No fork found, the chain stored in azure is probably different from the one of the provided input"); } if (oldTip == null || height > currentTip.Height) { await yield.ReturnAsync(CreateChainChange(height, block)); } else { if (height < currentTip.Height) { currentTip = currentTip.FindAncestorOrSelf(height); } var chainChange = CreateChainChange(height, block); if (chainChange.BlockId == currentTip.HashBlock) { if (forkIncluded) { await yield.ReturnAsync(chainChange); } yield.Break(); } await yield.ReturnAsync(chainChange); currentTip = currentTip.Previous; } height--; } } var enumerator = await ExecuteBalanceQuery(table, new TableQuery <DynamicTableEntity>(), new[] { 1, 2, 10 }).GetAsyncEnumeratorAsync(cancellation); while (await enumerator.MoveNextAsync(cancellation)) { var chainPart = new ChainPartEntry(enumerator.Current, ConsensuFactory); await ProcessChainPart(chainPart); } foreach (var chainPart in (await table.ExecuteQueryAsync(new TableQuery <DynamicTableEntity>())).Skip(2) .Select(e => new ChainPartEntry(e, ConsensuFactory))) { await ProcessChainPart(chainPart); } })); }