private async Task <List <TransactionWithResourceInfo> > FindContractOfWrongResourcesAsync(IChainContext chainContext, List <ExecutionReturnSet> returnSets) { var transactionIds = returnSets.Select(rs => rs.TransactionId); var transactions = await _blockchainService.GetTransactionsAsync(transactionIds); var txnWithResources = await _resourceExtractionService.GetResourcesAsync(chainContext, transactions, CancellationToken.None); txnWithResources = txnWithResources.Where(t => t.TransactionResourceInfo.ParallelType == ParallelType.Parallelizable); var txnWithResourceList = txnWithResources.ToList(); var readOnlyKeys = txnWithResourceList.GetReadOnlyPaths().Select(p => p.ToStateKey()).ToList(); var returnSetLookup = returnSets.ToDictionary(rs => rs.TransactionId, rs => rs); var wrongTxnWithResources = new List <TransactionWithResourceInfo>(); foreach (var txnWithResource in txnWithResourceList) { var extracted = new HashSet <string>(txnWithResource.TransactionResourceInfo.WritePaths .Concat(txnWithResource.TransactionResourceInfo.ReadPaths).Select(p => p.ToStateKey())); extracted.ExceptWith(readOnlyKeys); var actual = GetKeys(returnSetLookup[txnWithResource.Transaction.GetHash()]); actual.ExceptWith(extracted); if (actual.Count == 0) { continue; } Logger.LogDebug($"Conflict keys:{string.Join(";", actual)}"); wrongTxnWithResources.Add(txnWithResource); } return(wrongTxnWithResources); }
private async Task <List <Transaction> > FindContractOfWrongResourcesAsync(IChainContext chainContext, List <ExecutionReturnSet> returnSets) { var transactionIds = returnSets.Select(rs => rs.TransactionId); var transactions = await _blockchainService.GetTransactionsAsync(transactionIds); var txnWithResources = await _resourceExtractionService.GetResourcesAsync(chainContext, transactions, CancellationToken.None); var returnSetLookup = returnSets.ToDictionary(rs => rs.TransactionId, rs => rs); var wrongTxns = new List <Transaction>(); foreach (var txnWithResource in txnWithResources) { var extracted = new HashSet <string>(txnWithResource.Item2.Paths.Select(p => p.ToStateKey())); var actual = GetKeys(returnSetLookup[txnWithResource.Item1.GetHash()]); actual.ExceptWith(extracted); if (actual.Count > 0) { Logger.LogWarning($"Conflict keys:{string.Join(";", actual)}"); wrongTxns.Add(txnWithResource.Item1); } } return(wrongTxns); }
public async Task <GroupedTransactions> GroupAsync(IChainContext chainContext, List <Transaction> transactions) { Logger.LogTrace("Entered GroupAsync"); var toBeGrouped = GetTransactionsToBeGrouped(transactions, out var groupedTransactions); using (var cts = new CancellationTokenSource(_options.GroupingTimeOut)) { var parallelizables = new List <TransactionWithResourceInfo>(); Logger.LogTrace("Extracting resources for transactions."); var txsWithResources = await _resourceExtractionService.GetResourcesAsync(chainContext, toBeGrouped, cts.Token); Logger.LogTrace("Completed resource extraction."); foreach (var twr in txsWithResources) { if (twr.TransactionResourceInfo.ParallelType == ParallelType.InvalidContractAddress) { groupedTransactions.TransactionsWithoutContract.Add(twr.Transaction); continue; } // If timed out at this point, return all transactions as non-parallelizable if (cts.IsCancellationRequested) { groupedTransactions.NonParallelizables.Add(twr.Transaction); continue; } if (twr.TransactionResourceInfo.ParallelType == ParallelType.NonParallelizable) { groupedTransactions.NonParallelizables.Add(twr.Transaction); continue; } if (twr.TransactionResourceInfo.Paths.Count == 0) { // groups.Add(new List<Transaction>() {twr.Item1}); // Run in their dedicated group groupedTransactions.NonParallelizables.Add(twr.Transaction); continue; } parallelizables.Add(twr); } groupedTransactions.Parallelizables.AddRange(GroupParallelizables(parallelizables)); Logger.LogTrace("Completed transaction grouping."); } Logger.LogDebug($"From {transactions.Count} transactions, grouped {groupedTransactions.Parallelizables.Sum(p=>p.Count)} txs into " + $"{groupedTransactions.Parallelizables.Count} groups, left " + $"{groupedTransactions.NonParallelizables.Count} as non-parallelizable transactions."); return(groupedTransactions); }