Ejemplo n.º 1
0
        public async Task <List <TransactionTrace> > ExecuteAsync(List <Transaction> transactions, Hash chainId,
                                                                  CancellationToken cancellationToken, Hash disambiguationHash = null)
        {
            var chainContext = await _chainContextService.GetChainContextAsync(chainId);

            var stateCache = new Dictionary <DataPath, StateCache>();
            var traces     = new List <TransactionTrace>();

            foreach (var transaction in transactions)
            {
                var trace = await ExecuteOneAsync(0, transaction, chainId, chainContext, stateCache, cancellationToken);

                //Console.WriteLine($"{transaction.GetHash().ToHex()} : {trace.ExecutionStatus.ToString()}");
                if (trace.IsSuccessful() && trace.ExecutionStatus == ExecutionStatus.ExecutedButNotCommitted)
                {
                    //Console.WriteLine($"tx executed successfully: {transaction.GetHash().ToHex()}");
                    await trace.CommitChangesAsync(_stateStore);

//                    await _stateDictator.ApplyCachedDataAction(bufferedStateUpdates);
//                    foreach (var kv in bufferedStateUpdates)
//                    {
//                        stateCache[kv.Key] = kv.Value;
//                    }
                }

                if (_transactionTraceManager != null)
                {
                    // Will be null only in tests
                    await _transactionTraceManager.AddTransactionTraceAsync(trace, disambiguationHash);
                }

                traces.Add(trace);

                if (cancellationToken.IsCancellationRequested)
                {
                    break;
                }
            }

//            await _stateDictator.ApplyCachedDataAction(stateCache);
            return(traces);
        }
Ejemplo n.º 2
0
Archivo: Miner.cs Proyecto: wyk125/AElf
        /// <inheritdoc />
        /// <summary>
        /// Mine process.
        /// </summary>
        /// <returns></returns>
        public async Task <IBlock> Mine()
        {
            try
            {
                var stopwatch = new Stopwatch();
                stopwatch.Start();
                await GenerateTransactionWithParentChainBlockInfo();

                var txs = await _txHub.GetReceiptsOfExecutablesAsync();

                var txGrp  = txs.GroupBy(tr => tr.IsSystemTxn).ToDictionary(x => x.Key, x => x.ToList());
                var traces = new List <TransactionTrace>();
                //ParentChainBlockInfo pcb = null;
                if (txGrp.TryGetValue(true, out var sysRcpts))
                {
                    var sysTxs = sysRcpts.Select(x => x.Transaction).ToList();
                    _txFilter.Execute(sysTxs);

                    _logger?.Trace($"Start executing {sysTxs.Count} system transactions.");
                    traces = await ExecuteTransactions(sysTxs, true);

                    _logger?.Trace($"Finish executing {sysTxs.Count} system transactions.");

                    // need check result of cross chain transaction
                    //FindCrossChainInfo(sysTxs, traces, out pcb);
                }
                if (txGrp.TryGetValue(false, out var regRcpts))
                {
                    var regTxs = regRcpts.Select(x => x.Transaction).ToList();
                    _logger?.Trace($"Start executing {regTxs.Count} regular transactions.");
                    traces.AddRange(await ExecuteTransactions(regTxs));
                    _logger?.Trace($"Finish executing {regTxs.Count} regular transactions.");
                }

                ExtractTransactionResults(traces, out var results);

                // generate block
                var block = await GenerateBlockAsync(results);

                _logger?.Info($"Generated block {block.BlockHashToHex} at height {block.Header.Index} with {block.Body.TransactionsCount} txs.");

                // validate block before appending
                var chainContext = await _chainContextService.GetChainContextAsync(Hash.LoadHex(ChainConfig.Instance.ChainId));

                var blockValidationResult = await _blockValidationService.ValidateBlockAsync(block, chainContext);

                if (blockValidationResult != BlockValidationResult.Success)
                {
                    _logger?.Warn($"Found the block generated before invalid: {blockValidationResult}.");
                    return(null);
                }
                // append block
                await _blockChain.AddBlocksAsync(new List <IBlock> {
                    block
                });

                MessageHub.Instance.Publish(new BlockMined(block));

                // insert to db
                Update(results, block);

                /*if (pcb != null)
                 * {
                 *  await _chainManagerBasic.UpdateCurrentBlockHeightAsync(pcb.ChainId, pcb.Height);
                 * }*/
                await _txHub.OnNewBlock((Block)block);

                MessageHub.Instance.Publish(new BlockMinedAndStored(block));
                stopwatch.Stop();
                _logger?.Info($"Generate block {block.BlockHashToHex} at height {block.Header.Index} " +
                              $"with {block.Body.TransactionsCount} txs, duration {stopwatch.ElapsedMilliseconds} ms.");

                return(block);
            }
            catch (Exception e)
            {
                _logger?.Error(e, "Mining failed with exception.");
                return(null);
            }
        }