Esempio n. 1
0
        private void MoveToMain(Block block)
        {
            if (_logger.IsTrace)
            {
                _logger.Trace($"Moving {block.ToString(Block.Format.Short)} to main");
            }

            ChainLevelInfo level = LoadLevel(block.Number);
            int?           index = FindIndex(block.Hash, level);

            if (index == null)
            {
                throw new InvalidOperationException($"Cannot move unknown block {block.ToString(Block.Format.HashAndNumber)} to main");
            }


            BlockInfo info = level.BlockInfos[index.Value];

            info.WasProcessed = true;
            if (index.Value != 0)
            {
                (level.BlockInfos[index.Value], level.BlockInfos[0]) = (level.BlockInfos[0], level.BlockInfos[index.Value]);
            }

            // tks: in testing chains we have a chain full of processed blocks that we process again
            //if (level.HasBlockOnMainChain)
            //{
            //    throw new InvalidOperationException("When moving to main encountered a block in main on the same level");
            //}

            level.HasBlockOnMainChain = true;
            PersistLevel(block.Number, level);

            BlockAddedToMain?.Invoke(this, new BlockEventArgs(block));

            if (block.IsGenesis || block.TotalDifficulty > (Head?.TotalDifficulty ?? 0))
            {
                if (block.Number == 0)
                {
                    Genesis = block.Header;
                }

                if (block.TotalDifficulty == null)
                {
                    throw new InvalidOperationException("Head block with null total difficulty");
                }

                UpdateHeadBlock(block);
            }

            for (int i = 0; i < block.Transactions.Length; i++)
            {
                _transactionPool.RemoveTransaction(block.Transactions[i].Hash);
            }

            if (_logger.IsTrace)
            {
                _logger.Trace($"Block {block.ToString(Block.Format.Short)} added to main chain");
            }
        }
Esempio n. 2
0
 public UnprocessedBlockTreeWrapper(IBlockTree blockTree)
 {
     _blockTree = blockTree;
     _blockTree.NewHeadBlock          += (sender, args) => NewHeadBlock?.Invoke(sender, args);
     _blockTree.NewBestSuggestedBlock += (sender, args) => NewBestSuggestedBlock?.Invoke(sender, args);
     _blockTree.BlockAddedToMain      += (sender, args) => BlockAddedToMain?.Invoke(sender, args);
 }
Esempio n. 3
0
        private void MoveToMain(ChainLevelInfo level, Block block)
        {
            int?index = FindIndex(block.Hash, level);

            if (index.Value != 0)
            {
                (level.BlockInfos[index.Value], level.BlockInfos[0]) =
                    (level.BlockInfos[0], level.BlockInfos[index.Value]);
            }

            BlockInfo info = level.BlockInfos[index.Value];

            if (!info.WasProcessed)
            {
                throw new InvalidOperationException("Cannot move unprocessed blocks to main");
            }

            // TODO: in testing chains we have a chain full of processed blocks that we process again
            //if (level.HasBlockOnMainChain)
            //{
            //    throw new InvalidOperationException("When moving to main encountered a block in main on the same level");
            //}

            level.HasBlockOnMainChain = true;
            UpdateLevel(block.Number, level);

            BlockAddedToMain?.Invoke(this, new BlockEventArgs(block));

            if (block.TotalDifficulty > (Head?.TotalDifficulty ?? 0))
            {
                if (block.Number == 0)
                {
                    Genesis = block.Header;
                }

                UpdateHeadBlock(block);
            }
        }