public IActionResult SendTransaction([FromBody] Transaction transaction)
        {
            if (!ModelState.IsValid)
            {
                ModelError firstModelError = ModelState.Values
                                             .SelectMany(v => v.Errors)
                                             .FirstOrDefault();

                return(BadRequest(new { ErrorMsg = firstModelError.ErrorMessage }));
            }

            string applicationUrl = this.httpContextHelpers.GetApplicationUrl(HttpContext);

            TransactionSubmissionResponse transactionSubmissionResponse =
                this.nodeService.ProcessTransaction(transaction, applicationUrl);

            if (transactionSubmissionResponse.StatusCode != null)
            {
                return(StatusCode(
                           (int)transactionSubmissionResponse.StatusCode,
                           new { ErrorMessage = transactionSubmissionResponse.Message }));
            }

            return(Ok(new { TransactionHash = transactionSubmissionResponse.TransactionHash }));
        }
Example #2
0
        public TransactionSubmissionResponse ProcessTransaction(Transaction transaction, string currentPeerUrl)
        {
            // verify signature
            bool signatureVerificationResult = this.VerifySignature(transaction);

            var transactionSubmissionResponse = new TransactionSubmissionResponse();

            if (signatureVerificationResult == false)
            {
                transactionSubmissionResponse.StatusCode = 400; // Bad request
                transactionSubmissionResponse.Message    = "Signature verification failed";

                return(transactionSubmissionResponse);
            }

            // check for collision
            string transactionHash = this.CalculateTransactionHash(transaction);

            var collisionDetected = this.IsCollisionDetected(
                transactionHash,
                this.dataService.PendingTransactions = new List <Transaction>(),
                this.dataService.Blocks
                );

            if (collisionDetected)
            {
                transactionSubmissionResponse.StatusCode = 409; //Conflict
                transactionSubmissionResponse.Message    = "Collision has been detected";

                return(transactionSubmissionResponse);
            }

            // validate balance
            var balance = this.addressService.GetAddressBalance(transaction.From);

            if (balance.ConfirmedBalance.BalanceValue < transaction.Value + transaction.Fee)
            {
                transactionSubmissionResponse.StatusCode = 422; //Unprocessable entity
                transactionSubmissionResponse.Message    = "Insufficient funds";

                return(transactionSubmissionResponse);
            }

            transaction.TransactionHash = transactionHash;

            transactionSubmissionResponse.TransactionHash = transactionHash;

            this.dataService.PendingTransactions.Add(transaction);

            this.logger.LogInformation($"Node: {currentPeerUrl} added transaction with hash: {transactionHash} to pending transactions");

            // send transaction to peers
            this.SendTransactionToPeers(transaction, currentPeerUrl);

            return(transactionSubmissionResponse);
        }