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}"); }
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); }