Exemple #1
0
        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);
                }
            }));
        }