Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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);
            }
        }