Esempio n. 1
0
        private async Task HandleMissedBlocksAsync(Block arrivedBlock)
        {
            List <Block> missedBlocks = new List <Block>
            {
                arrivedBlock
            };
            var currentHeader = arrivedBlock.Header;

            while (true)
            {
                Block missedBlock = await RpcClient.GetBlockAsync(currentHeader.HashPrevBlock).ConfigureAwait(false);

                if (missedBlocks.Count > 144)
                {
                    missedBlocks.RemoveFirst();
                }

                currentHeader = missedBlock.Header;
                currentHeader.PrecomputeHash(false, true);
                missedBlocks.Add(missedBlock);

                if (currentHeader.GetHash() == Network.GenesisHash)
                {
                    var processedBlocksClone    = ProcessedBlocks.ToArray();
                    var processedReversedBlocks = processedBlocksClone.Reverse();
                    ProcessedBlocks.Clear();
                    foreach (var processedBlock in processedReversedBlocks)
                    {
                        OnReorg?.Invoke(this, processedBlock);
                    }
                    break;
                }

                // If we found the proper chain.
                var foundPrevBlock = ProcessedBlocks.FirstOrDefault(x => x.GetHash() == currentHeader.HashPrevBlock);
                if (foundPrevBlock != null)
                {
                    // If the last block hash is not what we found, then we missed a reorg also.
                    if (foundPrevBlock.GetHash() != ProcessedBlocks.Last().GetHash())
                    {
                        ReorgToBlock(foundPrevBlock);
                    }

                    break;
                }
            }

            missedBlocks.Reverse();
            foreach (var b in missedBlocks)
            {
                AddBlock(b);
            }
        }
Esempio n. 2
0
        private void ReorgToBlock(BlockHeader correctBlock)
        {
            var index         = ProcessedBlocks.IndexOf(correctBlock);
            int countToRemove = ProcessedBlocks.Count - (index + 1);
            var toRemoves     = ProcessedBlocks.TakeLast(countToRemove).ToList();

            ProcessedBlocks.RemoveRange(index + 1, countToRemove);
            toRemoves.Reverse();
            foreach (var toRemove in toRemoves)
            {
                OnReorg?.Invoke(this, toRemove);
            }
        }