Esempio n. 1
0
 async def setUp(self) -> None:
     self.gateway_node = MockGatewayNode(self.get_gateway_opts())
     self.gateway_node.requester = ThreadedRequestService(
         "mock_thread_service", self.gateway_node.alarm_queue,
         constants.THREADED_HTTP_POOL_SLEEP_INTERVAL_S)
     self.gateway_node.requester.start()
     self.gateway_node.account_id = ACCOUNT_ID
     self.node_endpoint_1 = IpEndpoint("127.0.0.1", 7000)
     self.blockchain_connection_1 = EthNodeConnection(
         MockSocketConnection(1,
                              node=self.gateway_node,
                              ip_address="127.0.0.1",
                              port=7000),
         cast(EthGatewayNode, self.gateway_node))
     self.blockchain_connection_1.on_connection_established()
Esempio n. 2
0
 def build_blockchain_connection(
     self, socket_connection: AbstractSocketConnectionProtocol
 ) -> AbstractGatewayBlockchainConnection:
     if self._is_in_local_discovery():
         return EthNodeDiscoveryConnection(socket_connection, self)
     else:
         return EthNodeConnection(socket_connection, self)
Esempio n. 3
0
    async def test_bdn_performance_multi_node(self):
        self.gateway_node.connection_pool.add(20,
                                              self.node_endpoint_1.ip_address,
                                              self.node_endpoint_1.port,
                                              self.blockchain_connection_1)

        blockchain_connection_2 = EthNodeConnection(
            MockSocketConnection(1,
                                 node=self.gateway_node,
                                 ip_address="127.0.0.1",
                                 port=333), self.gateway_node)
        blockchain_connection_2.on_connection_established()
        self.gateway_node.mock_add_blockchain_peer(blockchain_connection_2)
        node_endpoint_2 = IpEndpoint("127.0.0.1", 333)
        self.gateway_node.connection_pool.add(21, node_endpoint_2.ip_address,
                                              node_endpoint_2.port,
                                              blockchain_connection_2)

        gateway_bdn_performance_stats_service.set_node(self.gateway_node)
        gateway_bdn_performance_stats_service.log_block_from_bdn()
        gateway_bdn_performance_stats_service.log_block_from_bdn()
        gateway_bdn_performance_stats_service.log_block_from_blockchain_node(
            self.node_endpoint_1)
        gateway_bdn_performance_stats_service.log_tx_from_bdn()
        gateway_bdn_performance_stats_service.log_tx_from_blockchain_node(
            self.node_endpoint_1)
        gateway_bdn_performance_stats_service.log_tx_from_blockchain_node(
            self.node_endpoint_1)
        gateway_bdn_performance_stats_service.close_interval_data()

        result = await self.request(
            BxJsonRpcRequest("6", RpcRequestType.BDN_PERFORMANCE, None))
        self.assertEqual("6", result.id)
        self.assertIsNone(result.error)
        node_stats = result.result[str(self.node_endpoint_1)]
        self.assertEqual("66.67%", node_stats["blocks_from_bdn_percentage"])
        self.assertEqual("33.33%",
                         node_stats["transactions_from_bdn_percentage"])
        self.assertEqual(3, node_stats["total_blocks_seen"])

        node_stats_2 = result.result[str(node_endpoint_2)]
        self.assertEqual("100.00%", node_stats_2["blocks_from_bdn_percentage"])
        self.assertEqual("100.00%",
                         node_stats_2["transactions_from_bdn_percentage"])
        self.assertEqual(3, node_stats_2["total_blocks_seen"])
Esempio n. 4
0
class AbstractGatewayRpcIntegrationTest(AbstractTestCase):
    def __init__(self, *args, **kwargs):
        # hack to avoid unit test discovery of this class
        super().__init__(*args, **kwargs)
        if self.__class__ != AbstractGatewayRpcIntegrationTest:
            # pylint: disable=no-value-for-parameter
            self.run = unittest.TestCase.run.__get__(self, self.__class__)
        else:
            self.run = lambda self, *args, **kwargs: None
        self._account_model = None

    # pyre-ignore async setup problems
    async def setUp(self) -> None:
        self.gateway_node = MockGatewayNode(self.get_gateway_opts())
        self.gateway_node.requester = ThreadedRequestService(
            "mock_thread_service", self.gateway_node.alarm_queue,
            constants.THREADED_HTTP_POOL_SLEEP_INTERVAL_S)
        self.gateway_node.requester.start()
        self.gateway_node.account_id = ACCOUNT_ID
        self.node_endpoint_1 = IpEndpoint("127.0.0.1", 7000)
        self.blockchain_connection_1 = EthNodeConnection(
            MockSocketConnection(1,
                                 node=self.gateway_node,
                                 ip_address="127.0.0.1",
                                 port=7000),
            cast(EthGatewayNode, self.gateway_node))
        self.blockchain_connection_1.on_connection_established()

    @abstractmethod
    def get_gateway_opts(self) -> GatewayOpts:
        feed_service_model = FeedServiceModelBase(allow_filtering=True,
                                                  available_fields=["all"])
        base_feed_service_model = BdnFeedServiceModelConfigBase(
            expire_date="2999-01-01", feed=feed_service_model)
        self._account_model = BdnAccountModelBase(
            account_id="",
            logical_account_name="",
            certificate="",
            expire_date=utils_constants.DEFAULT_EXPIRATION_DATE.isoformat(),
            cloud_api=BdnServiceModelConfigBase(
                msg_quota=None,
                permit=BdnServiceModelBase(service_type=BdnServiceType.PERMIT),
                expire_date=utils_constants.DEFAULT_EXPIRATION_DATE.isoformat(
                )),
            new_transaction_streaming=base_feed_service_model,
            new_pending_transaction_streaming=base_feed_service_model,
            on_block_feed=base_feed_service_model,
            new_block_streaming=base_feed_service_model,
            transaction_state_feed=base_feed_service_model,
            blockchain_protocol="Ethereum",
            blockchain_network="Mainnet",
        )

    @abstractmethod
    async def request(self, req: BxJsonRpcRequest) -> JsonRpcResponse:
        pass

    @async_test
    async def test_blxr_tx(self):
        result = await self.request(
            BxJsonRpcRequest(
                "1", RpcRequestType.BLXR_TX, {
                    rpc_constants.TRANSACTION_PARAMS_KEY: RAW_TRANSACTION_HEX,
                    rpc_constants.STATUS_TRACK_PARAMS_KEY: "True"
                }))
        self.assertEqual("1", result.id)
        self.assertIsNone(result.error)
        self.assertEqual(TRANSACTION_HASH, result.result["tx_hash"])

        self.assertEqual(1, len(self.gateway_node.broadcast_messages))
        self.assertEqual(Sha256Hash(convert.hex_to_bytes(TRANSACTION_HASH)),
                         self.gateway_node.broadcast_messages[0][0].tx_hash())

    @async_test
    async def test_blxr_tx_ethereum_berlin(self):
        self.gateway_node.message_converter = EthNormalMessageConverter()
        self.gateway_node.network_num = 5

        # legacy
        result = await self.request(
            BxJsonRpcRequest(
                "1", RpcRequestType.BLXR_TX, {
                    rpc_constants.TRANSACTION_PARAMS_KEY:
                    convert.bytes_to_hex(eth_fixtures.LEGACY_TRANSACTION),
                    rpc_constants.STATUS_TRACK_PARAMS_KEY:
                    "True"
                }))
        self.assertEqual("1", result.id)
        self.assertIsNone(result.error)
        self.assertEqual(eth_fixtures.LEGACY_TRANSACTION_HASH,
                         result.result["tx_hash"])

        self.assertEqual(1, len(self.gateway_node.broadcast_messages))
        self.assertEqual(
            Sha256Hash(
                convert.hex_to_bytes(eth_fixtures.LEGACY_TRANSACTION_HASH)),
            self.gateway_node.broadcast_messages[0][0].tx_hash())

        # access list
        result = await self.request(
            BxJsonRpcRequest(
                "1", RpcRequestType.BLXR_TX, {
                    rpc_constants.TRANSACTION_PARAMS_KEY:
                    convert.bytes_to_hex(eth_fixtures.ACL_TRANSACTION),
                    rpc_constants.STATUS_TRACK_PARAMS_KEY:
                    "True"
                }))
        self.assertEqual("1", result.id)
        self.assertIsNone(result.error)
        self.assertEqual(eth_fixtures.ACL_TRANSACTION_HASH,
                         result.result["tx_hash"])

        self.assertEqual(2, len(self.gateway_node.broadcast_messages))
        self.assertEqual(
            Sha256Hash(convert.hex_to_bytes(
                eth_fixtures.ACL_TRANSACTION_HASH)),
            self.gateway_node.broadcast_messages[1][0].tx_hash())

    @async_test
    async def test_blxr_tx_expired(self):
        self.gateway_node.account_model.is_account_valid = MagicMock(
            return_value=False)
        result = await self.request(
            BxJsonRpcRequest(
                "2", RpcRequestType.BLXR_TX, {
                    rpc_constants.TRANSACTION_PARAMS_KEY: RAW_TRANSACTION_HEX,
                }))
        self.assertEqual("2", result.id)
        self.assertEqual("Invalid Account ID", result.error.message)
        self.assertIsNone(result.result)
        self.assertIsNotNone(result.error)

    @async_test
    async def test_blxr_tx_quota_exceeded(self):
        self.gateway_node.quota_level = 100
        result = await self.request(
            BxJsonRpcRequest(
                "3", RpcRequestType.BLXR_TX, {
                    rpc_constants.TRANSACTION_PARAMS_KEY: RAW_TRANSACTION_HEX,
                }))
        self.assertEqual("3", result.id)
        self.assertEqual("Insufficient quota", result.error.message)
        self.assertIsNone(result.result)
        self.assertIsNotNone(result.error)

    @async_test
    async def test_blxr_tx_from_json(self):
        tx_json = {
            'from':
            '0xc165599b5e418bb9d8a19090696ea2403b2927ed',
            'gas':
            "0x5208",
            'gasPrice':
            "0xc1b759d70",
            'hash':
            '0xd569674ad9fcaaedcb6867b7896067b445d4a838316be4292c474df17bf4bd50',
            'input':
            '0x',
            'nonce':
            "0x14",
            'to':
            '0xdb5f0c1f4198bc6ffa98b35f7188f82740b8caf7',
            'value':
            "0x3e871b540c000",
            'v':
            '0x26',
            'r':
            '0x484bc950fb2d595500baa604774cb8d156a677198e087801936f38ca0b27049',
            's':
            '0x7ca82ef7b6938c2e96966dd940b186c9cdc0c7f42b2843adbc0751bb6e67a2d4'
        }

        result = await self.request(
            BxJsonRpcRequest(
                "1", RpcRequestType.BLXR_TX, {
                    rpc_constants.TRANSACTION_JSON_PARAMS_KEY: tx_json,
                }))

        self.assertEqual("1", result.id)
        self.assertIsNone(result.error)
        self.assertEqual(
            "ad6f9332384194f80d8e49af8f093ad019b3f6b7173eb2956a46c9a0d8c4d03c",
            result.result["tx_hash"])

        self.assertEqual(1, len(self.gateway_node.broadcast_messages))
        self.assertEqual(
            Sha256Hash(
                convert.hex_to_bytes(
                    "ad6f9332384194f80d8e49af8f093ad019b3f6b7173eb2956a46c9a0d8c4d03c"
                )), self.gateway_node.broadcast_messages[0][0].tx_hash())

    @async_test
    async def test_blxr_eth_call(self):
        self.gateway_node.eth_ws_proxy_publisher = MockEthWsProxyPublisher(
            None, None, None, None)
        self.gateway_node.eth_ws_proxy_publisher.call_rpc = AsyncMock(
            return_value=JsonRpcResponse(request_id=1))
        result = await self.request(
            BxJsonRpcRequest(
                "1", RpcRequestType.BLXR_ETH_CALL, {
                    rpc_constants.TRANSACTION_JSON_PARAMS_KEY:
                    TRANSACTION_JSON,
                    rpc_constants.TAG_PARAMS_KEY: "latest"
                }))
        self.gateway_node.eth_ws_proxy_publisher.call_rpc.mock.assert_called_with(
            "eth_call", [TRANSACTION_JSON, "latest"])
        self.assertIsNone(result.error)

    @async_test
    async def test_gateway_status(self):
        result_summary = await self.request(
            BxJsonRpcRequest("2", RpcRequestType.GATEWAY_STATUS, None))
        self.assertEqual("2", result_summary.id)
        self.assertIsNone(result_summary.error)
        self.assertEqual(constants.LOCALHOST,
                         result_summary.result["ip_address"])
        self.assertEqual("NA", result_summary.result["continent"])
        self.assertEqual("United States", result_summary.result["country"])

        result_detailed = await self.request(
            BxJsonRpcRequest(
                "2.5", RpcRequestType.GATEWAY_STATUS, {
                    rpc_constants.DETAILS_LEVEL_PARAMS_KEY:
                    GatewayStatusDetailsLevel.DETAILED.name
                }))
        self.assertEqual("2.5", result_detailed.id)
        self.assertIsNone(result_detailed.error)
        self.assertEqual(constants.LOCALHOST,
                         result_detailed.result["summary"]["ip_address"])
        self.assertEqual("NA", result_detailed.result["summary"]["continent"])
        self.assertEqual("United States",
                         result_detailed.result["summary"]["country"])

    @async_test
    async def test_stop(self):
        result = await self.request(
            BxJsonRpcRequest("3", RpcRequestType.STOP, None))
        self.assertEqual("3", result.id)
        self.assertIsNone(result.error)
        self.assertEqual({}, result.result)
        self.gateway_node.should_force_exit = True
        self.gateway_node.should_restart_on_high_memory = False

    @async_test
    async def test_memory(self):
        result = await self.request(
            BxJsonRpcRequest("4", RpcRequestType.MEMORY, None))
        self.assertEqual("4", result.id)
        self.assertIsNone(result.error)
        self.assertEqual(
            0, result.result[gateway_memory_rpc_request.TOTAL_CACHED_TX])
        self.assertEqual(
            "0 bytes",
            result.result[gateway_memory_rpc_request.TOTAL_CACHED_TX_SIZE])

    @async_test
    async def test_peers(self):
        result = await self.request(
            BxJsonRpcRequest("5", RpcRequestType.PEERS, None))
        self.assertEqual("5", result.id)
        self.assertIsNone(result.error)
        self.assertEqual([], result.result)

    @async_test
    async def test_bdn_performance_single_node(self):
        self.gateway_node.connection_pool.add(20,
                                              self.node_endpoint_1.ip_address,
                                              self.node_endpoint_1.port,
                                              self.blockchain_connection_1)
        gateway_bdn_performance_stats_service.set_node(self.gateway_node)
        gateway_bdn_performance_stats_service.log_block_from_bdn()
        gateway_bdn_performance_stats_service.log_block_from_bdn()
        gateway_bdn_performance_stats_service.log_block_from_blockchain_node(
            self.node_endpoint_1)
        gateway_bdn_performance_stats_service.log_tx_from_bdn()
        gateway_bdn_performance_stats_service.log_tx_from_blockchain_node(
            self.node_endpoint_1)
        gateway_bdn_performance_stats_service.log_tx_from_blockchain_node(
            self.node_endpoint_1)
        gateway_bdn_performance_stats_service.close_interval_data()

        result = await self.request(
            BxJsonRpcRequest("6", RpcRequestType.BDN_PERFORMANCE, None))
        self.assertEqual("6", result.id)
        self.assertIsNone(result.error)
        node_stats = result.result[str(self.node_endpoint_1)]
        self.assertEqual("66.67%", node_stats["blocks_from_bdn_percentage"])
        self.assertEqual("33.33%",
                         node_stats["transactions_from_bdn_percentage"])
        self.assertEqual(3, node_stats["total_blocks_seen"])

    @async_test
    async def test_bdn_performance_multi_node(self):
        self.gateway_node.connection_pool.add(20,
                                              self.node_endpoint_1.ip_address,
                                              self.node_endpoint_1.port,
                                              self.blockchain_connection_1)

        blockchain_connection_2 = EthNodeConnection(
            MockSocketConnection(1,
                                 node=self.gateway_node,
                                 ip_address="127.0.0.1",
                                 port=333), self.gateway_node)
        blockchain_connection_2.on_connection_established()
        self.gateway_node.mock_add_blockchain_peer(blockchain_connection_2)
        node_endpoint_2 = IpEndpoint("127.0.0.1", 333)
        self.gateway_node.connection_pool.add(21, node_endpoint_2.ip_address,
                                              node_endpoint_2.port,
                                              blockchain_connection_2)

        gateway_bdn_performance_stats_service.set_node(self.gateway_node)
        gateway_bdn_performance_stats_service.log_block_from_bdn()
        gateway_bdn_performance_stats_service.log_block_from_bdn()
        gateway_bdn_performance_stats_service.log_block_from_blockchain_node(
            self.node_endpoint_1)
        gateway_bdn_performance_stats_service.log_tx_from_bdn()
        gateway_bdn_performance_stats_service.log_tx_from_blockchain_node(
            self.node_endpoint_1)
        gateway_bdn_performance_stats_service.log_tx_from_blockchain_node(
            self.node_endpoint_1)
        gateway_bdn_performance_stats_service.close_interval_data()

        result = await self.request(
            BxJsonRpcRequest("6", RpcRequestType.BDN_PERFORMANCE, None))
        self.assertEqual("6", result.id)
        self.assertIsNone(result.error)
        node_stats = result.result[str(self.node_endpoint_1)]
        self.assertEqual("66.67%", node_stats["blocks_from_bdn_percentage"])
        self.assertEqual("33.33%",
                         node_stats["transactions_from_bdn_percentage"])
        self.assertEqual(3, node_stats["total_blocks_seen"])

        node_stats_2 = result.result[str(node_endpoint_2)]
        self.assertEqual("100.00%", node_stats_2["blocks_from_bdn_percentage"])
        self.assertEqual("100.00%",
                         node_stats_2["transactions_from_bdn_percentage"])
        self.assertEqual(3, node_stats_2["total_blocks_seen"])

    @async_test
    async def test_transaction_status(self):
        time.time = MagicMock(return_value=time.time())
        expected_assignment_time = datetime.datetime.fromtimestamp(
            time.time()).isoformat()

        short_id = 123
        transaction_hash = helpers.generate_object_hash()
        transaction_contents = helpers.generate_bytearray(250)

        tx_service = self.gateway_node.get_tx_service()
        transaction_key = tx_service.get_transaction_key(transaction_hash)
        tx_service.set_transaction_contents_by_key(transaction_key,
                                                   transaction_contents)
        tx_service.assign_short_id_by_key(transaction_key, short_id)

        result = await self.request(
            BxJsonRpcRequest("7", RpcRequestType.TX_STATUS, {
                "transaction_hash":
                convert.bytes_to_hex(transaction_hash.binary)
            }))
        self.assertEqual("7", result.id)
        self.assertIsNone(result.error)
        self.assertEqual(
            {
                "status": "assigned short ID",
                "short_ids": [123],
                "assignment_time": expected_assignment_time
            }, result.result)

    @async_test
    async def test_add_blockchain_peer(self):
        self.gateway_node.enqueue_connection = MagicMock()
        result = await self.request(
            BxJsonRpcRequest(
                "8", RpcRequestType.ADD_BLOCKCHAIN_PEER, {
                    "peer":
                    "enode://d76d7d11a822fab02836f8b0ea462205916253eb630935d15191fb6f9d218cd94a768fc5b3d5516b9ed5010a4765f95aea7124a39d0ab8aaf6fa3d57e21ef396@127.0.0.1:30302"
                }))
        self.gateway_node.enqueue_connection.assert_called_once_with(
            "127.0.0.1", 30302, ConnectionType.BLOCKCHAIN_NODE)
        self.assertIn(BlockchainPeerInfo("127.0.0.1", 30302),
                      self.gateway_node.blockchain_peers)
        self.assertEqual("8", result.id)
        self.assertIsNone(result.error)
        self.assertEqual({"new_peer": "127.0.0.1:30302"}, result.result)

    @async_test
    async def test_remove_blockchain_peer(self):
        conn = MockConnection(
            MockSocketConnection(9,
                                 self.gateway_node,
                                 ip_address="127.0.0.1",
                                 port=30302), self.gateway_node)
        conn.mark_for_close = MagicMock()
        self.gateway_node.connection_pool.add(9, "127.0.0.1", 30302, conn)
        self.gateway_node.blockchain_peers.add(
            BlockchainPeerInfo(
                "127.0.0.1", 30302,
                "d76d7d11a822fab02836f8b0ea462205916253eb630935d15191fb6f9d218cd94a768fc5b3d5516b9ed5010a4765f95aea7124a39d0ab8aaf6fa3d57e21ef396"
            ))
        result = await self.request(
            BxJsonRpcRequest(
                "9", RpcRequestType.REMOVE_BLOCKCHAIN_PEER, {
                    "peer":
                    "enode://d76d7d11a822fab02836f8b0ea462205916253eb630935d15191fb6f9d218cd94a768fc5b3d5516b9ed5010a4765f95aea7124a39d0ab8aaf6fa3d57e21ef396@127.0.0.1:30302"
                }))
        self.assertNotIn(BlockchainPeerInfo("127.0.0.1", 30302),
                         self.gateway_node.blockchain_peers)
        conn.mark_for_close.assert_called_once_with(False)
        self.assertEqual("9", result.id)
        self.assertIsNone(result.error)
        self.assertEqual({"removed_peer": "127.0.0.1:30302"}, result.result)

    @async_test
    async def test_remove_blockchain_peer_not_in_pool(self):
        self.gateway_node.alarm_queue.register_alarm = MagicMock()
        self.gateway_node.blockchain_peers.add(
            BlockchainPeerInfo(
                "127.0.0.1", 30302,
                "d76d7d11a822fab02836f8b0ea462205916253eb630935d15191fb6f9d218cd94a768fc5b3d5516b9ed5010a4765f95aea7124a39d0ab8aaf6fa3d57e21ef396"
            ))
        result = await self.request(
            BxJsonRpcRequest(
                "9", RpcRequestType.REMOVE_BLOCKCHAIN_PEER, {
                    "peer":
                    "enode://d76d7d11a822fab02836f8b0ea462205916253eb630935d15191fb6f9d218cd94a768fc5b3d5516b9ed5010a4765f95aea7124a39d0ab8aaf6fa3d57e21ef396@127.0.0.1:30302"
                }))
        self.assertNotIn(BlockchainPeerInfo("127.0.0.1", 30302),
                         self.gateway_node.blockchain_peers)
        self.gateway_node.alarm_queue.register_alarm.assert_called()
        self.assertEqual("9", result.id)
        self.assertIsNone(result.error)
        self.assertEqual({"removed_peer": "127.0.0.1:30302"}, result.result)
Esempio n. 5
0
    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"
Esempio n. 6
0
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)