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); } } } }
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); 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 NotImplementedException() },