示例#1
0
        public async Task Init(Block block, RawOperation op, RawTransactionContent content)
        {
            var sender = await Cache.Accounts.GetAsync(content.Source);

            sender.Delegate ??= Cache.Accounts.GetDelegate(sender.DelegateId);

            var target = await Cache.Accounts.GetAsync(content.Destination)
                         ?? block.Originations?.FirstOrDefault(x => x.Contract.Address == content.Destination)?.Contract;

            if (target != null)
            {
                target.Delegate ??= Cache.Accounts.GetDelegate(target.DelegateId);
            }

            Transaction = new TransactionOperation
            {
                Id           = Cache.AppState.NextOperationId(),
                Block        = block,
                Level        = block.Level,
                Timestamp    = block.Timestamp,
                OpHash       = op.Hash,
                Amount       = content.Amount,
                BakerFee     = content.Fee,
                Counter      = content.Counter,
                GasLimit     = content.GasLimit,
                StorageLimit = content.StorageLimit,
                Sender       = sender,
                Target       = target,
                Parameters   = OperationParameters.Parse(content.Parameters),
                Status       = content.Metadata.Result.Status switch
                {
                    "applied" => OperationStatus.Applied,
                    "backtracked" => OperationStatus.Backtracked,
                    "failed" => OperationStatus.Failed,
                    "skipped" => OperationStatus.Skipped,
                    _ => throw new Exception($"Invalid status '{content.Metadata.Result.Status}'")
                },
示例#2
0
        protected async Task ValidateTransaction(RawTransactionContent transaction, RawBlock rawBlock)
        {
            if (!await Cache.Accounts.ExistsAsync(transaction.Source))
            {
                throw new ValidationException("unknown source account");
            }

            ValidateFeeBalanceUpdates(
                transaction.Metadata.BalanceUpdates,
                rawBlock.Metadata.Baker,
                transaction.Source,
                transaction.Fee,
                rawBlock.Metadata.LevelInfo.Cycle);

            if (transaction.Metadata.Result.BalanceUpdates != null)
            {
                ValidateTransferBalanceUpdates(
                    transaction.Metadata.Result.BalanceUpdates,
                    transaction.Source,
                    transaction.Destination,
                    transaction.Amount,
                    transaction.Metadata.Result.PaidStorageSizeDiff * Protocol.ByteCost,
                    transaction.Metadata.Result.AllocatedDestinationContract ? Protocol.OriginationSize * Protocol.ByteCost : 0);
            }

            if (transaction.Metadata.InternalResults?.Count > 0)
            {
                foreach (var internalContent in transaction.Metadata.InternalResults.Where(x => x is RawInternalTransactionResult))
                {
                    var internalTransaction = internalContent as RawInternalTransactionResult;

                    if (!await Cache.Accounts.ExistsAsync(internalTransaction.Source, AccountType.Contract))
                    {
                        throw new ValidationException("unknown source contract");
                    }

                    if (internalTransaction.Result.BalanceUpdates != null)
                    {
                        ValidateTransferBalanceUpdates(
                            internalTransaction.Result.BalanceUpdates,
                            internalTransaction.Source,
                            internalTransaction.Destination,
                            internalTransaction.Amount,
                            internalTransaction.Result.PaidStorageSizeDiff * Protocol.ByteCost,
                            internalTransaction.Result.AllocatedDestinationContract ? Protocol.OriginationSize * Protocol.ByteCost : 0,
                            transaction.Source);
                    }
                }

                foreach (var internalContent in transaction.Metadata.InternalResults.Where(x => x is RawInternalDelegationResult))
                {
                    var internalDelegation = internalContent as RawInternalDelegationResult;

                    if (!await Cache.Accounts.ExistsAsync(internalDelegation.Source, AccountType.Contract))
                    {
                        throw new ValidationException("unknown source contract");
                    }

                    if (internalDelegation.Result.Status == "applied" && internalDelegation.Delegate != null)
                    {
                        if (!Cache.Accounts.DelegateExists(internalDelegation.Delegate))
                        {
                            throw new ValidationException("unknown delegate account");
                        }
                    }
                }

                foreach (var internalContent in transaction.Metadata.InternalResults.Where(x => x is RawInternalOriginationResult))
                {
                    var internalOrigination = internalContent as RawInternalOriginationResult;

                    if (!await Cache.Accounts.ExistsAsync(internalOrigination.Source, AccountType.Contract))
                    {
                        throw new ValidationException("unknown source contract");
                    }

                    if (internalOrigination.Result.Status == "applied" && internalOrigination.Delegate != null)
                    {
                        if (!Cache.Accounts.DelegateExists(internalOrigination.Delegate))
                        {
                            throw new ValidationException("unknown delegate account");
                        }
                    }

                    if (internalOrigination.Result.BalanceUpdates != null)
                    {
                        ValidateTransferBalanceUpdates(
                            internalOrigination.Result.BalanceUpdates,
                            internalOrigination.Source,
                            internalOrigination.Result.OriginatedContracts[0],
                            internalOrigination.Balance,
                            internalOrigination.Result.PaidStorageSizeDiff * Protocol.ByteCost,
                            Protocol.OriginationSize * Protocol.ByteCost,
                            transaction.Source);
                    }
                }
            }
        }