Beispiel #1
0
        public async Task <List <ExecutionReturnSet> > ExecuteAsync(TransactionExecutingDto transactionExecutingDto,
                                                                    CancellationToken cancellationToken, bool throwException)
        {
            var groupStateCache = transactionExecutingDto.PartialBlockStateSet == null
                ? new TieredStateCache()
                : new TieredStateCache(
                new StateCacheFromPartialBlockStateSet(transactionExecutingDto.PartialBlockStateSet));
            var groupChainContext = new ChainContextWithTieredStateCache(
                transactionExecutingDto.BlockHeader.PreviousBlockHash,
                transactionExecutingDto.BlockHeader.Height - 1, groupStateCache);

            var returnSets = new List <ExecutionReturnSet>();

            foreach (var transaction in transactionExecutingDto.Transactions)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    break;
                }

                var trace = await ExecuteOneAsync(0, groupChainContext, transaction,
                                                  transactionExecutingDto.BlockHeader.Time,
                                                  cancellationToken);

                // Will be useful when debugging MerkleTreeRootOfWorldState is different from each miner.
                Logger.LogTrace(transaction.MethodName);
                Logger.LogTrace(trace.StateSet.Writes.Values.Select(v => v.ToBase64().ComputeHash().ToHex())
                                .JoinAsString("\n"));

                if (!trace.IsSuccessful())
                {
                    if (throwException)
                    {
                        Logger.LogError(trace.Error);
                    }

                    // Do not package this transaction if any of his inline transactions canceled.
                    if (IsTransactionCanceled(trace))
                    {
                        break;
                    }

                    trace.SurfaceUpError();
                }
                else
                {
                    groupStateCache.Update(trace.GetFlattenedWrites()
                                           .Select(x => new KeyValuePair <string, byte[]>(x.Key, x.Value.ToByteArray())));
                }

                if (trace.Error != string.Empty)
                {
                    Logger.LogError(trace.Error);
                }

                var result = GetTransactionResult(trace, transactionExecutingDto.BlockHeader.Height);

                if (result != null)
                {
                    await _transactionResultService.AddTransactionResultAsync(result,
                                                                              transactionExecutingDto.BlockHeader);
                }

                var returnSet = GetReturnSet(trace, result);
                returnSets.Add(returnSet);
            }

            return(returnSets);
        }
Beispiel #2
0
        public async Task <List <ExecutionReturnSet> > ExecuteAsync(TransactionExecutingDto transactionExecutingDto,
                                                                    CancellationToken cancellationToken)
        {
            try
            {
                var groupStateCache   = transactionExecutingDto.PartialBlockStateSet.ToTieredStateCache();
                var groupChainContext = new ChainContextWithTieredStateCache(
                    transactionExecutingDto.BlockHeader.PreviousBlockHash,
                    transactionExecutingDto.BlockHeader.Height - 1, groupStateCache);

                var returnSets = new List <ExecutionReturnSet>();
                foreach (var transaction in transactionExecutingDto.Transactions)
                {
                    TransactionTrace trace;
                    if (cancellationToken.IsCancellationRequested)
                    {
                        break;
                    }

                    var singleTxExecutingDto = new SingleTransactionExecutingDto
                    {
                        Depth               = 0,
                        ChainContext        = groupChainContext,
                        Transaction         = transaction,
                        CurrentBlockTime    = transactionExecutingDto.BlockHeader.Time,
                        OriginTransactionId = transaction.GetHash()
                    };
                    try
                    {
                        var transactionExecutionTask = Task.Run(() => ExecuteOneAsync(singleTxExecutingDto,
                                                                                      cancellationToken), cancellationToken);

                        trace = await transactionExecutionTask.WithCancellation(cancellationToken);
                    }
                    catch (OperationCanceledException)
                    {
                        Logger.LogTrace("Transaction canceled.");
                        if (cancellationToken.IsCancellationRequested)
                        {
                            break;
                        }
                        continue;
                    }


                    if (!TryUpdateStateCache(trace, groupStateCache))
                    {
                        break;
                    }
#if DEBUG
                    if (!string.IsNullOrEmpty(trace.Error))
                    {
                        Logger.LogInformation(trace.Error);
                    }
#endif
                    var result = GetTransactionResult(trace, transactionExecutingDto.BlockHeader.Height);

                    var returnSet = GetReturnSet(trace, result);
                    returnSets.Add(returnSet);
                }

                return(returnSets);
            }
            catch (Exception e)
            {
                Logger.LogError(e, "Failed while executing txs in block.");
                throw;
            }
        }
Beispiel #3
0
        public async Task <List <ExecutionReturnSet> > ExecuteAsync(TransactionExecutingDto transactionExecutingDto,
                                                                    CancellationToken cancellationToken)
        {
            try
            {
                var groupStateCache = transactionExecutingDto.PartialBlockStateSet == null
                    ? new TieredStateCache()
                    : new TieredStateCache(
                    new StateCacheFromPartialBlockStateSet(transactionExecutingDto.PartialBlockStateSet));
                var groupChainContext = new ChainContextWithTieredStateCache(
                    transactionExecutingDto.BlockHeader.PreviousBlockHash,
                    transactionExecutingDto.BlockHeader.Height - 1, groupStateCache);

                var transactionResults = new List <TransactionResult>();
                var returnSets         = new List <ExecutionReturnSet>();
                foreach (var transaction in transactionExecutingDto.Transactions)
                {
                    TransactionTrace trace;
                    if (cancellationToken.IsCancellationRequested)
                    {
                        break;
                    }

                    var singleTxExecutingDto = new SingleTransactionExecutingDto
                    {
                        Depth            = 0,
                        ChainContext     = groupChainContext,
                        Transaction      = transaction,
                        CurrentBlockTime = transactionExecutingDto.BlockHeader.Time,
                    };
                    try
                    {
                        var transactionExecutionTask = Task.Run(() => ExecuteOneAsync(singleTxExecutingDto,
                                                                                      cancellationToken), cancellationToken);

                        trace = await transactionExecutionTask.WithCancellation(cancellationToken);
                    }
                    catch (OperationCanceledException)
                    {
                        Logger.LogTrace("Transaction canceled.");
                        if (cancellationToken.IsCancellationRequested)
                        {
                            break;
                        }
                        continue;
                    }

                    if (trace == null)
                    {
                        break;
                    }

                    if (!trace.IsSuccessful())
                    {
                        // Do not package this transaction if any of his inline transactions canceled.
                        if (IsTransactionCanceled(trace))
                        {
                            break;
                        }

                        var transactionExecutingStateSets = new List <TransactionExecutingStateSet>();
                        foreach (var preTrace in trace.PreTraces)
                        {
                            if (preTrace.IsSuccessful())
                            {
                                transactionExecutingStateSets.AddRange(preTrace.GetStateSets());
                            }
                        }

                        foreach (var postTrace in trace.PostTraces)
                        {
                            if (postTrace.IsSuccessful())
                            {
                                transactionExecutingStateSets.AddRange(postTrace.GetStateSets());
                            }
                        }

                        groupStateCache.Update(transactionExecutingStateSets);
                        trace.SurfaceUpError();
                    }
                    else
                    {
                        groupStateCache.Update(trace.GetStateSets());
                    }
#if DEBUG
                    if (trace.Error != string.Empty)
                    {
                        Logger.LogError(trace.Error);
                    }
#endif
                    var result = GetTransactionResult(trace, transactionExecutingDto.BlockHeader.Height);

                    transactionResults.Add(result);

                    var returnSet = GetReturnSet(trace, result);
                    returnSets.Add(returnSet);
                }

                await _transactionResultService.AddTransactionResultsAsync(transactionResults,
                                                                           transactionExecutingDto.BlockHeader);

                return(returnSets);
            }
            catch (Exception e)
            {
                Logger.LogError(e, "Failed while executing txs in block.");
                throw;
            }
        }
Beispiel #4
0
        public async Task <List <ExecutionReturnSet> > ExecuteAsync(TransactionExecutingDto transactionExecutingDto,
                                                                    CancellationToken cancellationToken, bool throwException)
        {
            try
            {
                var groupStateCache = transactionExecutingDto.PartialBlockStateSet == null
                    ? new TieredStateCache()
                    : new TieredStateCache(
                    new StateCacheFromPartialBlockStateSet(transactionExecutingDto.PartialBlockStateSet));
                var groupChainContext = new ChainContextWithTieredStateCache(
                    transactionExecutingDto.BlockHeader.PreviousBlockHash,
                    transactionExecutingDto.BlockHeader.Height - 1, groupStateCache);

                var transactionResults = new List <TransactionResult>();
                var returnSets         = new List <ExecutionReturnSet>();
                foreach (var transaction in transactionExecutingDto.Transactions)
                {
                    TransactionTrace trace;
                    if (cancellationToken.IsCancellationRequested)
                    {
                        break;
                    }

                    var singleTxExecutingDto = new SingleTransactionExecutingDto
                    {
                        Depth            = 0,
                        ChainContext     = groupChainContext,
                        Transaction      = transaction,
                        CurrentBlockTime = transactionExecutingDto.BlockHeader.Time,
                    };
                    try
                    {
                        var task = Task.Run(() => ExecuteOneAsync(singleTxExecutingDto,
                                                                  cancellationToken), cancellationToken);
                        trace = await task.WithCancellation(cancellationToken);
                    }
                    catch (OperationCanceledException)
                    {
                        Logger.LogTrace($"transaction canceled");
                        break;
                    }

                    if (trace == null)
                    {
                        break;
                    }
                    // Will be useful when debugging MerkleTreeRootOfWorldState is different from each miner.

                    /*
                     * Logger.LogTrace(transaction.MethodName);
                     * Logger.LogTrace(trace.StateSet.Writes.Values.Select(v => v.ToBase64().ComputeHash().ToHex())
                     *  .JoinAsString("\n"));
                     */

                    if (!trace.IsSuccessful())
                    {
                        if (throwException)
                        {
                            Logger.LogError(trace.Error);
                        }

                        // Do not package this transaction if any of his inline transactions canceled.
                        if (IsTransactionCanceled(trace))
                        {
                            break;
                        }

                        var transactionExecutingStateSets = new List <TransactionExecutingStateSet>();
                        foreach (var preTrace in trace.PreTraces)
                        {
                            if (preTrace.IsSuccessful())
                            {
                                transactionExecutingStateSets.AddRange(preTrace.GetStateSets());
                            }
                        }

                        foreach (var postTrace in trace.PostTraces)
                        {
                            if (postTrace.IsSuccessful())
                            {
                                transactionExecutingStateSets.AddRange(postTrace.GetStateSets());
                            }
                        }

                        groupStateCache.Update(transactionExecutingStateSets);
                        trace.SurfaceUpError();
                    }
                    else
                    {
                        groupStateCache.Update(trace.GetStateSets());
                    }

                    if (trace.Error != string.Empty)
                    {
                        Logger.LogError(trace.Error);
                    }

                    var result = GetTransactionResult(trace, transactionExecutingDto.BlockHeader.Height);

                    if (result != null)
                    {
                        result.TransactionFee = trace.TransactionFee;
                        transactionResults.Add(result);
                    }

                    var returnSet = GetReturnSet(trace, result);
                    returnSets.Add(returnSet);
                }

                await _transactionResultService.AddTransactionResultsAsync(transactionResults,
                                                                           transactionExecutingDto.BlockHeader);

                return(returnSets);
            }
            catch (Exception e)
            {
                Logger.LogTrace("Failed while executing txs in block.", e);
                throw;
            }
        }