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()
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)