/// <summary> /// Processing pipeline for a block contains ValidateBlockBeforeExecute, ExecuteBlock and ValidateBlockAfterExecute. /// </summary> /// <param name="block"></param> /// <returns>Block processing result is true if succeed, otherwise false.</returns> private async Task <bool> TryProcessBlockAsync(Block block) { var blockHash = block.GetHash(); // Set the other blocks as bad block if found the first bad block if (!await _blockValidationService.ValidateBlockBeforeExecuteAsync(block)) { Logger.LogWarning($"Block validate fails before execution. block hash : {blockHash}"); return(false); } if (!await TryExecuteBlockAsync(block)) { Logger.LogWarning($"Block execution failed. block hash : {blockHash}"); return(false); } if (!await _blockValidationService.ValidateBlockAfterExecuteAsync(block)) { Logger.LogWarning($"Block validate fails after execution. block hash : {blockHash}"); return(false); } await _transactionResultService.ProcessTransactionResultAfterExecutionAsync(block.Header, block.Body.TransactionIds.ToList()); return(true); }
/// <summary> /// Processing pipeline for a block contains ValidateBlockBeforeExecute, ExecuteBlock and ValidateBlockAfterExecute. /// </summary> /// <param name="block"></param> /// <returns>Block processing result is true if succeed, otherwise false.</returns> private async Task <BlockExecutedSet> ProcessBlockAsync(Block block) { var blockHash = block.GetHash(); // Set the other blocks as bad block if found the first bad block if (!await _blockValidationService.ValidateBlockBeforeExecuteAsync(block)) { Logger.LogDebug($"Block validate fails before execution. block hash : {blockHash}"); return(null); } var blockExecutedSet = await ExecuteBlockAsync(block); if (blockExecutedSet == null) { Logger.LogDebug($"Block execution failed. block hash : {blockHash}"); return(null); } if (!await _blockValidationService.ValidateBlockAfterExecuteAsync(block)) { Logger.LogDebug($"Block validate fails after execution. block hash : {blockHash}"); return(null); } await _transactionResultService.ProcessTransactionResultAfterExecutionAsync(block.Header, block.Body.TransactionIds.ToList()); return(blockExecutedSet); }
public async Task <List <ChainBlockLink> > ExecuteBlocksAttachedToLongestChain(Chain chain, BlockAttachOperationStatus status) { if (!status.HasFlag(BlockAttachOperationStatus.LongestChainFound)) { Logger.LogTrace($"Try to attach to chain but the status is {status}."); return(null); } var successLinks = new List <ChainBlockLink>(); var blockLinks = await _chainManager.GetNotExecutedBlocks(chain.LongestChainHash); try { foreach (var blockLink in blockLinks) { var linkedBlock = await _blockchainService.GetBlockByHashAsync(blockLink.BlockHash); // Set the other blocks as bad block if found the first bad block if (!await _blockValidationService.ValidateBlockBeforeExecuteAsync(linkedBlock)) { await _chainManager.SetChainBlockLinkExecutionStatus(blockLink, ChainBlockLinkExecutionStatus.ExecutionFailed); Logger.LogWarning($"Block validate fails before execution. block hash : {blockLink.BlockHash}"); break; } if (!await ExecuteBlock(blockLink, linkedBlock)) { await _chainManager.SetChainBlockLinkExecutionStatus(blockLink, ChainBlockLinkExecutionStatus.ExecutionFailed); Logger.LogWarning($"Block execution failed. block hash : {blockLink.BlockHash}"); break; } if (!await _blockValidationService.ValidateBlockAfterExecuteAsync(linkedBlock)) { await _chainManager.SetChainBlockLinkExecutionStatus(blockLink, ChainBlockLinkExecutionStatus.ExecutionFailed); Logger.LogWarning($"Block validate fails after execution. block hash : {blockLink.BlockHash}"); break; } await _chainManager.SetChainBlockLinkExecutionStatus(blockLink, ChainBlockLinkExecutionStatus.ExecutionSuccess); successLinks.Add(blockLink); Logger.LogInformation($"Executed block {blockLink.BlockHash} at height {blockLink.Height}."); await LocalEventBus.PublishAsync(new BlockAcceptedEvent() { BlockHeader = linkedBlock.Header }); } } catch (ValidateNextTimeBlockValidationException ex) { Logger.LogWarning($"Block validate fails after execution. Exception message {ex.Message}"); } if (successLinks.Count > 0) { var blockLink = successLinks.Last(); await _blockchainService.SetBestChainAsync(chain, blockLink.Height, blockLink.BlockHash); await LocalEventBus.PublishAsync(new BestChainFoundEventData { BlockHash = chain.BestChainHash, BlockHeight = chain.BestChainHeight, ExecutedBlocks = successLinks.Select(p => p.BlockHash).ToList() }); } Logger.LogInformation($"Attach blocks to best chain, status: {status}, best chain hash: {chain.BestChainHash}, height: {chain.BestChainHeight}"); return(blockLinks); }