def setUp(self): self.node = MockGatewayNode( gateway_helpers.get_gateway_opts(8000, include_default_btc_args=True, include_default_eth_args=True)) self.relay_connection = AbstractRelayConnection( MockSocketConnection(node=self.node, ip_address="127.0.0.1", port=12345), self.node) self.blockchain_connection = EthBaseConnection( MockSocketConnection(node=self.node, ip_address="127.0.0.1", port=12345), self.node) self.node.message_converter = converter_factory.create_eth_message_converter( self.node.opts) dummy_private_key = crypto_utils.make_private_key( helpers.generate_bytearray(111)) dummy_public_key = crypto_utils.private_to_public_key( dummy_private_key) self.blockchain_connection_protocol = EthNodeConnectionProtocol( self.blockchain_connection, True, dummy_private_key, dummy_public_key) self.blockchain_connection.network_num = 0 self.blockchain_connection_protocol.publish_transaction = MagicMock() self.relay_connection.state = ConnectionState.INITIALIZED gateway_transaction_stats_service.set_node(self.node)
def setUp(self): self.node = MockGatewayNode( gateway_helpers.get_gateway_opts( 8000, include_default_btc_args=True, include_default_eth_args=True, split_relays=True, ) ) self.connection = AbstractRelayConnection( MockSocketConnection(node=self.node, ip_address=constants.LOCALHOST, port=12345), self.node ) self.connection.state = ConnectionState.INITIALIZED self.blockchain_connecton = AbstractGatewayBlockchainConnection( MockSocketConnection(node=self.node, ip_address=constants.LOCALHOST, port=333), self.node) self.blockchain_connecton.state = ConnectionState.ESTABLISHED
def _handle_decrypted_block( self, bx_block: memoryview, connection: AbstractRelayConnection, encrypted_block_hash_hex: Optional[str] = None, recovered: bool = False, recovered_txs_source: Optional[RecoveredTxsSource] = None) -> None: transaction_service = self._node.get_tx_service() message_converter = self._node.message_converter assert message_converter is not None valid_block = self._validate_compressed_block_header(bx_block) if not valid_block.is_valid: reason = valid_block.reason assert reason is not None block_stats.add_block_event_by_block_hash( valid_block.block_hash, BlockStatEventType.BLOCK_DECOMPRESSED_FAILED_VALIDATION, connection.network_num, more_info=reason) return # TODO: determine if a real block or test block. Discard if test block. if self._node.remote_node_conn or self._node.has_active_blockchain_peer( ): try: (block_message, block_info, unknown_sids, unknown_hashes) = message_converter.bx_block_to_block( bx_block, transaction_service) block_content_debug_utils.log_compressed_block_debug_info( transaction_service, bx_block) except MessageConversionError as e: block_stats.add_block_event_by_block_hash( e.msg_hash, BlockStatEventType.BLOCK_CONVERSION_FAILED, network_num=connection.network_num, conversion_type=e.conversion_type.value) transaction_service.on_block_cleaned_up(e.msg_hash) connection.log_warning(log_messages.FAILED_TO_DECOMPRESS_BLOCK, e.msg_hash, e) return else: connection.log_warning(log_messages.LACK_BLOCKCHAIN_CONNECTION) return block_hash = block_info.block_hash all_sids = block_info.short_ids if encrypted_block_hash_hex is not None: block_stats.add_block_event_by_block_hash( block_hash, BlockStatEventType.BLOCK_TO_ENC_BLOCK_MATCH, matching_block_hash=encrypted_block_hash_hex, matching_block_type=StatBlockType.ENCRYPTED.value, network_num=connection.network_num) self.cancel_hold_timeout(block_hash, connection) if recovered: block_stats.add_block_event_by_block_hash( block_hash, BlockStatEventType.BLOCK_RECOVERY_COMPLETED, network_num=connection.network_num, more_info=str(recovered_txs_source)) if block_hash in self._node.blocks_seen.contents: block_stats.add_block_event_by_block_hash( block_hash, BlockStatEventType.BLOCK_DECOMPRESSED_IGNORE_SEEN, start_date_time=block_info.start_datetime, end_date_time=block_info.end_datetime, network_num=connection.network_num, prev_block_hash=block_info.prev_block_hash, original_size=block_info.original_size, compressed_size=block_info.compressed_size, txs_count=block_info.txn_count, blockchain_network=self._node.opts.blockchain_network, blockchain_protocol=self._node.opts.blockchain_protocol, matching_block_hash=block_info.compressed_block_hash, matching_block_type=StatBlockType.COMPRESSED.value, more_info=stats_format.duration(block_info.duration_ms)) self._node.track_block_from_bdn_handling_ended(block_hash) transaction_service.track_seen_short_ids(block_hash, all_sids) connection.log_info("Discarding duplicate block {} from the BDN.", block_hash) if block_message is not None: self._node.on_block_received_from_bdn(block_hash, block_message) if self._node.block_queuing_service_manager.get_block_data( block_hash) is None: self._node.block_queuing_service_manager.store_block_data( block_hash, block_message) return if not recovered: connection.log_info("Received block {} from the BDN.", block_hash) else: connection.log_info("Successfully recovered block {}.", block_hash) if block_message is not None: compression_rate = block_info.compression_rate assert compression_rate is not None block_stats.add_block_event_by_block_hash( block_hash, BlockStatEventType.BLOCK_DECOMPRESSED_SUCCESS, start_date_time=block_info.start_datetime, end_date_time=block_info.end_datetime, network_num=connection.network_num, prev_block_hash=block_info.prev_block_hash, original_size=block_info.original_size, compressed_size=block_info.compressed_size, txs_count=block_info.txn_count, blockchain_network=self._node.opts.blockchain_network, blockchain_protocol=self._node.opts.blockchain_protocol, matching_block_hash=block_info.compressed_block_hash, matching_block_type=StatBlockType.COMPRESSED.value, more_info="Compression rate {}, Decompression time {}, " "Queued behind {} blocks".format( stats_format.percentage(compression_rate), stats_format.duration(block_info.duration_ms), self._node.block_queuing_service_manager. get_length_of_each_queuing_service_stats_format())) self._on_block_decompressed(block_message) if recovered or self._node.block_queuing_service_manager.is_in_any_queuing_service( block_hash): self._node.block_queuing_service_manager.update_recovered_block( block_hash, block_message) else: self._node.block_queuing_service_manager.push( block_hash, block_message) gateway_bdn_performance_stats_service.log_block_from_bdn() self._node.on_block_received_from_bdn(block_hash, block_message) transaction_service.track_seen_short_ids(block_hash, all_sids) self._node.publish_block(None, block_hash, block_message, FeedSource.BDN_SOCKET) self._node.log_blocks_network_content(self._node.network_num, block_message) else: if self._node.block_queuing_service_manager.is_in_any_queuing_service( block_hash) and not recovered: connection.log_trace( "Handling already queued block again. Ignoring.") return self._node.block_recovery_service.add_block( bx_block, block_hash, unknown_sids, unknown_hashes) block_stats.add_block_event_by_block_hash( block_hash, BlockStatEventType.BLOCK_DECOMPRESSED_WITH_UNKNOWN_TXS, start_date_time=block_info.start_datetime, end_date_time=block_info.end_datetime, network_num=connection.network_num, prev_block_hash=block_info.prev_block_hash, original_size=block_info.original_size, compressed_size=block_info.compressed_size, txs_count=block_info.txn_count, blockchain_network=self._node.opts.blockchain_network, blockchain_protocol=self._node.opts.blockchain_protocol, matching_block_hash=block_info.compressed_block_hash, matching_block_type=StatBlockType.COMPRESSED.value, more_info="{} sids, {} hashes, [{},...]".format( len(unknown_sids), len(unknown_hashes), unknown_sids[:5])) connection.log_info( "Block {} requires short id recovery. Querying BDN...", block_hash) self.start_transaction_recovery(unknown_sids, unknown_hashes, block_hash, connection) if recovered: # should never happen –– this should not be called on blocks that have not recovered connection.log_error(log_messages.BLOCK_DECOMPRESSION_FAILURE, block_hash) else: self._node.block_queuing_service_manager.push( block_hash, waiting_for_recovery=True)
def process_block_key(self, msg, connection: AbstractRelayConnection) -> None: """ Handles key message receive from bloXroute. Looks for the encrypted block and decrypts; otherwise stores for later. """ key = msg.key() block_hash = msg.block_hash() if not self._node.should_process_block_hash(block_hash): return block_stats.add_block_event_by_block_hash( block_hash, BlockStatEventType.ENC_BLOCK_KEY_RECEIVED_BY_GATEWAY_FROM_NETWORK, network_num=connection.network_num, peers=[connection]) if self._node.in_progress_blocks.has_encryption_key_for_hash( block_hash): return if self._node.in_progress_blocks.has_ciphertext_for_hash(block_hash): connection.log_trace( "Cipher text found. Decrypting and sending to node.") decrypt_start_timestamp = time.time() decrypt_start_datetime = datetime.datetime.utcnow() block = self._node.in_progress_blocks.decrypt_and_get_payload( block_hash, key) if block is not None: block_stats.add_block_event_by_block_hash( block_hash, BlockStatEventType.ENC_BLOCK_DECRYPTED_SUCCESS, start_date_time=decrypt_start_datetime, end_date_time=datetime.datetime.utcnow(), network_num=connection.network_num, more_info=stats_format.timespan(decrypt_start_timestamp, time.time())) self._handle_decrypted_block( block, connection, encrypted_block_hash_hex=convert.bytes_to_hex( block_hash.binary)) else: block_stats.add_block_event_by_block_hash( block_hash, BlockStatEventType.ENC_BLOCK_DECRYPTION_ERROR, network_num=connection.network_num) else: connection.log_trace( "No cipher text found on key message. Storing.") self._node.in_progress_blocks.add_key(block_hash, key) conns = self._node.broadcast( msg, connection, connection_types=(ConnectionType.GATEWAY, )) if len(conns) > 0: block_stats.add_block_event_by_block_hash( block_hash, BlockStatEventType.ENC_BLOCK_KEY_SENT_BY_GATEWAY_TO_PEERS, network_num=self._node.network_num, peers=conns)
def process_block_broadcast(self, msg, connection: AbstractRelayConnection) -> None: """ Handle broadcast message receive from bloXroute. This is typically an encrypted block. """ # TODO handle the situation where txs that received from relays while syncing are in the blocks that were # ignored while syncing, so these txs won't be cleaned for 3 days if not self._node.should_process_block_hash(msg.block_hash()): return block_stats.add_block_event( msg, BlockStatEventType.ENC_BLOCK_RECEIVED_BY_GATEWAY_FROM_NETWORK, network_num=connection.network_num, more_info=stats_format.connection(connection)) block_hash = msg.block_hash() is_encrypted = msg.is_encrypted() self._node.track_block_from_bdn_handling_started( block_hash, connection.peer_desc) if not is_encrypted: block = msg.blob() self._handle_decrypted_block(block, connection) return cipherblob = msg.blob() expected_hash = Sha256Hash(crypto.double_sha256(cipherblob)) if block_hash != expected_hash: connection.log_warning(log_messages.BLOCK_WITH_INCONSISTENT_HASHES, expected_hash, block_hash) return if self._node.in_progress_blocks.has_encryption_key_for_hash( block_hash): connection.log_trace( "Already had key for received block. Sending block to node.") decrypt_start_timestamp = time.time() decrypt_start_datetime = datetime.datetime.utcnow() block = self._node.in_progress_blocks.decrypt_ciphertext( block_hash, cipherblob) if block is not None: block_stats.add_block_event( msg, BlockStatEventType.ENC_BLOCK_DECRYPTED_SUCCESS, start_date_time=decrypt_start_datetime, end_date_time=datetime.datetime.utcnow(), network_num=connection.network_num, more_info=stats_format.timespan(decrypt_start_timestamp, time.time())) self._handle_decrypted_block( block, connection, encrypted_block_hash_hex=convert.bytes_to_hex( block_hash.binary)) else: block_stats.add_block_event( msg, BlockStatEventType.ENC_BLOCK_DECRYPTION_ERROR, network_num=connection.network_num) else: connection.log_trace("Received encrypted block. Storing.") self._node.in_progress_blocks.add_ciphertext( block_hash, cipherblob) block_received_message = BlockReceivedMessage(block_hash) conns = self._node.broadcast( block_received_message, connection, connection_types=(ConnectionType.GATEWAY, )) block_stats.add_block_event_by_block_hash( block_hash, BlockStatEventType.ENC_BLOCK_SENT_BLOCK_RECEIPT, network_num=connection.network_num, peers=conns, )
class AbstractRelayConnectionTest(AbstractTestCase): def setUp(self): self.node = MockGatewayNode( gateway_helpers.get_gateway_opts(8000, include_default_btc_args=True, include_default_eth_args=True)) self.connection = AbstractRelayConnection( MockSocketConnection(node=self.node, ip_address="127.0.0.1", port=12345), self.node) self.connection.state = ConnectionState.INITIALIZED self.blockchain_connecton = AbstractGatewayBlockchainConnection( MockSocketConnection(node=self.node, ip_address="127.0.0.1", port=333), self.node) self.blockchain_connecton.state = ConnectionState.ESTABLISHED self.node.node_conn = self.blockchain_connecton @patch( "bxgateway.services.block_processing_service.BlockProcessingService._handle_decrypted_block" ) def test_msg_broadcast_encrypted(self, mock_handle_decrypted_block): msg_bytes = helpers.generate_bytearray(50) msg_hash = Sha256Hash(crypto.double_sha256(msg_bytes)) broadcast_msg = BroadcastMessage(message_hash=msg_hash, network_num=1, is_encrypted=True, blob=msg_bytes) self.connection.msg_broadcast(broadcast_msg) self.assertTrue( self.node.in_progress_blocks.has_ciphertext_for_hash(msg_hash)) self.assertEqual(1, len(self.node.broadcast_messages)) self.assertIsInstance(self.node.broadcast_messages[0][0], BlockReceivedMessage) mock_handle_decrypted_block.assert_not_called() @patch( "bxgateway.services.block_processing_service.BlockProcessingService._handle_decrypted_block" ) def test_msg_broadcast_unencrypted(self, mock_handle_decrypted_block): msg_bytes = helpers.generate_bytearray(50) msg_hash = Sha256Hash(crypto.double_sha256(msg_bytes)) broadcast_msg = BroadcastMessage(message_hash=msg_hash, network_num=1, is_encrypted=False, blob=msg_bytes) self.connection.msg_broadcast(broadcast_msg) self.assertFalse( self.node.in_progress_blocks.has_ciphertext_for_hash(msg_hash)) self.assertEqual(0, len(self.node.broadcast_messages)) mock_handle_decrypted_block.assert_called_once() def test_msg_tx__full_message(self): tx_service = self.connection.node.get_tx_service() short_id = 1 tx_hash = helpers.generate_object_hash() tx_content = helpers.generate_bytearray(250) full_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=short_id, tx_val=tx_content) self.connection.msg_tx(full_message) self.assertEqual(short_id, tx_service.get_short_id(tx_hash)) self.assertEqual(tx_content, tx_service.get_transaction_by_hash(tx_hash)) def test_msg_tx__compact_then_full(self): tx_service = self.connection.node.get_tx_service() short_id = 1 tx_hash = helpers.generate_object_hash() tx_content = helpers.generate_bytearray(250) compact_tx_msg = TxMessage(message_hash=tx_hash, network_num=1, short_id=short_id) no_short_id_tx_msg = TxMessage(message_hash=tx_hash, network_num=1, tx_val=tx_content) self.connection.msg_tx(compact_tx_msg) self.connection.msg_tx(no_short_id_tx_msg) self.assertEqual(short_id, tx_service.get_short_id(tx_hash)) self.assertEqual(tx_content, tx_service.get_transaction_by_hash(tx_hash)) def test_ping_pong(self): hello_msg = HelloMessage( protocol_version=protocol_version.PROTOCOL_VERSION, network_num=1) self.connection.add_received_bytes(hello_msg.rawbytes()) self.connection.process_message() hello_msg_bytes = self.connection.get_bytes_to_send() self.assertTrue(len(hello_msg_bytes) > 0) self.connection.advance_sent_bytes(len(hello_msg_bytes)) ack_msg = AckMessage() self.connection.add_received_bytes(ack_msg.rawbytes()) self.connection.process_message() ack_msg_bytes = self.connection.get_bytes_to_send() self.assertTrue(len(ack_msg_bytes) > 0) self.connection.advance_sent_bytes(len(ack_msg_bytes)) ping_msg = PingMessage(nonce=12345) self.connection.add_received_bytes(ping_msg.rawbytes()) self.connection.process_message() pong_msg_bytes = self.connection.get_bytes_to_send() self.assertTrue(len(pong_msg_bytes) > 0) msg_type, payload_len = AbstractBloxrouteMessage.unpack( pong_msg_bytes[:AbstractBloxrouteMessage.HEADER_LENGTH]) self.assertEqual(BloxrouteMessageType.PONG, msg_type) self.connection.advance_sent_bytes(len(pong_msg_bytes)) time.time = MagicMock(return_value=time.time() + constants.PING_INTERVAL_S) self.node.alarm_queue.fire_alarms() ping_msg_bytes = self.connection.get_bytes_to_send() self.assertTrue(len(ping_msg_bytes) > 0) msg_type, payload_len = AbstractBloxrouteMessage.unpack( ping_msg_bytes[:AbstractBloxrouteMessage.HEADER_LENGTH]) self.assertEqual(BloxrouteMessageType.PING, msg_type) @patch( "bxgateway.connections.abstract_relay_connection.AbstractRelayConnection.log" ) def test_msg_notification(self, log): args_list = [ "10", str(QuotaType.FREE_DAILY_QUOTA.value), str(EntityType.TRANSACTION.value), "100" ] args = ",".join(args_list) notification_msg = NotificationMessage( NotificationCode.QUOTA_FILL_STATUS, args) log.assert_not_called() self.connection.msg_notify(notification_msg) log.assert_called_once()
def _handle_decrypted_consensus_block( self, bx_block: memoryview, connection: AbstractRelayConnection, encrypted_block_hash_hex: Optional[str] = None, recovered: bool = False, recovered_txs_source: Optional[RecoveredTxsSource] = None ): transaction_service = self._node.get_tx_service() if self._node.has_active_blockchain_peer() or self._node.remote_node_conn: try: block_message, block_info, unknown_sids, unknown_hashes = \ self._node.consensus_message_converter.bx_block_to_block(bx_block, transaction_service) except MessageConversionError as e: block_stats.add_block_event_by_block_hash( e.msg_hash, BlockStatEventType.BLOCK_CONVERSION_FAILED, network_num=connection.network_num, broadcast_type=BroadcastMessageType.CONSENSUS, conversion_type=e.conversion_type.value ) transaction_service.on_block_cleaned_up(e.msg_hash) connection.log_warning(log_messages.FAILED_TO_DECOMPRESS_BLOCK_ONT_CONSENSUS, e.msg_hash, e) return else: connection.log_warning(log_messages.LACK_BLOCKCHAIN_CONNECTION_ONT_CONSENSUS) return block_hash = block_info.block_hash all_sids = block_info.short_ids if encrypted_block_hash_hex is not None: block_stats.add_block_event_by_block_hash(block_hash, BlockStatEventType.BLOCK_TO_ENC_BLOCK_MATCH, matching_block_hash=encrypted_block_hash_hex, matching_block_type=StatBlockType.ENCRYPTED.value, network_num=connection.network_num, broadcast_type=BroadcastMessageType.CONSENSUS) self.cancel_hold_timeout(block_hash, connection) if recovered: block_stats.add_block_event_by_block_hash(block_hash, BlockStatEventType.BLOCK_RECOVERY_COMPLETED, network_num=connection.network_num, broadcast_type=BroadcastMessageType.CONSENSUS, more_info=str(recovered_txs_source)) if block_hash in self._node.blocks_seen.contents: block_stats.add_block_event_by_block_hash(block_hash, BlockStatEventType.BLOCK_DECOMPRESSED_IGNORE_SEEN, start_date_time=block_info.start_datetime, end_date_time=block_info.end_datetime, network_num=connection.network_num, broadcast_type=BroadcastMessageType.CONSENSUS, prev_block_hash=block_info.prev_block_hash, original_size=block_info.original_size, compressed_size=block_info.compressed_size, txs_count=block_info.txn_count, blockchain_network=self._node.opts.blockchain_protocol, blockchain_protocol=self._node.opts.blockchain_network, matching_block_hash=block_info.compressed_block_hash, matching_block_type=StatBlockType.COMPRESSED.value, more_info=stats_format.duration(block_info.duration_ms)) self._node.track_block_from_bdn_handling_ended(block_hash) transaction_service.track_seen_short_ids(block_hash, all_sids) connection.log_info( "Discarding duplicate consensus block {} from the BDN.", block_hash ) return if not recovered: connection.log_info("Received consensus block {} from the BDN.", block_hash) else: connection.log_info("Successfully recovered consensus block {}.", block_hash) if block_message is not None: block_stats.add_block_event_by_block_hash(block_hash, BlockStatEventType.BLOCK_DECOMPRESSED_SUCCESS, start_date_time=block_info.start_datetime, end_date_time=block_info.end_datetime, network_num=connection.network_num, broadcast_type=BroadcastMessageType.CONSENSUS, prev_block_hash=block_info.prev_block_hash, original_size=block_info.original_size, compressed_size=block_info.compressed_size, txs_count=block_info.txn_count, blockchain_network=self._node.opts.blockchain_protocol, blockchain_protocol=self._node.opts.blockchain_network, matching_block_hash=block_info.compressed_block_hash, matching_block_type=StatBlockType.COMPRESSED.value, peer=connection.peer_desc, more_info="Consensus compression rate {}, Decompression time {}, " "Queued behind {} blocks".format( stats_format.percentage(block_info.compression_rate), stats_format.duration(block_info.duration_ms), self._node.block_queueing_service_manager.get_length_of_each_queuing_service_stats_format())) if recovered or block_hash in self._node.block_queueing_service_manager: self._node.block_queueing_service_manager.update_recovered_block(block_hash, block_message) else: self._node.block_queueing_service_manager.push(block_hash, block_message) self._node.block_recovery_service.cancel_recovery_for_block(block_hash) # self._node.blocks_seen.add(block_hash) transaction_service.track_seen_short_ids(block_hash, all_sids) else: if block_hash in self._node.block_queueing_service_manager and not recovered: connection.log_trace("Handling already queued consensus block again. Ignoring.") return self._node.block_recovery_service.add_block(bx_block, block_hash, unknown_sids, unknown_hashes) block_stats.add_block_event_by_block_hash(block_hash, BlockStatEventType.BLOCK_DECOMPRESSED_WITH_UNKNOWN_TXS, start_date_time=block_info.start_datetime, end_date_time=block_info.end_datetime, network_num=connection.network_num, broadcast_type=BroadcastMessageType.CONSENSUS, prev_block_hash=block_info.prev_block_hash, original_size=block_info.original_size, compressed_size=block_info.compressed_size, txs_count=block_info.txn_count, blockchain_network=self._node.opts.blockchain_protocol, blockchain_protocol=self._node.opts.blockchain_network, matching_block_hash=block_info.compressed_block_hash, matching_block_type=StatBlockType.COMPRESSED.value, more_info="{} sids, {} hashes".format( len(unknown_sids), len(unknown_hashes))) connection.log_info("Consensus block {} requires short id recovery. Querying BDN...", block_hash) self.start_transaction_recovery(unknown_sids, unknown_hashes, block_hash, connection) if recovered: # should never happen –– this should not be called on blocks that have not recovered connection.log_error(log_messages.BLOCK_DECOMPRESSION_FAILURE_ONT_CONSENSUS, block_hash) else: self._node.block_queueing_service_manager.push(block_hash, waiting_for_recovery=True)
class GatewayTransactionStatsServiceTest(AbstractTestCase): def setUp(self): self.node = MockGatewayNode( gateway_helpers.get_gateway_opts(8000, include_default_btc_args=True, include_default_eth_args=True)) self.relay_connection = AbstractRelayConnection( MockSocketConnection(node=self.node, ip_address="127.0.0.1", port=12345), self.node) self.blockchain_connection = EthBaseConnection( MockSocketConnection(node=self.node, ip_address="127.0.0.1", port=12345), self.node) self.node.message_converter = converter_factory.create_eth_message_converter( self.node.opts) dummy_private_key = crypto_utils.make_private_key( helpers.generate_bytearray(111)) dummy_public_key = crypto_utils.private_to_public_key( dummy_private_key) self.blockchain_connection_protocol = EthNodeConnectionProtocol( self.blockchain_connection, True, dummy_private_key, dummy_public_key) self.blockchain_connection.network_num = 0 self.blockchain_connection_protocol.publish_transaction = MagicMock() self.relay_connection.state = ConnectionState.INITIALIZED gateway_transaction_stats_service.set_node(self.node) def test_tx_stats_new_full_from_relay(self): short_id = 123 tx_hash = helpers.generate_object_hash() tx_content = helpers.generate_bytearray(250) full_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=short_id, tx_val=tx_content) self.relay_connection.msg_tx(full_message) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. new_full_transactions_received_from_relays) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. new_compact_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. short_id_assignments_processed) def test_tx_stats_new_compact_from_relay(self): short_id = 321 tx_hash = helpers.generate_object_hash() compact_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=short_id) self.relay_connection.msg_tx(compact_message) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. new_full_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. new_compact_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. short_id_assignments_processed) def test_tx_stats_duplicate_full_from_relay(self): short_id = 1 tx_hash = helpers.generate_object_hash() tx_content = helpers.generate_bytearray(250) full_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=short_id, tx_val=tx_content) self.relay_connection.msg_tx(full_message) self.relay_connection.msg_tx(full_message) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. new_compact_transactions_received_from_relays) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. duplicate_compact_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. new_full_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. duplicate_full_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. short_id_assignments_processed) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. redundant_transaction_content_messages) def test_tx_stats_duplicate_compact_from_relay(self): short_id = 1 tx_hash = helpers.generate_object_hash() compact_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=short_id) self.relay_connection.msg_tx(compact_message) self.relay_connection.msg_tx(compact_message) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. new_full_transactions_received_from_relays) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. duplicate_full_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. new_compact_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. duplicate_compact_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. short_id_assignments_processed) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. redundant_transaction_content_messages) def test_tx_stats_duplicate_compact_after_full_from_relay(self): short_id = 1 tx_hash = helpers.generate_object_hash() tx_content = helpers.generate_bytearray(250) full_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=short_id, tx_val=tx_content) compact_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=short_id) self.relay_connection.msg_tx(full_message) self.relay_connection.msg_tx(compact_message) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. new_full_transactions_received_from_relays) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. duplicate_full_transactions_received_from_relays) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. new_compact_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. duplicate_compact_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. short_id_assignments_processed) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. redundant_transaction_content_messages) def test_tx_stats_new_full_after_new_compact_from_relay(self): short_id = 1 tx_hash = helpers.generate_object_hash() tx_content = helpers.generate_bytearray(250) compact_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=short_id) full_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=short_id, tx_val=tx_content) self.relay_connection.msg_tx(compact_message) self.relay_connection.msg_tx(full_message) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. new_full_transactions_received_from_relays) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. duplicate_full_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. new_compact_transactions_received_from_relays) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. duplicate_compact_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. short_id_assignments_processed) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. redundant_transaction_content_messages) def test_tx_stats_redundant_tx_contents_from_relay(self): tx_hash = helpers.generate_object_hash() tx_content = helpers.generate_bytearray(250) short_id = 1 full_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=short_id, tx_val=tx_content) self.relay_connection.msg_tx(full_message) short_id = 2 full_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=short_id, tx_val=tx_content) self.relay_connection.msg_tx(full_message) self.assertEqual( 2, gateway_transaction_stats_service.interval_data. new_full_transactions_received_from_relays) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. duplicate_full_transactions_received_from_relays) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. new_compact_transactions_received_from_relays) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. duplicate_compact_transactions_received_from_relays) self.assertEqual( 2, gateway_transaction_stats_service.interval_data. short_id_assignments_processed) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. redundant_transaction_content_messages) def test_tx_stats_multiple_new_compact_from_relay(self): tx_hash = helpers.generate_object_hash() short_id = 1 compact_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=short_id) self.relay_connection.msg_tx(compact_message) short_id = 2 compact_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=short_id) self.relay_connection.msg_tx(compact_message) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. new_full_transactions_received_from_relays) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. duplicate_full_transactions_received_from_relays) self.assertEqual( 2, gateway_transaction_stats_service.interval_data. new_compact_transactions_received_from_relays) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. duplicate_compact_transactions_received_from_relays) self.assertEqual( 2, gateway_transaction_stats_service.interval_data. short_id_assignments_processed) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. redundant_transaction_content_messages) def test_tx_stats_new_from_blockchain_node(self): txs = [ mock_eth_messages.get_dummy_transaction(1), ] tx_msg = TransactionsEthProtocolMessage(None, txs) self.blockchain_connection_protocol.msg_tx(tx_msg) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. new_transactions_received_from_blockchain) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. duplicate_transactions_received_from_blockchain) def test_tx_stats_duplicate_from_blockchain_node(self): txs = [ mock_eth_messages.get_dummy_transaction(7), ] tx_msg = TransactionsEthProtocolMessage(None, txs) self.blockchain_connection_protocol.msg_tx(tx_msg) self.blockchain_connection_protocol.msg_tx(tx_msg) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. new_transactions_received_from_blockchain) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. duplicate_transactions_received_from_blockchain) def test_tx_stats_new_full_relay_duplicate_blockchain_node(self): blockchain_node_txs = [ mock_eth_messages.get_dummy_transaction(7), ] blockchain_node_tx_msg = TransactionsEthProtocolMessage( None, blockchain_node_txs) bx_tx_message = self.node.message_converter.tx_to_bx_txs( blockchain_node_tx_msg, 1) for (msg, tx_hash, tx_bytes) in bx_tx_message: relay_full_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=1, tx_val=tx_bytes) self.relay_connection.msg_tx(relay_full_message) self.blockchain_connection_protocol.msg_tx(blockchain_node_tx_msg) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. new_full_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. short_id_assignments_processed) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. duplicate_transactions_received_from_blockchain) def test_tx_stats_new_compact_relay_new_blockchain_node(self): blockchain_node_txs = [ mock_eth_messages.get_dummy_transaction(7), ] blockchain_node_tx_msg = TransactionsEthProtocolMessage( None, blockchain_node_txs) bx_tx_message = self.node.message_converter.tx_to_bx_txs( blockchain_node_tx_msg, 1) for (msg, tx_hash, tx_bytes) in bx_tx_message: relay_compact_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=1) self.relay_connection.msg_tx(relay_compact_message) self.blockchain_connection_protocol.msg_tx(blockchain_node_tx_msg) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. new_compact_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. short_id_assignments_processed) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. new_transactions_received_from_blockchain) def test_tx_stats_new_blockchain_node_redundant_full_relay(self): blockchain_node_txs = [ mock_eth_messages.get_dummy_transaction(7), ] blockchain_node_tx_msg = TransactionsEthProtocolMessage( None, blockchain_node_txs) self.blockchain_connection_protocol.msg_tx(blockchain_node_tx_msg) time.time = MagicMock(return_value=time.time() + 1) self.node.alarm_queue.fire_alarms() bx_tx_message = self.node.message_converter.tx_to_bx_txs( blockchain_node_tx_msg, 1) for (msg, tx_hash, tx_bytes) in bx_tx_message: relay_full_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=1, tx_val=tx_bytes) self.relay_connection.msg_tx(relay_full_message) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. new_full_transactions_received_from_relays) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. duplicate_full_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. new_transactions_received_from_blockchain) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. short_id_assignments_processed) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. redundant_transaction_content_messages) def test_tx_stats_new_blockchain_node_new_compact_relay(self): blockchain_node_txs = [ mock_eth_messages.get_dummy_transaction(7), ] blockchain_node_tx_msg = TransactionsEthProtocolMessage( None, blockchain_node_txs) self.blockchain_connection_protocol.msg_tx(blockchain_node_tx_msg) bx_tx_message = self.node.message_converter.tx_to_bx_txs( blockchain_node_tx_msg, 1) for (msg, tx_hash, tx_bytes) in bx_tx_message: relay_compact_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=1) self.relay_connection.msg_tx(relay_compact_message) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. new_transactions_received_from_blockchain) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. new_compact_transactions_received_from_relays) self.assertEqual( 1, gateway_transaction_stats_service.interval_data. short_id_assignments_processed) self.assertEqual( 0, gateway_transaction_stats_service.interval_data. redundant_transaction_content_messages)
def setUp(self): self.node = MockGatewayNode(gateway_helpers.get_gateway_opts( 8000, include_default_eth_args=True, use_extensions=True), block_queueing_cls=MagicMock()) self.node.message_converter = converter_factory.create_eth_message_converter( self.node.opts) self.node.block_processing_service = BlockProcessingService(self.node) is_handshake_initiator = True dummy_private_key = crypto_utils.make_private_key( helpers.generate_bytearray(111)) dummy_public_key = crypto_utils.private_to_public_key( dummy_private_key) rlpx_cipher = RLPxCipher(is_handshake_initiator, dummy_private_key, dummy_public_key) node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE, MagicMock()) local_ip = "127.0.0.1" eth_port = 30303 eth_opts = gateway_helpers.get_gateway_opts( 1234, include_default_eth_args=True, blockchain_address=(local_ip, eth_port), pub_key=convert.bytes_to_hex(dummy_public_key)) self.eth_node = EthGatewayNode(eth_opts, node_ssl_service) self.blockchain_connection = EthNodeConnection( MockSocketConnection(1, node=self.node, ip_address=local_ip, port=30303), self.node) self.blockchain_connection.on_connection_established() self.node.connection_pool.add(19, local_ip, eth_port, self.blockchain_connection) self.blockchain_connection_1 = EthNodeConnection( MockSocketConnection(1, node=self.node, ip_address=local_ip, port=333), self.node) self.blockchain_connection_1.on_connection_established() self.node.mock_add_blockchain_peer(self.blockchain_connection_1) self.node_1_endpoint = IpEndpoint(local_ip, 333) self.node.connection_pool.add(20, self.node_1_endpoint.ip_address, self.node_1_endpoint.port, self.blockchain_connection_1) self.blockchain_connection_2 = EthNodeConnection( MockSocketConnection(1, node=self.node, ip_address=local_ip, port=444), self.node) self.blockchain_connection_2.on_connection_established() self.node.mock_add_blockchain_peer(self.blockchain_connection_2) self.node_2_endpoint = IpEndpoint(local_ip, 444) self.node.connection_pool.add(21, self.node_2_endpoint.ip_address, self.node_2_endpoint.port, self.blockchain_connection_2) self.blockchain_connection_1.network_num = 0 self.tx_blockchain_connection_protocol = EthNodeConnectionProtocol( self.blockchain_connection_1, is_handshake_initiator, rlpx_cipher) self.block_blockchain_connection_protocol = EthNodeConnectionProtocol( self.blockchain_connection_1, is_handshake_initiator, rlpx_cipher) self.tx_blockchain_connection_protocol.publish_transaction = MagicMock( ) self.block_blockchain_connection_protocol.publish_transaction = MagicMock( ) self.tx_blockchain_connection_protocol_2 = EthNodeConnectionProtocol( self.blockchain_connection_2, is_handshake_initiator, rlpx_cipher) self.block_blockchain_connection_protocol_2 = EthNodeConnectionProtocol( self.blockchain_connection_2, is_handshake_initiator, rlpx_cipher) self.tx_blockchain_connection_protocol_2.publish_transaction = MagicMock( ) self.block_blockchain_connection_protocol_2.publish_transaction = MagicMock( ) self.relay_connection = AbstractRelayConnection( MockSocketConnection(1, node=self.node, ip_address=local_ip, port=12345), self.node) self.relay_connection.state = ConnectionState.INITIALIZED gateway_bdn_performance_stats_service.set_node(self.node) self.node.account_id = "12345"
class GatewayBdnPerformanceStatsTest(AbstractTestCase): def setUp(self): self.node = MockGatewayNode(gateway_helpers.get_gateway_opts( 8000, include_default_eth_args=True, use_extensions=True), block_queueing_cls=MagicMock()) self.node.message_converter = converter_factory.create_eth_message_converter( self.node.opts) self.node.block_processing_service = BlockProcessingService(self.node) is_handshake_initiator = True dummy_private_key = crypto_utils.make_private_key( helpers.generate_bytearray(111)) dummy_public_key = crypto_utils.private_to_public_key( dummy_private_key) rlpx_cipher = RLPxCipher(is_handshake_initiator, dummy_private_key, dummy_public_key) node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE, MagicMock()) local_ip = "127.0.0.1" eth_port = 30303 eth_opts = gateway_helpers.get_gateway_opts( 1234, include_default_eth_args=True, blockchain_address=(local_ip, eth_port), pub_key=convert.bytes_to_hex(dummy_public_key)) self.eth_node = EthGatewayNode(eth_opts, node_ssl_service) self.blockchain_connection = EthNodeConnection( MockSocketConnection(1, node=self.node, ip_address=local_ip, port=30303), self.node) self.blockchain_connection.on_connection_established() self.node.connection_pool.add(19, local_ip, eth_port, self.blockchain_connection) self.blockchain_connection_1 = EthNodeConnection( MockSocketConnection(1, node=self.node, ip_address=local_ip, port=333), self.node) self.blockchain_connection_1.on_connection_established() self.node.mock_add_blockchain_peer(self.blockchain_connection_1) self.node_1_endpoint = IpEndpoint(local_ip, 333) self.node.connection_pool.add(20, self.node_1_endpoint.ip_address, self.node_1_endpoint.port, self.blockchain_connection_1) self.blockchain_connection_2 = EthNodeConnection( MockSocketConnection(1, node=self.node, ip_address=local_ip, port=444), self.node) self.blockchain_connection_2.on_connection_established() self.node.mock_add_blockchain_peer(self.blockchain_connection_2) self.node_2_endpoint = IpEndpoint(local_ip, 444) self.node.connection_pool.add(21, self.node_2_endpoint.ip_address, self.node_2_endpoint.port, self.blockchain_connection_2) self.blockchain_connection_1.network_num = 0 self.tx_blockchain_connection_protocol = EthNodeConnectionProtocol( self.blockchain_connection_1, is_handshake_initiator, rlpx_cipher) self.block_blockchain_connection_protocol = EthNodeConnectionProtocol( self.blockchain_connection_1, is_handshake_initiator, rlpx_cipher) self.tx_blockchain_connection_protocol.publish_transaction = MagicMock( ) self.block_blockchain_connection_protocol.publish_transaction = MagicMock( ) self.tx_blockchain_connection_protocol_2 = EthNodeConnectionProtocol( self.blockchain_connection_2, is_handshake_initiator, rlpx_cipher) self.block_blockchain_connection_protocol_2 = EthNodeConnectionProtocol( self.blockchain_connection_2, is_handshake_initiator, rlpx_cipher) self.tx_blockchain_connection_protocol_2.publish_transaction = MagicMock( ) self.block_blockchain_connection_protocol_2.publish_transaction = MagicMock( ) self.relay_connection = AbstractRelayConnection( MockSocketConnection(1, node=self.node, ip_address=local_ip, port=12345), self.node) self.relay_connection.state = ConnectionState.INITIALIZED gateway_bdn_performance_stats_service.set_node(self.node) self.node.account_id = "12345" def test_bdn_stats_tx_new_full_from_bdn(self): short_id = 1 tx_hash = helpers.generate_object_hash() tx_content = helpers.generate_bytearray(250) full_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=short_id, tx_val=tx_content) self.relay_connection.msg_tx(full_message) self.assertEqual( 3, len(gateway_bdn_performance_stats_service.interval_data. blockchain_node_to_bdn_stats)) for stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.values( ): self.assertEqual(1, stats.new_tx_received_from_bdn) def test_bdn_stats_tx_new_full_from_bdn_ignore_duplicate(self): short_id = 1 tx_hash = helpers.generate_object_hash() tx_content = helpers.generate_bytearray(250) full_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=short_id, tx_val=tx_content) self.relay_connection.msg_tx(full_message) self.relay_connection.msg_tx(full_message) self.assertEqual( 3, len(gateway_bdn_performance_stats_service.interval_data. blockchain_node_to_bdn_stats)) for stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.values( ): self.assertEqual(1, stats.new_tx_received_from_bdn) def test_bdn_stats_tx_new_from_node_low_fee(self): self.node.opts.blockchain_networks[ self.node.network_num].min_tx_network_fee = 500 blockchain_network = self.tx_blockchain_connection_protocol.connection.node.get_blockchain_network( ) blockchain_network.protocol = "ethereum" txs = [ mock_eth_messages.get_dummy_transaction(1, gas_price=5), ] tx_msg = TransactionsEthProtocolMessage(None, txs) self.assertEqual(1, len(tx_msg.get_transactions())) self.tx_blockchain_connection_protocol.msg_tx(tx_msg) self.assertEqual( 3, len(gateway_bdn_performance_stats_service.interval_data. blockchain_node_to_bdn_stats)) node_1_stats = gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats[ self.node_1_endpoint] for endpoint, stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.items( ): if endpoint == self.node_1_endpoint: continue self.assertEqual(0, stats.new_tx_received_from_bdn) self.assertEqual(0, node_1_stats.new_tx_received_from_blockchain_node) self.assertEqual( 1, node_1_stats.new_tx_received_from_blockchain_node_low_fee) def test_bdn_stats_tx_new_from_node(self): txs = [ mock_eth_messages.get_dummy_transaction(1), ] tx_msg = TransactionsEthProtocolMessage(None, txs) self.tx_blockchain_connection_protocol.msg_tx(tx_msg) self.assertEqual( 3, len(gateway_bdn_performance_stats_service.interval_data. blockchain_node_to_bdn_stats)) node_1_stats = gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats[ self.node_1_endpoint] for endpoint, stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.items( ): if endpoint == self.node_1_endpoint: continue self.assertEqual(1, stats.new_tx_received_from_bdn) self.assertEqual(1, node_1_stats.new_tx_received_from_blockchain_node) def test_bdn_stats_tx_new_from_node_ignore_duplicate(self): txs = [ mock_eth_messages.get_dummy_transaction(1), ] tx_msg = TransactionsEthProtocolMessage(None, txs) self.tx_blockchain_connection_protocol.msg_tx(tx_msg) self.tx_blockchain_connection_protocol.msg_tx(tx_msg) self.assertEqual( 3, len(gateway_bdn_performance_stats_service.interval_data. blockchain_node_to_bdn_stats)) node_1_stats = gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats[ self.node_1_endpoint] for endpoint, stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.items( ): if endpoint == self.node_1_endpoint: continue self.assertEqual(1, stats.new_tx_received_from_bdn) self.assertEqual(1, node_1_stats.new_tx_received_from_blockchain_node) def test_bdn_stats_tx_new_from_node_ignore_duplicate_from_second_node( self): txs = [ mock_eth_messages.get_dummy_transaction(1), ] tx_msg = TransactionsEthProtocolMessage(None, txs) self.tx_blockchain_connection_protocol.msg_tx(tx_msg) self.tx_blockchain_connection_protocol_2.msg_tx(tx_msg) self.assertEqual( 3, len(gateway_bdn_performance_stats_service.interval_data. blockchain_node_to_bdn_stats)) node_1_stats = gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats[ self.node_1_endpoint] for endpoint, stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.items( ): if endpoint == self.node_1_endpoint: continue self.assertEqual(1, stats.new_tx_received_from_bdn) self.assertEqual(1, node_1_stats.new_tx_received_from_blockchain_node) def test_bdn_stats_tx_new_full_from_bdn_ignore_from_node(self): blockchain_node_txs = [ mock_eth_messages.get_dummy_transaction(7), ] blockchain_node_tx_msg = TransactionsEthProtocolMessage( None, blockchain_node_txs) bx_tx_message = self.node.message_converter.tx_to_bx_txs( blockchain_node_tx_msg, 1) for (msg, tx_hash, tx_bytes) in bx_tx_message: relay_full_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=1, tx_val=tx_bytes) self.relay_connection.msg_tx(relay_full_message) self.tx_blockchain_connection_protocol.msg_tx(blockchain_node_tx_msg) self.assertEqual( 3, len(gateway_bdn_performance_stats_service.interval_data. blockchain_node_to_bdn_stats)) for stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.values( ): self.assertEqual(1, stats.new_tx_received_from_bdn) self.assertEqual(0, stats.new_tx_received_from_blockchain_node) def test_bdn_stats_tx_new_from_node_ignore_from_bdn(self): blockchain_node_txs = [ mock_eth_messages.get_dummy_transaction(7), ] blockchain_node_tx_msg = TransactionsEthProtocolMessage( None, blockchain_node_txs) self.tx_blockchain_connection_protocol.msg_tx(blockchain_node_tx_msg) time.time = MagicMock(return_value=time.time() + 1) self.node.alarm_queue.fire_alarms() bx_tx_message = self.node.message_converter.tx_to_bx_txs( blockchain_node_tx_msg, 1) for (msg, tx_hash, tx_bytes) in bx_tx_message: relay_full_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=1, tx_val=tx_bytes) self.relay_connection.msg_tx(relay_full_message) self.assertEqual( 3, len(gateway_bdn_performance_stats_service.interval_data. blockchain_node_to_bdn_stats)) node_1_stats = gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats[ self.node_1_endpoint] for endpoint, stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.items( ): if endpoint == self.node_1_endpoint: continue self.assertEqual(1, stats.new_tx_received_from_bdn) self.assertEqual(0, stats.new_tx_received_from_blockchain_node) self.assertEqual(1, node_1_stats.new_tx_received_from_blockchain_node) self.assertEqual(0, node_1_stats.new_tx_received_from_bdn) def test_bdn_stats_tx_ignore_new_compact_from_bdn_log_new_from_node(self): blockchain_node_txs = [ mock_eth_messages.get_dummy_transaction(7), ] blockchain_node_tx_msg = TransactionsEthProtocolMessage( None, blockchain_node_txs) bx_tx_message = self.node.message_converter.tx_to_bx_txs( blockchain_node_tx_msg, 1) for (msg, tx_hash, tx_bytes) in bx_tx_message: relay_compact_message = TxMessage(message_hash=tx_hash, network_num=1, short_id=1) self.relay_connection.msg_tx(relay_compact_message) self.tx_blockchain_connection_protocol.msg_tx(blockchain_node_tx_msg) self.assertEqual( 3, len(gateway_bdn_performance_stats_service.interval_data. blockchain_node_to_bdn_stats)) node_1_stats = gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats[ self.node_1_endpoint] for endpoint, stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.items( ): if endpoint == self.node_1_endpoint: continue self.assertEqual(1, stats.new_tx_received_from_bdn) self.assertEqual(1, node_1_stats.new_tx_received_from_blockchain_node) self.assertEqual(0, node_1_stats.new_tx_received_from_bdn) def test_bdn_stats_block_new_from_node(self): block_msg = NewBlockEthProtocolMessage( None, _block_with_timestamp( time.time() + 1 - self.node.opts.blockchain_ignore_block_interval_count * self.node.opts.blockchain_block_interval), 10) block_msg.serialize() self.block_blockchain_connection_protocol.msg_block(block_msg) self.assertEqual( 3, len(gateway_bdn_performance_stats_service.interval_data. blockchain_node_to_bdn_stats)) node_1_stats = gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats[ self.node_1_endpoint] for endpoint, stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.items( ): if endpoint == self.node_1_endpoint: continue self.assertEqual(1, stats.new_blocks_received_from_bdn) self.assertEqual(1, node_1_stats.new_blocks_received_from_blockchain_node) def test_bdn_stats_block_new_from_node_ignore_duplicate(self): block_msg = NewBlockEthProtocolMessage( None, _block_with_timestamp( time.time() + 1 - self.node.opts.blockchain_ignore_block_interval_count * self.node.opts.blockchain_block_interval), 10) block_msg.serialize() self.block_blockchain_connection_protocol.msg_block(block_msg) self.block_blockchain_connection_protocol.msg_block(block_msg) self.assertEqual( 3, len(gateway_bdn_performance_stats_service.interval_data. blockchain_node_to_bdn_stats)) node_1_stats = gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats[ self.node_1_endpoint] for endpoint, stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.items( ): if endpoint == self.node_1_endpoint: continue self.assertEqual(1, stats.new_blocks_received_from_bdn) self.assertEqual(1, node_1_stats.new_blocks_received_from_blockchain_node) def test_bdn_stats_block_new_from_bdn(self): block_msg = mock_eth_messages.new_block_eth_protocol_message(21, 1017) internal_new_block_msg = InternalEthBlockInfo.from_new_block_msg( block_msg) msg_bytes, block_info = self.node.message_converter.block_to_bx_block( internal_new_block_msg, self.node._tx_service, True, self.node.network.min_tx_age_seconds) msg_hash = Sha256Hash(crypto.double_sha256(msg_bytes)) broadcast_msg = BroadcastMessage(message_hash=msg_hash, network_num=1, is_encrypted=False, blob=msg_bytes) self.relay_connection.msg_broadcast(broadcast_msg) self.assertEqual( 3, len(gateway_bdn_performance_stats_service.interval_data. blockchain_node_to_bdn_stats)) for stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.values( ): self.assertEqual(1, stats.new_blocks_received_from_bdn) def test_bdn_stats_block_new_from_bdn_ignore_duplicate(self): block_msg = mock_eth_messages.new_block_eth_protocol_message(21, 1017) internal_new_block_msg = InternalEthBlockInfo.from_new_block_msg( block_msg) msg_bytes, block_info = self.node.message_converter.block_to_bx_block( internal_new_block_msg, self.node._tx_service, True, self.node.network.min_tx_age_seconds) msg_hash = Sha256Hash(crypto.double_sha256(msg_bytes)) broadcast_msg = BroadcastMessage(message_hash=msg_hash, network_num=1, is_encrypted=False, blob=msg_bytes) self.relay_connection.msg_broadcast(broadcast_msg) self.relay_connection.msg_broadcast(broadcast_msg) self.assertEqual( 3, len(gateway_bdn_performance_stats_service.interval_data. blockchain_node_to_bdn_stats)) for stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.values( ): self.assertEqual(1, stats.new_blocks_received_from_bdn) def test_bdn_stats_block_new_from_bdn_ignore_from_node(self): block_msg = NewBlockEthProtocolMessage( None, _block_with_timestamp(time.time() + 1 - ( self.node.opts.blockchain_ignore_block_interval_count * self.node.opts.blockchain_block_interval)), 10) internal_new_block_msg = InternalEthBlockInfo.from_new_block_msg( block_msg) msg_bytes, block_info = self.node.message_converter.block_to_bx_block( internal_new_block_msg, self.node._tx_service, True, self.node.network.min_tx_age_seconds) msg_hash = Sha256Hash(crypto.double_sha256(msg_bytes)) broadcast_msg = BroadcastMessage(message_hash=msg_hash, network_num=1, is_encrypted=False, blob=msg_bytes) self.relay_connection.msg_broadcast(broadcast_msg) block_msg.serialize() self.block_blockchain_connection_protocol.msg_block(block_msg) self.assertEqual( 3, len(gateway_bdn_performance_stats_service.interval_data. blockchain_node_to_bdn_stats)) for stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.values( ): self.assertEqual(1, stats.new_blocks_received_from_bdn) self.assertEqual(0, stats.new_blocks_received_from_blockchain_node) def test_bdn_stats_block_new_from_node_ignore_from_bdn(self): block_msg = NewBlockEthProtocolMessage( None, _block_with_timestamp( time.time() + 1 - self.node.opts.blockchain_ignore_block_interval_count * self.node.opts.blockchain_block_interval), 10) block_msg.serialize() self.block_blockchain_connection_protocol.msg_block(block_msg) internal_new_block_msg = InternalEthBlockInfo.from_new_block_msg( block_msg) msg_bytes, block_info = self.node.message_converter.block_to_bx_block( internal_new_block_msg, self.node._tx_service, True, self.node.network.min_tx_age_seconds) msg_hash = Sha256Hash(crypto.double_sha256(msg_bytes)) broadcast_msg = BroadcastMessage(message_hash=msg_hash, network_num=1, is_encrypted=False, blob=msg_bytes) self.relay_connection.msg_broadcast(broadcast_msg) self.assertEqual( 3, len(gateway_bdn_performance_stats_service.interval_data. blockchain_node_to_bdn_stats)) node_1_stats = gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats[ self.node_1_endpoint] for endpoint, stats in gateway_bdn_performance_stats_service.interval_data.blockchain_node_to_bdn_stats.items( ): if endpoint == self.node_1_endpoint: continue self.assertEqual(1, stats.new_blocks_received_from_bdn) self.assertEqual(1, node_1_stats.new_blocks_received_from_blockchain_node) self.assertEqual(0, node_1_stats.new_blocks_received_from_bdn)