public async Task <TransactionValidationResult> ValidateDataTransaction(DataTransaction transaction) { var userCode = 0L; var result = TransactionResultTypes.Unknown; var message = string.Empty; TransactionValidation nodeValidation = null; var type = transaction.TransactionType; var chainInfo = _coreChain.GetChainInfo(ChainId); var accountId = transaction.AccountId; var service = _node.ChainManager.GetService(ChainId); if (chainInfo == null) { result = TransactionResultTypes.ChainNotFound; goto end; } if (service == null) { result = TransactionResultTypes.ChainServiceUnavailable; goto end; } if (!_chainKeyValid) { var chainKey = chainInfo.GetValidChainKey(ChainIndex, ChainKeyIndex, Time.Timestamp); if (chainKey == null || chainKey.PublicKey != ChainKey.PublicKey) { result = TransactionResultTypes.ChainNodeInvalid; goto end; } _chainKeyValid = true; } if (transaction == null) { result = TransactionResultTypes.InvalidTransaction; goto end; } if (!transaction.IsDataTransactionValid) { result = TransactionResultTypes.InvalidContent; goto end; } if (BlockStorage.History.ContainsTransactionIdentifier(transaction)) { result = TransactionResultTypes.AlreadyProcessed; goto end; } var coreAccount = _coreChain.GetCoreAccount(accountId); if (coreAccount == null) { result = TransactionResultTypes.InvalidCoreAccount; goto end; } var serviceAccount = _serviceChain.GetServiceAccount(accountId); if (transaction.SignKeyIndex == Protocol.CoreAccountSignKeyIndex) { if (!transaction.IsSignatureValid(coreAccount.AccountKey, null)) { result = TransactionResultTypes.InvalidSignature; goto end; } } else { if (serviceAccount == null) { result = TransactionResultTypes.InvalidServiceAccount; goto end; } var accountKey = serviceAccount.GetValidAccountKey(transaction.SignKeyIndex, transaction.Timestamp); if (accountKey == null) { result = TransactionResultTypes.InvalidServiceAccountKey; goto end; } if (accountKey.IsExpired()) { result = TransactionResultTypes.Expired; goto end; } if (!transaction.IsSignatureValid(coreAccount.AccountKey, accountKey)) { result = TransactionResultTypes.InvalidSignature; goto end; } } { var(featResult, featCode) = ValidateTransactionFeatures((ushort)DataTransactionTypes.FeatureRequest, transaction); if (featResult != TransactionResultTypes.Ok) { result = featResult; userCode = featCode; goto end; } } if (type == DataTransactionTypes.Attachement) { if (!Attachements.AreAttachementsUploaded(transaction as AttachementDataTransaction)) { result = TransactionResultTypes.AttachementsNotUploaded; goto end; } } var purchaseRequired = transaction.GetFeature <RequiredPurchase>(RequiredPurchase.FeatureId); if (purchaseRequired != null && purchaseRequired.RequiredPurchaseType != PurchaseTypes.None) { if (!serviceAccount.HasRequiredTransactionPurchase(transaction, purchaseRequired)) { result = TransactionResultTypes.PurchaseRequired; goto end; } } var validation = await service.IsDataTransactionValid(transaction); userCode = validation.UserCode; message = validation.Message; if (!validation.IsOK) { if (validation.Result == ServiceResultTypes.PurchaseRequired) { result = TransactionResultTypes.PurchaseRequired; } else { result = TransactionResultTypes.ChainServiceErrorResponse; } goto end; } result = TransactionResultTypes.Ok; nodeValidation = new TransactionValidation(transaction, ChainKeyIndex, ChainKey); end: return(new TransactionValidationResult(result, userCode, message, nodeValidation)); }