Exemple #1
0
        public async Task find_block_by_hash_should_invoke_blockchain_bridge_find_block_by_hash()
        {
            var block = Build.A.Block.TestObject;

            _blockchainBridge.FindBlock(block.Hash).Returns(block);
            var result = await _ndmBridge.FindBlockAsync(block.Hash);

            _blockchainBridge.Received().FindBlock(block.Hash);
            result.Should().Be(block);
        }
        public async Task find_block_by_hash_should_invoke_proxy_eth_getBlockByHash()
        {
            var blockModel = GetBlockModel();

            _proxy.eth_getBlockByHash(blockModel.Hash).Returns(RpcResult <BlockModel> .Ok(blockModel));
            var block = await _ndmBridge.FindBlockAsync(blockModel.Hash);

            await _proxy.Received().eth_getBlockByHash(blockModel.Hash);

            block.Should().NotBeNull();
            ValidateBlock(block, blockModel);
        }
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 try_confirm_should_skip_further_processing_if_confirmation_timestamp_is_0()
        {
            const int  latestBlockNumber     = 3;
            const uint confirmationTimestamp = 0;
            var        block       = GetBlock();
            var        deposit     = GetDepositDetails();
            var        transaction = GetTransaction();

            _blockchainBridge.GetTransactionAsync(deposit.Transaction.Hash).Returns(transaction);
            _blockchainBridge.GetLatestBlockNumberAsync().Returns(latestBlockNumber);
            _blockchainBridge.FindBlockAsync(latestBlockNumber).Returns(block);
            _depositService.VerifyDepositAsync(deposit.Consumer, deposit.Id, block.Header.Number)
            .Returns(confirmationTimestamp);
            await _depositConfirmationService.TryConfirmAsync(deposit);

            await _depositService.Received().VerifyDepositAsync(deposit.Consumer, deposit.Id, block.Header.Number);

            await _depositRepository.Received().UpdateAsync(deposit);
        }
Exemple #5
0
        public async Task verify_async_should_return_result_with_confirmed_property_equal_to_true_if_required_number_of_confirmations_is_achieved()
        {
            var transaction = GetTransaction();
            var block       = GetBlock();
            var parentBlock = GetBlock();

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

            result.BlockFound.Should().BeTrue();
            result.Confirmed.Should().BeTrue();
            result.Confirmations.Should().Be(2);
            result.RequiredConfirmations.Should().Be(2);
            await _blockchainBridge.Received().GetLatestBlockAsync();

            await _blockchainBridge.Received(2).FindBlockAsync(block.ParentHash);
        }
Exemple #6
0
        private async Task <(uint confirmations, bool rejected)> VerifyDepositConfirmationsAsync(DepositDetails deposit,
                                                                                                 NdmTransaction transaction, long headNumber)
        {
            if (headNumber <= transaction.BlockNumber)
            {
                return(0, false);
            }

            Keccak?transactionHash = deposit.Transaction?.Hash;
            uint   confirmations   = 0u;
            Block? block           = await _blockchainBridge.FindBlockAsync(headNumber);

            do
            {
                if (block is null)
                {
                    if (_logger.IsWarn)
                    {
                        _logger.Warn("Block was not found.");
                    }
                    return(0, false);
                }

                uint confirmationTimestamp = await _depositService.VerifyDepositAsync(deposit.Consumer, deposit.Id, block.Header.Number);

                if (confirmationTimestamp > 0)
                {
                    confirmations++;
                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Deposit: '{deposit.Id}' has been confirmed in block number: {block.Number}, hash: '{block.Hash}', transaction hash: '{transactionHash}', timestamp: {confirmationTimestamp}.");
                    }
                    if (deposit.ConfirmationTimestamp == 0)
                    {
                        deposit.SetConfirmationTimestamp(confirmationTimestamp);
                        await _depositRepository.UpdateAsync(deposit);
                    }
                }
                else
                {
                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Deposit with id: '{deposit.Id}' has not returned confirmation timestamp from the contract call yet.'");
                    }
                    return(0, false);
                }

                if (confirmations == _requiredBlockConfirmations)
                {
                    break;
                }

                if (transaction.BlockHash == block.Hash || block.Number <= transaction.BlockNumber)
                {
                    break;
                }

                if (block.ParentHash is null)
                {
                    break;
                }

                block = await _blockchainBridge.FindBlockAsync(block.ParentHash);
            } while (confirmations < _requiredBlockConfirmations);

            long latestBlockNumber = await _blockchainBridge.GetLatestBlockNumberAsync();

            long?blocksDifference = latestBlockNumber - transaction.BlockNumber;

            if (blocksDifference >= _requiredBlockConfirmations && confirmations < _requiredBlockConfirmations)
            {
                if (_logger.IsError)
                {
                    _logger.Error($"Deposit: '{deposit.Id}' has been rejected - missing confirmation in block number: {block!.Number}, hash: {block!.Hash}' (transaction hash: '{transactionHash}').");
                }
                return(confirmations, true);
            }

            return(confirmations, false);
        }