Exemplo n.º 1
0
        public async Task ProcessBlockExecutionResultAsync(Chain chain, BlockExecutionResult blockExecutionResult)
        {
            if (blockExecutionResult.ExecutedFailedBlocks.Any() ||
                blockExecutionResult.SuccessBlockExecutedSets.Count == 0 ||
                blockExecutionResult.SuccessBlockExecutedSets.Last().Height < chain.BestChainHeight)
            {
                await SetBlockExecutionStatusAsync(blockExecutionResult.ExecutedFailedBlocks.Select(b => b.GetHash()),
                                                   ChainBlockLinkExecutionStatus.ExecutionFailed);

                await _blockchainService.RemoveLongestBranchAsync(chain);

                Logger.LogDebug("No block executed successfully or no block is higher than best chain.");
                return;
            }

            var lastExecutedSuccessBlock = blockExecutionResult.SuccessBlockExecutedSets.Last();
            await _blockchainService.SetBestChainAsync(chain, lastExecutedSuccessBlock.Height,
                                                       lastExecutedSuccessBlock.GetHash());

            await SetBlockExecutionStatusAsync(blockExecutionResult.SuccessBlockExecutedSets.Select(b => b.GetHash()),
                                               ChainBlockLinkExecutionStatus.ExecutionSuccess);

            await LocalEventBus.PublishAsync(new BlocksExecutionSucceededEvent
            {
                BlockExecutedSets = blockExecutionResult.SuccessBlockExecutedSets
            });

            Logger.LogInformation(
                $"Attach blocks to best chain, best chain hash: {chain.BestChainHash}, height: {chain.BestChainHeight}");
        }
Exemplo n.º 2
0
        public async Task AttachBlockAsync(Block block)
        {
            var chain = await _blockchainService.GetChainAsync();

            var status = await _blockchainService.AttachBlockToChainAsync(chain, block);

            if (!status.HasFlag(BlockAttachOperationStatus.LongestChainFound))
            {
                Logger.LogDebug($"Try to attach to chain but the status is {status}.");
                return;
            }

            var notExecutedChainBlockLinks =
                await _chainBlockLinkService.GetNotExecutedChainBlockLinksAsync(chain.LongestChainHash);

            var notExecutedBlocks =
                await _blockchainService.GetBlocksAsync(notExecutedChainBlockLinks.Select(l => l.BlockHash));

            var executionResult = new BlockExecutionResult();

            try
            {
                executionResult = await _blockchainExecutingService.ExecuteBlocksAsync(notExecutedBlocks);
            }
            catch (Exception e)
            {
                Logger.LogError(e, "Block execute fails.");
                throw;
            }
            finally
            {
                await _blockExecutionResultProcessingService.ProcessBlockExecutionResultAsync(chain, executionResult);
            }
        }
        public async Task Process_LessThanBestChainHeight_BlockExecutionResult()
        {
            var chain = await _blockchainService.GetChainAsync();

            await _blockchainService.RemoveLongestBranchAsync(chain);

            var block = _kernelTestHelper.GenerateBlock(1, Hash.Empty);
            await _blockchainService.AttachBlockToChainAsync(chain, block);

            var executionResult = new BlockExecutionResult
            {
                SuccessBlockExecutedSets = { new BlockExecutedSet {
                                                 Block = block
                                             } }
            };
            await _blockExecutionResultProcessingService.ProcessBlockExecutionResultAsync(chain, executionResult);

            chain = await _blockchainService.GetChainAsync();

            chain.LongestChainHash.ShouldBe(chain.BestChainHash);
            chain.LongestChainHeight.ShouldBe(chain.BestChainHeight);
        }
        public async Task Process_Failed_BlockExecutionResult()
        {
            var chain = await _blockchainService.GetChainAsync();

            await _blockchainService.AttachBlockToChainAsync(chain, _kernelTestHelper.LongestBranchBlockList.Last());

            var executionResult = new BlockExecutionResult();

            executionResult.ExecutedFailedBlocks.Add(_kernelTestHelper.LongestBranchBlockList.Last());

            await _blockExecutionResultProcessingService.ProcessBlockExecutionResultAsync(chain, executionResult);

            chain = await _blockchainService.GetChainAsync();

            chain.LongestChainHash.ShouldBe(chain.BestChainHash);
            chain.LongestChainHeight.ShouldBe(chain.BestChainHeight);

            var chainBlockLink =
                await _chainManager.GetChainBlockLinkAsync(_kernelTestHelper.LongestBranchBlockList.Last().GetHash());

            chainBlockLink.ExecutionStatus.ShouldBe(ChainBlockLinkExecutionStatus.ExecutionFailed);
        }
        public async Task Process_Success_BlockExecutionResult()
        {
            var chain = await _blockchainService.GetChainAsync();

            await _blockchainService.RemoveLongestBranchAsync(chain);

            var block = _kernelTestHelper.GenerateBlock(chain.BestChainHeight, chain.BestChainHash);
            await _blockchainService.AttachBlockToChainAsync(chain, block);

            chain = await _blockchainService.GetChainAsync();

            var block2 = _kernelTestHelper.GenerateBlock(block.Height, block.GetHash());
            await _blockchainService.AttachBlockToChainAsync(chain, block2);

            var executionResult = new BlockExecutionResult
            {
                SuccessBlockExecutedSets = { new BlockExecutedSet {
                                                 Block = block
                                             }, new BlockExecutedSet{
                                                 Block = block2
                                             } }
            };
            await _blockExecutionResultProcessingService.ProcessBlockExecutionResultAsync(chain, executionResult);

            chain = await _blockchainService.GetChainAsync();

            chain.BestChainHeight.ShouldBe(block2.Height);
            chain.BestChainHash.ShouldBe(block2.GetHash());

            var chainBlockLink = await _chainManager.GetChainBlockLinkAsync(block.GetHash());

            chainBlockLink.ExecutionStatus.ShouldBe(ChainBlockLinkExecutionStatus.ExecutionSuccess);
            var chainBlockLink2 = await _chainManager.GetChainBlockLinkAsync(block2.GetHash());

            chainBlockLink2.ExecutionStatus.ShouldBe(ChainBlockLinkExecutionStatus.ExecutionSuccess);
        }
        public async Task <BlockExecutionResult> ExecuteBlocksAsync(IEnumerable <Block> blocks)
        {
            var executionResult = new BlockExecutionResult();

            try
            {
                foreach (var block in blocks)
                {
                    var blockExecutedSet = await ProcessBlockAsync(block);

                    if (blockExecutedSet == null)
                    {
                        executionResult.ExecutedFailedBlocks.Add(block);
                        return(executionResult);
                    }

                    executionResult.SuccessBlockExecutedSets.Add(blockExecutedSet);
                    Logger.LogInformation(
                        $"Executed block {block.GetHash()} at height {block.Height}, with {block.Body.TransactionsCount} txns.");

                    await LocalEventBus.PublishAsync(new BlockAcceptedEvent { BlockExecutedSet = blockExecutedSet });
                }
            }
            catch (BlockValidationException ex)
            {
                if (!(ex.InnerException is ValidateNextTimeBlockValidationException))
                {
                    throw;
                }

                Logger.LogDebug(
                    $"Block validation failed: {ex.Message}. Inner exception {ex.InnerException.Message}");
            }

            return(executionResult);
        }