private async Task <TransactionTrace> ExecuteOneAsync(int depth, Transaction transaction, Hash chainId, IChainContext chainContext, Dictionary <DataPath, StateCache> stateCache, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(new TransactionTrace() { TransactionId = transaction.GetHash(), StdErr = "Execution Canceled", ExecutionStatus = ExecutionStatus.Canceled }); } var trace = new TransactionTrace() { TransactionId = transaction.GetHash() }; var txCtxt = new TransactionContext() { PreviousBlockHash = chainContext.BlockHash, Transaction = transaction, BlockHeight = chainContext.BlockHeight, Trace = trace, CallDepth = depth }; var executive = await _smartContractService.GetExecutiveAsync(transaction.To, chainId); try { executive.SetDataCache(stateCache); await executive.SetTransactionContext(txCtxt).Apply(); foreach (var inlineTx in txCtxt.Trace.InlineTransactions) { var inlineTrace = await ExecuteOneAsync(depth + 1, inlineTx, chainId, chainContext, stateCache, cancellationToken); trace.InlineTraces.Add(inlineTrace); } } catch (Exception ex) { txCtxt.Trace.ExecutionStatus = ExecutionStatus.ContractError; txCtxt.Trace.StdErr += ex + "\n"; } finally { await _smartContractService.PutExecutiveAsync(transaction.To, executive); } return(trace); }
private async Task <List <ulong> > ReadBalancesForAddrs(List <Address> targets, Address tokenContractAddr) { List <ulong> res = new List <ulong>(); foreach (var target in targets) { Transaction tx = new Transaction() { From = target, To = tokenContractAddr, IncrementId = 0, MethodName = "GetBalance", Params = ByteString.CopyFrom(ParamsPacker.Pack(target)), }; var txnCtxt = new TransactionContext() { Transaction = tx }; var executive = await _smartContractService.GetExecutiveAsync(tokenContractAddr, ChainId); try { await executive.SetTransactionContext(txnCtxt).Apply(); } finally { await _smartContractService.PutExecutiveAsync(tokenContractAddr, executive); } res.Add(txnCtxt.Trace.RetVal.Data.DeserializeToUInt64()); } return(res); }
private async Task <BlockValidationResult> DPoSValidation(IBlock block, IChainContext context) { // If the height of chain is 1, no need to check consensus validation if (block.Header.Index < GlobalConfig.GenesisBlockHeight + 2) { return(BlockValidationResult.Success); } // Get BP address var uncompressedPrivateKey = block.Header.P.ToByteArray(); var recipientKeyPair = ECKeyPair.FromPublicKey(uncompressedPrivateKey); var address = recipientKeyPair.GetAddress().DumpHex(); // Get the address of consensus contract var contractAccountHash = AddressHelpers.GetSystemContractAddress(context.ChainId, SmartContractType.AElfDPoS.ToString()); var timestampOfBlock = block.Header.Time; long roundId = 1; var updateTx = block.Body.TransactionList.Where(t => t.MethodName == ConsensusBehavior.UpdateAElfDPoS.ToString()) .ToList(); if (updateTx.Count > 0) { if (updateTx.Count > 1) { return(BlockValidationResult.IncorrectDPoSTxInBlock); } roundId = ((Round)ParamsPacker.Unpack(updateTx[0].Params.ToByteArray(), new[] { typeof(Round), typeof(Round), typeof(StringValue) })[1]).RoundId; } //Formulate an Executive and execute a transaction of checking time slot of this block producer TransactionTrace trace; var executive = await _smartContractService.GetExecutiveAsync(contractAccountHash, context.ChainId); try { var tx = GetTxToVerifyBlockProducer(contractAccountHash, NodeConfig.Instance.ECKeyPair, address, timestampOfBlock, roundId); if (tx == null) { return(BlockValidationResult.FailedToCheckConsensusInvalidation); } var tc = new TransactionContext { Transaction = tx }; await executive.SetTransactionContext(tc).Apply(); trace = tc.Trace; } finally { _smartContractService.PutExecutiveAsync(contractAccountHash, executive).Wait(); } //If failed to execute the transaction of checking time slot if (!trace.StdErr.IsNullOrEmpty()) { _logger.Trace("Failed to execute tx Validation: " + trace.StdErr); return(BlockValidationResult.FailedToCheckConsensusInvalidation); } var result = Int32Value.Parser.ParseFrom(trace.RetVal.ToByteArray()).Value; switch (result) { case 1: return(BlockValidationResult.NotBP); case 2: return(BlockValidationResult.InvalidTimeSlot); case 3: return(BlockValidationResult.SameWithCurrentRound); case 11: return(BlockValidationResult.ParseProblem); default: return(BlockValidationResult.Success); } }