Example #1
0
        public async Task verify_async_should_return_result_with_confirmed_property_equal_to_false_if_latest_block_is_null()
        {
            NdmTransaction            transaction = GetTransaction();
            TransactionVerifierResult result      = await _transactionVerifier.VerifyAsync(transaction);

            result.BlockFound.Should().BeFalse();
            result.Confirmed.Should().BeFalse();
            await _blockchainBridge.Received().GetLatestBlockAsync();
        }
Example #2
0
        public async Task verify_async_should_return_result_with_confirmed_property_equal_to_false_if_block_was_not_found_and_required_number_of_confirmations_was_not_achieved()
        {
            Block          block       = GetBlock();
            NdmTransaction transaction = GetTransaction();

            _blockchainBridge.GetLatestBlockAsync().Returns(block);
            TransactionVerifierResult result = await _transactionVerifier.VerifyAsync(transaction);

            result.BlockFound.Should().BeTrue();
            result.Confirmed.Should().BeFalse();
            await _blockchainBridge.Received().GetLatestBlockAsync();

            await _blockchainBridge.Received().FindBlockAsync(block.ParentHash);
        }
Example #3
0
        private async Task <bool> TryConfirmClaimAsync(DepositDetails deposit, string type)
        {
            string claimType = $"{type}refund";
            Keccak depositId = deposit.Id;

            NdmTransaction? transactionDetails  = null;
            TransactionInfo includedTransaction = deposit.Transactions.SingleOrDefault(t => t.State == TransactionState.Included);
            IOrderedEnumerable <TransactionInfo> pendingTransactions = deposit.Transactions
                                                                       .Where(t => t.State == TransactionState.Pending)
                                                                       .OrderBy(t => t.Timestamp);

            if (_logger.IsInfo)
            {
                _logger.Info($"Deposit: '{deposit.Id}' refund claim pending transactions: {string.Join(", ", pendingTransactions.Select(t => $"{t.Hash} [{t.Type}]"))}");
            }

            if (includedTransaction is null)
            {
                foreach (TransactionInfo transaction in pendingTransactions)
                {
                    Keccak?transactionHash = transaction.Hash;
                    if (transactionHash is null)
                    {
                        if (_logger.IsInfo)
                        {
                            _logger.Info($"Transaction was not found for hash: '{null}' for deposit: '{depositId}' to claim the {claimType}.");
                        }
                        return(false);
                    }

                    transactionDetails = await _blockchainBridge.GetTransactionAsync(transactionHash);

                    if (transactionDetails is null)
                    {
                        if (_logger.IsInfo)
                        {
                            _logger.Info($"Transaction was not found for hash: '{transactionHash}' for deposit: '{depositId}' to claim the {claimType}.");
                        }
                        return(false);
                    }

                    if (transactionDetails.IsPending)
                    {
                        if (_logger.IsInfo)
                        {
                            _logger.Info($"Transaction with hash: '{transactionHash}' for deposit: '{deposit.Id}' {claimType} claim is still pending.");
                        }
                        return(false);
                    }

                    deposit.SetIncludedClaimedRefundTransaction(transactionHash);
                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Transaction with hash: '{transactionHash}', type: '{transaction.Type}' for deposit: '{deposit.Id}' {claimType} claim was included into block: {transactionDetails.BlockNumber}.");
                    }
                    await _depositRepository.UpdateAsync(deposit);

                    includedTransaction = transaction;
                    break;
                }
            }
            else if (includedTransaction.Type == TransactionType.Cancellation)
            {
                return(false);
            }
            else
            {
                transactionDetails = includedTransaction.Hash == null ? null : await _blockchainBridge.GetTransactionAsync(includedTransaction.Hash);

                if (transactionDetails is null)
                {
                    if (_logger.IsWarn)
                    {
                        _logger.Warn($"Transaction (set as included) was not found for hash: '{includedTransaction.Hash}' for deposit: '{deposit.Id}' {claimType} claim.");
                    }
                    return(false);
                }
            }

            if (includedTransaction is null)
            {
                return(false);
            }

            if (_logger.IsInfo)
            {
                _logger.Info($"Trying to claim the {claimType} (transaction hash: '{includedTransaction.Hash}') for deposit: '{depositId}'.");
            }
            TransactionVerifierResult verifierResult = await _transactionVerifier.VerifyAsync(transactionDetails !);

            if (!verifierResult.BlockFound)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Block number: {transactionDetails!.BlockNumber}, hash: '{transactionDetails.BlockHash}' was not found for transaction hash: '{includedTransaction.Hash}' - {claimType} claim for deposit: '{depositId}' will not confirmed.");
                }
                return(false);
            }

            if (_logger.IsInfo)
            {
                _logger.Info($"The {claimType} claim (transaction hash: '{includedTransaction.Hash}') for deposit: '{depositId}' has {verifierResult.Confirmations} confirmations (required at least {verifierResult.RequiredConfirmations}).");
            }
            if (!verifierResult.Confirmed)
            {
                return(false);
            }

            deposit.SetRefundClaimed();
            await _depositRepository.UpdateAsync(deposit);

            if (_logger.IsInfo)
            {
                _logger.Info($"The {claimType} claim (transaction hash: '{includedTransaction.Hash}') for deposit: '{depositId}' has been confirmed.");
            }

            return(true);
        }