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); }
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); }
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); }
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); }