def test_convert_transaction_to_int(self): transaction = Transaction(tx="79283647", receivers=[ TransactionReceiver(address="9782364", amount=0.40), TransactionReceiver(address="9782364", amount=0.30) ]) expected_result = Transaction( tx="79283647", receivers=[ TransactionReceiver(address="9782364", amount=40), TransactionReceiver(address="9782364", amount=30) ]) with patch.object(self._integer_converter, 'safely_convert_to_int'): def stub(amount: float): return int(amount * 100) self._integer_converter.safely_convert_to_int.side_effect = stub actual_result = self._integer_converter.convert_transaction_to_int( transaction) self.assertEqual(actual_result, expected_result) self.assertEqual( self._integer_converter.safely_convert_to_int.call_count, 2)
def test_revert_transaction_conversion(self): expected_result = Transaction( tx="79283647", receivers=[ TransactionReceiver(address="9782364", amount=0.40), TransactionReceiver(address="9782364", amount=0.30) ]) transaction = Transaction(tx="79283647", receivers=[ TransactionReceiver(address="9782364", amount=40), TransactionReceiver(address="9782364", amount=30) ]) with patch.object(self._integer_converter, 'revert_amount_conversion'): def stub(amount: float): return float(amount / 100) self._integer_converter.revert_amount_conversion.side_effect = stub actual_result = self._integer_converter.revert_transaction_conversion( transaction) self.assertEqual(actual_result, expected_result)
def test_iteration_filter_one_transaction(self): """Two transactions were given, one should be filtered and the other one not.""" height_of_highest_block = 30 last_checked_coin_block_height = height_of_highest_block - self._last_block_distance - 1 not_filtered_transaction = Transaction(tx="tx", receivers=[self._gateway_managed_address_receiver]) filtered_transaction = Transaction(tx="khj", receivers=[TransactionReceiver(address="92634867", amount=3425)]) self._block_height_storage.get_last_checked_block_height.return_value = last_checked_coin_block_height self._chain_query_service.get_height_of_highest_block.return_value = height_of_highest_block self._polling_state_storage.get_polling_state.return_value = None def _get_transactions_of_block_at_height(height: int): if height == (last_checked_coin_block_height + 1): return [not_filtered_transaction, filtered_transaction] else: return [] self._chain_query_service.get_transactions_of_block_at_height.side_effect = _get_transactions_of_block_at_height self._transaction_polling_service._iteration() self._transaction_consumer.filter_transaction.assert_any_call(not_filtered_transaction) self._transaction_consumer.filter_transaction.assert_any_call(filtered_transaction) self._transaction_consumer.handle_transaction.assert_called_once_with(not_filtered_transaction) self._chain_query_service.get_transactions_of_block_at_height.assert_called_once_with( last_checked_coin_block_height + 1) self._block_height_storage.set_last_checked_block_height.assert_called_once_with( last_checked_coin_block_height + 1)
def setUp(self): self._gateway_managed_address_receiver = TransactionReceiver("734968234", 832645) self._chain_query_service = MagicMock() self._logger = MagicMock() self._max_handle_transaction_tries = 1 self._polling_state_storage = MagicMock() self._block_height_storage = MagicMock() self._transaction_consumer = MagicMock() self._min_polling_delay = 0.1 self._max_polling_delay = 40 self._last_block_distance = 5 self._scheduler = MagicMock() self._transaction_polling_service = TransactionPollingService( chain_query_service=cast(ChainQueryService, self._chain_query_service), logger=cast(Logger, self._logger), block_height_storage=cast(BlockHeightStorageProxy, self._block_height_storage), transaction_consumer=cast(TransactionConsumer, self._transaction_consumer), max_handle_transaction_tries=self._max_handle_transaction_tries, polling_state_storage=cast(PollingStateStorageProxy, self._polling_state_storage), min_polling_delay_s=self._min_polling_delay, max_polling_delay_s=self._max_polling_delay, last_block_distance=self._last_block_distance) self._apply_filter_transaction_mock()
def convert_transaction_to_int(self, transaction: Transaction) -> Transaction: res = deepcopy(transaction) for i in range(0, len(res.receivers)): receiver = res.receivers[i] res.receivers[i] = TransactionReceiver(receiver.address, self.safely_convert_to_int(receiver.amount)) return res
def revert_transaction_conversion(self, transaction: Transaction) -> Transaction: res = deepcopy(transaction) for i in range(0, len(res.receivers)): receiver = res.receivers[i] res.receivers[i] = TransactionReceiver(receiver.address, self.revert_amount_conversion(cast(int, receiver.amount))) return res
def test_filter_transaction_already_exists(self): """ Should not pass a transaction that is existing in one of the attempt lists """ transaction = Transaction( tx="78265", receivers=[TransactionReceiver('28734', 7823)]) self._attempt_list_storage.gateway_transaction_exists.return_value = True res = self._waves_transaction_consumer_impl.filter_transaction( transaction) self.assertFalse(res)
def setUp(self): self._waves_standard_fee = 10000 self._coin_standard_fee = 10111 self._gateway_managed_receiver = TransactionReceiver('826323', 7710475) self._not_gateway_managed_receiver = TransactionReceiver( '871263', 9992323) self._wallet_storage = MagicMock(spec=WalletStorage) self._coin_chain_query_service = MagicMock(spec=ChainQueryService) self._gateway_address = '7625897' self._gateway_coin_holder_receiver = TransactionReceiver( self._gateway_address, 6758) self._map_storage = MagicMock() self._logger = MagicMock() self._waves_transaction_storage = MagicMock() self._gateway_waves_address = "jshdj" self._gateway_owner_address = '263587234' self._attempt_service = MagicMock() self._fee_service = MagicMock() self._gateway_fee = 2344 self._gateway_pywaves_address = MagicMock() self._gateway_pywaves_address.address = self._gateway_waves_address self._attempt_list_storage = MagicMock() self._coin_transaction_consumer_impl = CoinTransactionConsumerImpl( attempt_service=cast(TransactionAttemptListService, self._attempt_service), gateway_coin_address=self._gateway_address, map_storage=cast(MapStorage, self._map_storage), logger=cast(Logger, self._logger), gateway_waves_address=self._gateway_waves_address, gateway_owner_address=self._gateway_owner_address, fee_service=cast(FeeService, self._fee_service), only_one_transaction_receiver=True, gateway_pywaves_address=cast(pywaves.Address, self._gateway_pywaves_address), attempt_list_storage=cast(TransactionAttemptListStorage, self._attempt_list_storage)) self._fee_service.get_coin_fee.return_value = self._coin_standard_fee self._fee_service.get_gateway_fee.return_value = self._gateway_fee self._fee_service.get_waves_fee.return_value = self._waves_standard_fee
def test_filter_transaction_by_receiver_failure(self): """ Should not pass a transaction with only one receiver which does not equal the gateway address """ transaction = Transaction( tx="78265", receivers=[TransactionReceiver('28734', 7823)]) self._attempt_list_storage.gateway_transaction_exists.return_value = False res = self._waves_transaction_consumer_impl.filter_transaction( transaction) self._attempt_list_storage.find_by_trigger.assert_not_called() self.assertFalse(res)
def test_get_transactions_of_block_at_height(self, mock_requests_get: MagicMock): mock_get_result = MagicMock() mock_get_result.ok = True transactions = [{ 'signature': '5Kg1u9AUix8H3xkPGpHBCuFptCJJwMGkYcdRitsCuSd' 'Zidcf19DoMNMJUKvRrRw2SjF5fGgedZJiJWwZ5DRENM64', 'id': 'HR96p2fuceFm2P1wbs8FtxyeoPmGooKjHmV1gHUhZ5U2', 'assetId': self._asset_id, 'amount': 110000, 'feeAsset': None, 'fee': 100000, 'recipient': 'address:3Mxjf6da1ixZD5UzM7H9rLXLWzfv5YXZvVn', 'attachment': 'B4GdmuG3Jbxg7DLNWu3YrXiFbdQzPiCYBGqqunsG3', 'senderPublicKey': '3bwjGNumMn4K5Yzt154PFegJN4StPvdQ6HAhzbDnCP1m', 'timestamp': 1502026364974, 'type': 4, 'sender': '3Mxjf6da1ixZD5UzM7H9rLXLWzfv5YXZvVn' }] mock_get_result.text = json.dumps({'transactions': transactions}) mock_requests_get.return_value = mock_get_result # self._chain_query_service._get_response_from_node.return_value = {'transactions': transactions} transactions = self._chain_query_service.get_transactions_of_block_at_height( 20) expected_transaction = Transaction( tx='HR96p2fuceFm2P1wbs8FtxyeoPmGooKjHmV1gHUhZ5U2', receivers=[ TransactionReceiver( address='3Mxjf6da1ixZD5UzM7H9rLXLWzfv5YXZvVn', amount=110000) ]) self.assertEqual(len(transactions), 1) self.assertEqual(transactions[0], expected_transaction)
def send_coin(self, attempt: TransactionAttempt, secret: Optional[str]) -> Transaction: if attempt.sender != self._gateway_pywaves_address.address: raise PyWavesError('Missing secret for sender ' + attempt.sender) transaction = self._gateway_pywaves_address.sendAsset( recipient=pw.Address(attempt.receivers[0].address), asset=self._w_ltc, amount=attempt.receivers[0].amount, txFee=attempt.fee) if transaction is None: raise PyWavesError("Encountered an unknown exception while trying to perform waves transaction.") return Transaction( tx=transaction['id'], receivers=[TransactionReceiver(transaction['recipient'], attempt.receivers[0].amount)])
def setUp(self): self._coin_standard_fee = 7269 self._gateway_waves_receiver = TransactionReceiver("9823748", 923235) self._gateway_waves_address_secret = KeyPair(public="9238746", secret="9236478") self._coin_transaction_service = MagicMock() self._waves_chain_query_service = MagicMock( spec=WavesChainQueryServiceImpl) self._waves_transaction_storage = MagicMock() self._logger = MagicMock() self._gateway_coin_address_secret = KeyPair(public="9374682o", secret="sdkjrlig") self._coin_transaction_storage = MagicMock() self._gateway_owner_coin_holder = "23u4oi362" self._gateway_fee = 0 self._gateway_owner_address = "923768" self._fee_service = MagicMock() self._only_one_transaction_receiver = True self._attempt_service = MagicMock() self._gateway_pywaves_address = MagicMock() self._gateway_pywaves_address.address = self._gateway_waves_receiver.address self._attempt_list_storage = MagicMock() self._coin_address_validation_service = MagicMock() self._waves_transaction_consumer_impl = WavesTransactionConsumerImpl( gateway_waves_address_secret=self._gateway_waves_address_secret, waves_chain_query_service=cast(WavesChainQueryServiceImpl, self._waves_chain_query_service), logger=cast(Logger, self._logger), gateway_owner_address=self._gateway_owner_address, gateway_coin_address_secret=self._gateway_coin_address_secret, fee_service=cast(FeeService, self._fee_service), only_one_transaction_receiver=cast( bool, self._only_one_transaction_receiver), attempt_service=cast(TransactionAttemptListService, self._attempt_service), gateway_pywaves_address=cast(pywaves.Address, self._gateway_pywaves_address), attempt_list_storage=cast(TransactionAttemptListStorage, self._attempt_list_storage), coin_address_validation_service=cast( AddressValidationService, self._coin_address_validation_service)) self._fee_service.get_coin_fee.return_value = self._coin_standard_fee self._fee_service.get_gateway_fee.return_value = self._gateway_fee
def test_iteration_do_nothing(self): """In the case of a fresh start, the handle_transaction method should not be called.""" height_of_highest_block = 30 transaction = Transaction(tx="tx", receivers=[TransactionReceiver("receiver", 6587)]) self._block_height_storage.get_last_checked_block_height.return_value = None self._chain_query_service.get_height_of_highest_block.return_value = height_of_highest_block self._chain_query_service.get_transactions_of_block_at_height.return_value = [transaction] self._transaction_consumer.filter_transaction.return_value = False self._polling_state_storage.get_polling_state.return_value = None self._transaction_polling_service._iteration() self._transaction_consumer.filter_transaction.assert_not_called() self._transaction_consumer.handle_transaction.assert_not_called() self._chain_query_service.get_transactions_of_block_at_height.assert_not_called() self._block_height_storage.set_last_checked_block_height.assert_called_once_with(height_of_highest_block)
def _convert_node_response_to_transaction(self, res: dict) -> Optional[Transaction]: if 'assetId' not in res or res['assetId'] != self._asset_id: return None if res['type'] != 4: return None try: address = res['recipient'].split(':')[1] except IndexError: address = res['recipient'] try: sender = res['sender'].split(':')[1] except IndexError: sender = res['sender'] return Transaction( tx=res['id'], receivers=[TransactionReceiver(address=address, amount=res['amount'])], senders=[TransactionSender(address=sender)])