public async Task <BlockExecutedSet> ExecuteBlockAsync(BlockHeader blockHeader, IEnumerable <Transaction> nonCancellableTransactions, IEnumerable <Transaction> cancellableTransactions, CancellationToken cancellationToken) { Logger.LogTrace("Entered ExecuteBlockAsync"); var nonCancellable = nonCancellableTransactions.ToList(); var cancellable = cancellableTransactions.ToList(); var nonCancellableReturnSets = await _transactionExecutingService.ExecuteAsync( new TransactionExecutingDto { BlockHeader = blockHeader, Transactions = nonCancellable }, CancellationToken.None); Logger.LogTrace("Executed non-cancellable txs"); var returnSetCollection = new ExecutionReturnSetCollection(nonCancellableReturnSets); List <ExecutionReturnSet> cancellableReturnSets = new List <ExecutionReturnSet>(); if (!cancellationToken.IsCancellationRequested && cancellable.Count > 0) { cancellableReturnSets = await _transactionExecutingService.ExecuteAsync( new TransactionExecutingDto { BlockHeader = blockHeader, Transactions = cancellable, PartialBlockStateSet = returnSetCollection.ToBlockStateSet() }, cancellationToken); returnSetCollection.AddRange(cancellableReturnSets); Logger.LogTrace("Executed cancellable txs"); } var executedCancellableTransactions = new HashSet <Hash>(cancellableReturnSets.Select(x => x.TransactionId)); var allExecutedTransactions = nonCancellable.Concat(cancellable.Where(x => executedCancellableTransactions.Contains(x.GetHash()))) .ToList(); var blockStateSet = CreateBlockStateSet(blockHeader.PreviousBlockHash, blockHeader.Height, returnSetCollection); var block = await FillBlockAfterExecutionAsync(blockHeader, allExecutedTransactions, returnSetCollection, blockStateSet); // set txn results var transactionResults = await SetTransactionResultsAsync(returnSetCollection, block.Header); // set blocks state blockStateSet.BlockHash = block.GetHash(); Logger.LogTrace("Set block state set."); await _blockchainStateService.SetBlockStateSetAsync(blockStateSet); // handle execution cases await CleanUpReturnSetCollectionAsync(block.Header, returnSetCollection); return(new BlockExecutedSet { Block = block, TransactionMap = allExecutedTransactions.ToDictionary(p => p.GetHash(), p => p), TransactionResultMap = transactionResults.ToDictionary(p => p.TransactionId, p => p) }); }
private BlockStateSet GetUpdatedBlockStateSet(ExecutionReturnSetCollection executionReturnSetCollection, TransactionExecutingDto transactionExecutingDto) { var updatedPartialBlockStateSet = executionReturnSetCollection.ToBlockStateSet(); if (transactionExecutingDto.PartialBlockStateSet != null) { var partialBlockStateSet = transactionExecutingDto.PartialBlockStateSet.Clone(); foreach (var change in partialBlockStateSet.Changes) { if (updatedPartialBlockStateSet.Changes.TryGetValue(change.Key, out _)) { continue; } if (updatedPartialBlockStateSet.Deletes.Contains(change.Key)) { continue; } updatedPartialBlockStateSet.Changes[change.Key] = change.Value; } foreach (var delete in partialBlockStateSet.Deletes) { if (updatedPartialBlockStateSet.Deletes.Contains(delete)) { continue; } if (updatedPartialBlockStateSet.Changes.TryGetValue(delete, out _)) { continue; } updatedPartialBlockStateSet.Deletes.Add(delete); } } return(updatedPartialBlockStateSet); }