public async Task <RefundClaimStatus> TryClaimRefundAsync(DepositDetails deposit, Address refundTo)
        {
            ulong now = _timestamper.EpochSeconds;

            if (!deposit.CanClaimRefund(now))
            {
                return(RefundClaimStatus.Empty);
            }

            Block?latestBlock = await _blockchainBridge.GetLatestBlockAsync();

            if (latestBlock == null)
            {
                return(RefundClaimStatus.Empty);
            }

            now = (ulong)latestBlock.Timestamp;
            if (!deposit.CanClaimRefund(now))
            {
                return(RefundClaimStatus.Empty);
            }

            Keccak depositId       = deposit.Deposit.Id;
            Keccak?transactionHash = deposit.ClaimedRefundTransaction?.Hash;

            if (transactionHash is null)
            {
                Address     provider    = deposit.DataAsset.Provider.Address;
                RefundClaim refundClaim = new RefundClaim(depositId, deposit.DataAsset.Id, deposit.Deposit.Units,
                                                          deposit.Deposit.Value, deposit.Deposit.ExpiryTime, deposit.Pepper, provider, refundTo);
                UInt256 gasPrice = await _gasPriceService.GetCurrentAsync();

                transactionHash = await _refundService.ClaimRefundAsync(refundTo, refundClaim, gasPrice);

                if (transactionHash is null)
                {
                    if (_logger.IsError)
                    {
                        _logger.Error("There was an error when trying to claim refund (no transaction hash returned).");
                    }
                    return(RefundClaimStatus.Empty);
                }

                deposit.AddClaimedRefundTransaction(TransactionInfo.Default(transactionHash, 0, gasPrice,
                                                                            _refundService.GasLimit, _timestamper.EpochSeconds));
                await _depositRepository.UpdateAsync(deposit);

                if (_logger.IsInfo)
                {
                    _logger.Info($"Claimed a refund for deposit: '{depositId}', gas price: {gasPrice} wei, transaction hash: '{transactionHash}' (awaits a confirmation).");
                }
            }

            bool confirmed = await TryConfirmClaimAsync(deposit, string.Empty);

            return(confirmed
                ? RefundClaimStatus.Confirmed(transactionHash)
                : RefundClaimStatus.Unconfirmed(transactionHash));
        }
Exemple #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()
        {
            var block       = GetBlock();
            var transaction = GetTransaction();

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

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

            await _blockchainBridge.Received().FindBlockAsync(block.ParentHash);
        }
Exemple #3
0
        public async Task <TransactionVerifierResult> VerifyAsync(NdmTransaction transaction)
        {
            int   confirmations = 0;
            Block?latestBlock   = await _blockchainBridge.GetLatestBlockAsync();

            if (latestBlock is null)
            {
                return(new TransactionVerifierResult(false, 0, _requiredBlockConfirmations));
            }

            do
            {
                confirmations++;
                if (latestBlock.Hash == transaction.BlockHash)
                {
                    break;
                }

                latestBlock = await _blockchainBridge.FindBlockAsync(latestBlock.ParentHash);

                if (latestBlock is null)
                {
                    confirmations = 0;
                    break;
                }

                if (confirmations == _requiredBlockConfirmations)
                {
                    break;
                }
            } while (confirmations < _requiredBlockConfirmations);

            return(new TransactionVerifierResult(true, confirmations, _requiredBlockConfirmations));
        }
        public async Task TryClaimRefundAsync(DepositDetails deposit, Address refundTo)
        {
            var now = _timestamper.EpochSeconds;

            if (!deposit.CanClaimRefund(now))
            {
                return;
            }

            var latestBlock = await _blockchainBridge.GetLatestBlockAsync();

            now = (ulong)latestBlock.Timestamp;
            if (!deposit.CanClaimRefund(now))
            {
                return;
            }

            var depositId       = deposit.Deposit.Id;
            var transactionHash = deposit.ClaimedRefundTransactionHash;

            if (transactionHash is null)
            {
                var provider    = deposit.DataAsset.Provider.Address;
                var refundClaim = new RefundClaim(depositId, deposit.DataAsset.Id, deposit.Deposit.Units,
                                                  deposit.Deposit.Value, deposit.Deposit.ExpiryTime, deposit.Pepper, provider, refundTo);
                transactionHash = await _refundService.ClaimRefundAsync(refundTo, refundClaim);

                deposit.SetClaimedRefundTransactionHash(transactionHash);
                await _depositRepository.UpdateAsync(deposit);

                if (_logger.IsInfo)
                {
                    _logger.Info($"Claimed a refund for deposit: '{depositId}', transaction hash: '{transactionHash}' (awaits a confirmation).");
                }
            }

            await TryConfirmClaimAsync(deposit, string.Empty);
        }
        public async Task get_latest_block_should_invoke_proxy_eth_getBlockByNumber_with_latest_argument()
        {
            var blockModel = GetBlockModel();

            _proxy.eth_getBlockByNumber(Arg.Is <BlockParameterModel>(x => x.Type == BlockParameterModel.Latest.Type))
            .Returns(RpcResult <BlockModel> .Ok(blockModel));
            var block = await _ndmBridge.GetLatestBlockAsync();

            await _proxy.Received()
            .eth_getBlockByNumber(Arg.Is <BlockParameterModel>(x => x.Type == BlockParameterModel.Latest.Type));

            block.Should().NotBeNull();
            ValidateBlock(block, blockModel);
        }
Exemple #6
0
        public async Task get_latest_block_number_should_return_null_if_head_is_null()
        {
            var result = await _ndmBridge.GetLatestBlockAsync();

            result.Should().BeNull();
        }