示例#1
0
    def test_msg_tx(self):
        self.node.feed_manager.publish_to_feed = MagicMock()
        self.node.opts.ws = True
        self.node.opts.transaction_validation = False

        transaction = mock_eth_messages.get_dummy_transaction(1)
        transaction_hash = transaction.hash()
        transaction_contents = transaction.contents()
        messages = TransactionsEthProtocolMessage(None, [transaction])

        self.sut.msg_tx(messages)

        # published to both feeds
        self.node.feed_manager.publish_to_feed.assert_has_calls(
            [
                call(
                    FeedKey(EthNewTransactionFeed.NAME),
                    EthRawTransaction(
                        transaction_hash, transaction_contents, FeedSource.BLOCKCHAIN_SOCKET, local_region=True
                    )
                ),
                call(
                    FeedKey(EthPendingTransactionFeed.NAME),
                    EthRawTransaction(
                        transaction_hash, transaction_contents, FeedSource.BLOCKCHAIN_SOCKET, local_region=True
                    )
                ),
            ]
        )

        # broadcast transactions
        self.assertEqual(1, len(self.broadcast_messages))
        self.assertEqual(1, len(self.broadcast_to_node_messages))
示例#2
0
    async def test_eth_pending_tx_feed_subscribe_with_duplicates(self):
        self.gateway_node.feed_manager.register_feed(
            EthPendingTransactionFeed(self.gateway_node.alarm_queue))

        eth_tx_message = generate_new_eth_transaction()
        eth_transaction = EthRawTransaction(eth_tx_message.tx_hash(),
                                            eth_tx_message.tx_val(),
                                            FeedSource.BDN_SOCKET,
                                            local_region=True)
        expected_tx_hash = f"0x{str(eth_transaction.tx_hash)}"

        async with WsProvider(self.ws_uri) as ws:
            subscription_id = await ws.subscribe("pendingTxs",
                                                 {"duplicates": True})

            self.gateway_node.feed_manager.publish_to_feed(
                FeedKey("pendingTxs"), eth_transaction)

            subscription_message = await ws.get_next_subscription_notification_by_id(
                subscription_id)
            self.assertEqual(subscription_id,
                             subscription_message.subscription_id)
            self.assertEqual(expected_tx_hash,
                             subscription_message.notification["txHash"])

            # will publish twice
            self.gateway_node.feed_manager.publish_to_feed(
                FeedKey("pendingTxs"), eth_transaction)
            subscription_message = await ws.get_next_subscription_notification_by_id(
                subscription_id)
            self.assertEqual(subscription_id,
                             subscription_message.subscription_id)
            self.assertEqual(expected_tx_hash,
                             subscription_message.notification["txHash"])
示例#3
0
    async def test_eth_pending_transactions_feed_subscribe_filters4(self):
        self.gateway_node.feed_manager.feeds.clear()
        self.gateway_node.feed_manager.register_feed(
            EthPendingTransactionFeed(self.gateway_node.alarm_queue)
        )
        to = "0x"
        eth_tx_message = generate_new_eth_with_to_transaction(to[2:])
        eth_transaction = EthRawTransaction(
            eth_tx_message.tx_hash(),
            eth_tx_message.tx_val(),
            FeedSource.BLOCKCHAIN_SOCKET,
            local_region=True
        )
        expected_tx_hash = f"0x{str(eth_transaction.tx_hash)}"
        logger.error(expected_tx_hash)
        to2 = "0x0000000000000000000000000000000000000000"
        eth_tx_message2 = generate_new_eth_with_to_transaction(to2[2:])
        eth_transaction2 = EthRawTransaction(
            eth_tx_message2.tx_hash(),
            eth_tx_message2.tx_val(),
            FeedSource.BLOCKCHAIN_SOCKET,
            local_region=True
        )
        expected_tx_hash2 = f"0x{str(eth_transaction2.tx_hash)}"
        logger.error(expected_tx_hash2)
        async with WsProvider(self.ws_uri) as ws:
            subscription_id = await ws.subscribe(
                "pendingTxs",
                options={
                    "filters": f"to in [0x0000000000000000000000000000000000000000]"
                },
            )

            self.gateway_node.feed_manager.publish_to_feed(
                FeedKey("pendingTxs"), eth_transaction
            )
            self.gateway_node.feed_manager.publish_to_feed(
                FeedKey("pendingTxs"), eth_transaction2
            )

            subscription_message = await ws.get_next_subscription_notification_by_id(
                subscription_id
            )
            self.assertEqual(subscription_id, subscription_message.subscription_id)
            self.assertEqual(
                expected_tx_hash, subscription_message.notification["txHash"]
            )
            subscription_message = await ws.get_next_subscription_notification_by_id(
                subscription_id
            )
            self.assertEqual(subscription_id, subscription_message.subscription_id)
            self.assertEqual(
                expected_tx_hash2, subscription_message.notification["txHash"]
            )
示例#4
0
    async def test_eth_transaction_receipts_feed_default_subscribe(self):
        self.gateway_node.opts.eth_ws_uri = f"ws://{constants.LOCALHOST}:8005"
        self.gateway_node.feed_manager.register_feed(
            EthTransactionReceiptsFeed(self.gateway_node, 0))
        self.gateway_node.eth_ws_proxy_publisher = MockEthWsProxyPublisher(
            "", None, None, self.gateway_node)
        receipt_result = {
            "blockHash":
            "0xe6f67c6948158c45dct10b169ad6bf3a96c6402489733a03051feaf7d09e7b54",
            "blockNumber": "0xaf25e5",
            "cumulativeGasUsed": "0xbdb9ae",
            "from": "0x82170dd1cec50107963bf1ba1e80955ea302c5ce",
            "gasUsed": "0x5208",
            "logs": [],
            "logsBloom":
            "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
            "status": "0x1",
            "to": "0xa09f63d9a0b0fbe89e41e51282ad660e7c876165",
            "transactionHash":
            "0xbcdc5b22bf463f9b8766dd61cc133caf13472b6ae8474061134d9dc2983625f6",
            "transactionIndex": "0x90"
        }
        self.gateway_node.eth_ws_proxy_publisher.call_rpc = AsyncMock(
            return_value=JsonRpcResponse(request_id=1, result=receipt_result))
        block = mock_eth_messages.get_dummy_block(5)
        internal_block_info = InternalEthBlockInfo.from_new_block_msg(
            NewBlockEthProtocolMessage(None, block, 1))
        eth_raw_block_1 = EthRawBlock(1, internal_block_info.block_hash(),
                                      FeedSource.BLOCKCHAIN_RPC,
                                      get_block_message_lazy(None))
        eth_raw_block_2 = EthRawBlock(
            1, internal_block_info.block_hash(), FeedSource.BLOCKCHAIN_SOCKET,
            get_block_message_lazy(internal_block_info))

        async with WsProvider(self.ws_uri) as ws:
            subscription_id = await ws.subscribe(
                rpc_constants.ETH_TRANSACTION_RECEIPTS_FEED_NAME)

            self.gateway_node.feed_manager.publish_to_feed(
                FeedKey(rpc_constants.ETH_TRANSACTION_RECEIPTS_FEED_NAME),
                eth_raw_block_1)
            self.gateway_node.feed_manager.publish_to_feed(
                FeedKey(rpc_constants.ETH_TRANSACTION_RECEIPTS_FEED_NAME),
                eth_raw_block_2)

            for i in range(len(block.transactions)):
                subscription_message = await ws.get_next_subscription_notification_by_id(
                    subscription_id)
                self.assertEqual(subscription_id,
                                 subscription_message.subscription_id)
                self.assertEqual(subscription_message.notification,
                                 {"receipt": receipt_result})
示例#5
0
    async def test_eth_new_transactions_feed_subscribe_filters(self):
        self.gateway_node.feed_manager.feeds.clear()
        self.gateway_node.feed_manager.register_feed(EthNewTransactionFeed())
        to = "0x1111111111111111111111111111111111111111"
        eth_tx_message = generate_new_eth_with_to_transaction(to[2:])
        eth_transaction = EthRawTransaction(eth_tx_message.tx_hash(),
                                            eth_tx_message.tx_val(),
                                            FeedSource.BLOCKCHAIN_SOCKET,
                                            local_region=True)
        expected_tx_hash = f"0x{str(eth_transaction.tx_hash)}"
        logger.error(expected_tx_hash)
        async with WsProvider(self.ws_uri) as ws:
            subscription_id = await ws.subscribe(
                "newTxs", options={"filters": f"to = {to} or to = aaaa"})

            self.gateway_node.feed_manager.publish_to_feed(
                FeedKey("newTxs"), eth_transaction)

            subscription_message = await ws.get_next_subscription_notification_by_id(
                subscription_id)
            self.assertEqual(subscription_id,
                             subscription_message.subscription_id)
            self.assertEqual(expected_tx_hash,
                             subscription_message.notification["txHash"])

            expected_tx_contents = get_expected_eth_tx_contents(eth_tx_message)
            self.assertEqual(expected_tx_contents,
                             subscription_message.notification["txContents"])
示例#6
0
    async def test_onblock_feed_default_subscribe(self):
        self.gateway_node.opts.eth_ws_uri = f"ws://{constants.LOCALHOST}:8005"
        block_height = 100
        name = "abc123"

        self.gateway_node.feed_manager.register_feed(
            EthOnBlockFeed(self.gateway_node))
        self.gateway_node.eth_ws_proxy_publisher = MockEthWsProxyPublisher(
            "", None, None, self.gateway_node)
        self.gateway_node.eth_ws_proxy_publisher.call_rpc = AsyncMock(
            return_value=JsonRpcResponse(request_id=1))

        async with WsProvider(self.ws_uri) as ws:
            subscription_id = await ws.subscribe(
                rpc_constants.ETH_ON_BLOCK_FEED_NAME,
                {"call_params": [{
                    "data": "0x",
                    "name": name
                }]},
            )

            self.gateway_node.feed_manager.publish_to_feed(
                FeedKey(rpc_constants.ETH_ON_BLOCK_FEED_NAME),
                EventNotification(block_height=block_height),
            )

            subscription_message = await ws.get_next_subscription_notification_by_id(
                subscription_id)
            self.assertEqual(subscription_id,
                             subscription_message.subscription_id)
            print(subscription_message)
            self.assertEqual(block_height,
                             subscription_message.notification["blockHeight"])

            self.assertEqual(name, subscription_message.notification["name"])
示例#7
0
    async def test_eth_new_tx_feed_subscribe_include_from_blockchain(self):
        self.gateway_node.feed_manager.feeds.clear()
        self.gateway_node.feed_manager.register_feed(EthNewTransactionFeed())

        eth_tx_message = generate_new_eth_transaction()
        eth_transaction = EthRawTransaction(eth_tx_message.tx_hash(),
                                            eth_tx_message.tx_val(),
                                            FeedSource.BLOCKCHAIN_SOCKET,
                                            local_region=True)
        expected_tx_hash = f"0x{str(eth_transaction.tx_hash)}"

        async with WsProvider(self.ws_uri) as ws:
            subscription_id = await ws.subscribe(
                "newTxs", {"include_from_blockchain": True})

            self.gateway_node.feed_manager.publish_to_feed(
                FeedKey("newTxs"), eth_transaction)

            subscription_message = await ws.get_next_subscription_notification_by_id(
                subscription_id)
            self.assertEqual(subscription_id,
                             subscription_message.subscription_id)
            self.assertEqual(expected_tx_hash,
                             subscription_message.notification["txHash"])

            expected_tx_contents = get_expected_eth_tx_contents(eth_tx_message)
            self.assertEqual(expected_tx_contents,
                             subscription_message.notification["txContents"])
            self.assertTrue(subscription_message.notification["localRegion"])
    def msg_confirmed_tx(self, msg: ConfirmedTxMessage) -> None:
        tx_hash = msg.tx_hash()
        transaction_key = self.node.get_tx_service().get_transaction_key(
            tx_hash)
        tx_contents = msg.tx_val()

        # shouldn't ever happen, but just in case
        if tx_contents == ConfirmedTxMessage.EMPTY_TX_VAL:
            tx_contents = cast(
                Optional[memoryview],
                self.node.get_tx_service().get_transaction_by_key(
                    transaction_key))
            if tx_contents is None:
                transaction_feed_stats_service.log_pending_transaction_missing_contents(
                )
                return

        self.node.feed_manager.publish_to_feed(
            FeedKey(EthPendingTransactionFeed.NAME),
            EthRawTransaction(tx_hash,
                              tx_contents,
                              FeedSource.BDN_SOCKET,
                              local_region=True))

        transaction_feed_stats_service.log_pending_transaction_from_internal(
            tx_hash)
示例#9
0
 def _publish_block_to_on_block_feed(
     self,
     raw_block: EthRawBlock,
 ) -> None:
     if raw_block.source in EthOnBlockFeed.VALID_SOURCES:
         self.feed_manager.publish_to_feed(
             FeedKey(EthOnBlockFeed.NAME),
             EventNotification(raw_block.block_number))
 def publish_new_transaction(self, tx_hash: Sha256Hash,
                             tx_contents: memoryview,
                             local_region: bool) -> None:
     self.node.feed_manager.publish_to_feed(
         FeedKey(NewTransactionFeed.NAME),
         RawTransactionFeedEntry(tx_hash,
                                 tx_contents,
                                 local_region=local_region))
示例#11
0
 def _publish_block_to_on_block_feed(
     self,
     raw_block: EthRawBlock,
 ) -> None:
     if raw_block.source in {FeedSource.BLOCKCHAIN_RPC}:
         self.feed_manager.publish_to_feed(
             FeedKey(EthOnBlockFeed.NAME),
             EventNotification(raw_block.block_number))
 def publish_transaction(self,
                         tx_hash: Sha256Hash,
                         tx_contents: memoryview,
                         local_region: bool = True) -> None:
     transaction_feed_stats_service.log_new_transaction(tx_hash)
     self.node.feed_manager.publish_to_feed(
         FeedKey(EthNewTransactionFeed.NAME),
         EthRawTransaction(tx_hash,
                           tx_contents,
                           FeedSource.BLOCKCHAIN_SOCKET,
                           local_region=local_region))
     transaction_feed_stats_service.log_pending_transaction_from_local(
         tx_hash)
     self.node.feed_manager.publish_to_feed(
         FeedKey(EthPendingTransactionFeed.NAME),
         EthRawTransaction(tx_hash,
                           tx_contents,
                           FeedSource.BLOCKCHAIN_SOCKET,
                           local_region=local_region))
 def publish_new_transaction(self, tx_hash: Sha256Hash,
                             tx_contents: memoryview,
                             local_region: bool) -> None:
     gas_price = eth_common_utils.raw_tx_gas_price(tx_contents, 0)
     if gas_price >= self.node.get_network_min_transaction_fee():
         self.node.feed_manager.publish_to_feed(
             FeedKey(EthNewTransactionFeed.NAME),
             EthRawTransaction(tx_hash,
                               tx_contents,
                               FeedSource.BDN_SOCKET,
                               local_region=local_region))
示例#14
0
    def process_transaction_with_contents(self,
                                          transaction_key: TransactionKey,
                                          tx_contents: memoryview) -> None:
        transaction_feed_stats_service.log_pending_transaction_from_local(
            transaction_key.transaction_hash)

        self.feed_manager.publish_to_feed(
            FeedKey(EthPendingTransactionFeed.NAME),
            EthRawTransaction(transaction_key.transaction_hash,
                              tx_contents,
                              FeedSource.BLOCKCHAIN_RPC,
                              local_region=True))
示例#15
0
    async def test_eth_new_tx_feed_subscribe_not_include_from_blockchain(self):
        self.gateway_node.feed_manager.feeds.clear()
        self.gateway_node.feed_manager.register_feed(EthNewTransactionFeed())

        eth_tx_message = generate_new_eth_transaction()
        eth_transaction = EthRawTransaction(
            eth_tx_message.tx_hash(), eth_tx_message.tx_val(), FeedSource.BDN_SOCKET, local_region=True
        )
        expected_tx_hash = f"0x{str(eth_transaction.tx_hash)}"

        eth_tx_message_blockchain = generate_new_eth_transaction()
        eth_transaction_blockchain = EthRawTransaction(
            eth_tx_message_blockchain.tx_hash(),
            eth_tx_message_blockchain.tx_val(),
            FeedSource.BLOCKCHAIN_SOCKET,
            local_region=True
        )

        async with WsProvider(self.ws_uri) as ws:
            subscription_id = await ws.subscribe(
                "newTxs", {"include_from_blockchain": False}
            )

            self.gateway_node.feed_manager.publish_to_feed(FeedKey("newTxs"), eth_transaction)
            subscription_message = await ws.get_next_subscription_notification_by_id(
                subscription_id
            )
            self.assertEqual(subscription_id, subscription_message.subscription_id)
            self.assertEqual(
                expected_tx_hash, subscription_message.notification["txHash"]
            )

            self.gateway_node.feed_manager.publish_to_feed(
                FeedKey("newTxs"), eth_transaction_blockchain
            )
            with self.assertRaises(asyncio.TimeoutError):
                await asyncio.wait_for(
                    ws.get_next_subscription_notification_by_id(subscription_id), 0.1
                )
    def test_publish_new_tx_from_different_location(self):
        # relay from different region
        bx_tx_message_2 = self._convert_to_bx_message(
            mock_eth_messages.EIP_155_TRANSACTIONS_MESSAGE)
        self.node.feed_manager.publish_to_feed = MagicMock()
        self.relay_connection_2.msg_tx(bx_tx_message_2)

        expected_publication = EthRawTransaction(bx_tx_message_2.tx_hash(),
                                                 bx_tx_message_2.tx_val(),
                                                 FeedSource.BDN_SOCKET,
                                                 local_region=False)
        self.node.feed_manager.publish_to_feed.assert_called_once_with(
            FeedKey(NewTransactionFeed.NAME), expected_publication)
    def validate_params_get_options(self):
        params = self.params

        if not isinstance(params, list) or len(params) != 2:
            raise RpcInvalidParams(
                self.request_id,
                "Subscribe RPC request params must be a list of length 2.",
            )
        feed_name, options = params
        self.feed_name = feed_name
        self.feed_key = FeedKey(self.feed_name, self.feed_network)

        self.options = options
    def test_publish_new_transaction(self):
        bx_tx_message = self._convert_to_bx_message(
            mock_eth_messages.EIP_155_TRANSACTIONS_MESSAGE)
        bx_tx_message.set_transaction_flag(TransactionFlag.LOCAL_REGION)

        self.node.feed_manager.publish_to_feed = MagicMock()
        self.relay_connection_1.msg_tx(bx_tx_message)

        expected_publication = EthRawTransaction(bx_tx_message.tx_hash(),
                                                 bx_tx_message.tx_val(),
                                                 FeedSource.BDN_SOCKET,
                                                 local_region=True)
        self.node.feed_manager.publish_to_feed.assert_called_once_with(
            FeedKey(NewTransactionFeed.NAME), expected_publication)
示例#19
0
    async def test_connection_and_close_while_receiving_subscriptions(self):
        async with WsProvider(self.ws_uri) as ws:
            self.assertEqual(1, len(self.server._connections))

            connection_handler = self.server._connections[0]
            self.assertTrue(ws.running)
            subscription_id = await ws.subscribe("newTxs")

            tx_contents = helpers.generate_bytes(250)

            raw_published_message = RawTransaction(
                helpers.generate_object_hash(),
                memoryview(tx_contents),
                FeedSource.BDN_SOCKET,
                False
            )
            serialized_published_message = RawTransactionFeedEntry(
                raw_published_message.tx_hash, raw_published_message.tx_contents, raw_published_message.local_region
            )
            self.gateway_node.feed_manager.publish_to_feed(
                FeedKey("newTxs"), raw_published_message
            )

            subscription_message = await ws.get_next_subscription_notification_by_id(
                subscription_id
            )
            self.assertEqual(subscription_id, subscription_message.subscription_id)

            self.assertEqual(
                serialized_published_message.tx_hash,
                subscription_message.notification["txHash"],
            )
            self.assertEqual(
                serialized_published_message.tx_contents,
                subscription_message.notification["txContents"],
            )

            self.assertFalse(
                subscription_message.notification["localRegion"],
            )

            task = asyncio.create_task(
                ws.get_next_subscription_notification_by_id(subscription_id)
            )
            await connection_handler.close()
            await asyncio.sleep(0.01)

            exception = task.exception()
            self.assertIsInstance(exception, WsException)
示例#20
0
    def process_transaction_with_parsed_contents(
        self, transaction_key: TransactionKey, parsed_tx: Optional[Dict[str, Any]]
    ) -> None:
        transaction_feed_stats_service.log_pending_transaction_from_local(transaction_key.transaction_hash)

        if parsed_tx is None:
            logger.debug(log_messages.TRANSACTION_NOT_FOUND_IN_MEMPOOL, transaction_key.transaction_hash)
            transaction_feed_stats_service.log_pending_transaction_missing_contents()
        else:
            gas_price = int(parsed_tx["gasPrice"], 16)
            if gas_price >= self.node.get_network_min_transaction_fee():
                self.feed_manager.publish_to_feed(
                    FeedKey(EthPendingTransactionFeed.NAME),
                    EthRawTransaction(
                        transaction_key.transaction_hash,
                        parsed_tx,
                        FeedSource.BLOCKCHAIN_RPC,
                        local_region=True,
                    )
                )
示例#21
0
    async def setUp(self) -> None:
        crypto_utils.recover_public_key = MagicMock(return_value=bytes(32))
        account_model = BdnAccountModelBase(
            "account_id",
            "account_name",
            "fake_certificate",
            new_transaction_streaming=BdnServiceModelConfigBase(
                expire_date=date(2999, 1, 1).isoformat()))

        self.eth_ws_port = helpers.get_free_port()
        self.eth_ws_uri = f"ws://127.0.0.1:{self.eth_ws_port}"
        self.eth_ws_server_message_queue = asyncio.Queue()
        await self.start_server()

        gateway_opts = gateway_helpers.get_gateway_opts(
            8000, eth_ws_uri=self.eth_ws_uri, ws=True)
        gateway_opts.set_account_options(account_model)
        self.gateway_node = MockGatewayNode(gateway_opts)
        self.gateway_node.transaction_streamer_peer = OutboundPeerModel(
            "127.0.0.1", 8006, node_type=NodeType.INTERNAL_GATEWAY)
        self.gateway_node.feed_manager.register_feed(
            EthPendingTransactionFeed(self.gateway_node.alarm_queue))

        self.eth_ws_proxy_publisher = EthWsProxyPublisher(
            self.eth_ws_uri, self.gateway_node.feed_manager,
            self.gateway_node.get_tx_service(), self.gateway_node)
        self.subscriber: Subscriber[
            RawTransactionFeedEntry] = self.gateway_node.feed_manager.subscribe_to_feed(
                FeedKey(EthPendingTransactionFeed.NAME), {})
        self.assertIsNotNone(self.subscriber)

        await self.eth_ws_proxy_publisher.start()
        await asyncio.sleep(0.01)

        self.assertEqual(len(self.eth_ws_proxy_publisher.receiving_tasks), 2)
        self.assertEqual(0, self.subscriber.messages.qsize())

        self.sample_transactions = {
            i: mock_eth_messages.get_dummy_transaction(i)
            for i in range(10)
        }
示例#22
0
    def __init__(
            self,
            request: BxJsonRpcRequest,
            node: "AbstractNode",
            feed_manager: FeedManager,
            subscribe_handler: Callable[[Subscriber, FeedKey], None],
            feed_network: int = 0,
            account_details: Optional[BdnAccountModelBase] = None) -> None:
        self.feed_name = ""
        self.feed_network = feed_network
        self.feed_key = FeedKey(self.feed_name, self.feed_network)
        self.feed_manager = feed_manager
        self.subscribe_handler = subscribe_handler
        self.options = {}
        self.available_fields = []
        self.all_fields = []
        self.account_details = account_details
        self.service_model: Optional[BdnFeedServiceModelConfigBase] = None

        super().__init__(request, node)

        assert self.feed_name != ""
    async def test_unsubscribe(self):
        feed = TestFeed("foo")
        self.feed_manager.register_feed(feed)

        subscribe_request = BxJsonRpcRequest("1", RpcRequestType.SUBSCRIBE,
                                             ["foo", {}])
        rpc_handler = self.rpc.get_request_handler(subscribe_request)
        result = await rpc_handler.process_request()
        subscriber_id = result.result

        # message is received
        next_message_task: Future[BxJsonRpcRequest] = asyncio.ensure_future(
            self.rpc.get_next_subscribed_message())
        await asyncio.sleep(0)
        self.assertFalse(next_message_task.done())
        feed.publish("foobar")
        await asyncio.sleep(0)  # publish to subscriber
        await asyncio.sleep(0)  # subscriber publishes to queue
        self.assertTrue(next_message_task.done())

        unsubscribe_request = BxJsonRpcRequest("1", RpcRequestType.UNSUBSCRIBE,
                                               [subscriber_id])
        rpc_handler = self.rpc.get_request_handler(unsubscribe_request)
        result = await rpc_handler.process_request()
        self.assertTrue(result.result)

        next_message_task: Future[BxJsonRpcRequest] = asyncio.ensure_future(
            self.rpc.get_next_subscribed_message())
        feed.publish("foobar_not_received")
        feed.publish("foobar_not_received_2")
        await asyncio.sleep(0)  # publish to subscriber
        await asyncio.sleep(0)  # subscriber publishes to queue
        self.assertFalse(next_message_task.done())  # no message

        self.assertEqual(0, len(self.rpc.subscriptions))
        self.assertEqual(
            0,
            self.feed_manager.get_feed(FeedKey("foo")).subscriber_count())
    async def test_subscribe_to_feed(self):
        feed = TestFeed("foo")
        self.feed_manager.register_feed(feed)
        subscribe_request = BxJsonRpcRequest("1", RpcRequestType.SUBSCRIBE,
                                             ["foo", {}])

        rpc_handler = self.rpc.get_request_handler(subscribe_request)
        self.assertIsInstance(rpc_handler, SubscribeRpcRequest)

        result = await rpc_handler.process_request()
        self.assertIsNotNone(result.result)
        self.assertIsNone(result.error)
        subscriber_id = result.result

        self.assertEqual(
            1,
            self.feed_manager.get_feed(FeedKey("foo")).subscriber_count())
        self.assertEqual(1, len(self.rpc.subscriptions))
        self.assertIn(subscriber_id, self.rpc.subscriptions)

        next_message_task: Future[BxJsonRpcRequest] = asyncio.ensure_future(
            self.rpc.get_next_subscribed_message())
        await asyncio.sleep(0)
        self.assertFalse(next_message_task.done())

        feed.publish("foobar")
        await asyncio.sleep(0)  # publish to subscriber
        await asyncio.sleep(0)  # subscriber publishes to queue

        self.assertTrue(next_message_task.done())
        next_message = next_message_task.result()

        self.assertEqual("2.0", next_message.json_rpc_version)
        self.assertEqual(RpcRequestType.SUBSCRIBE, next_message.method)
        self.assertEqual(subscriber_id, next_message.params["subscription"])
        self.assertEqual("foobar", next_message.params["result"])
示例#25
0
 def _publish_block_to_transaction_receipts_feed(self,
                                                 raw_block: EthRawBlock):
     self.feed_manager.publish_to_feed(
         FeedKey(EthTransactionReceiptsFeed.NAME), raw_block)
示例#26
0
 def _publish_block_to_new_block_feed(
     self,
     raw_block: EthRawBlock,
 ) -> None:
     self.feed_manager.publish_to_feed(FeedKey(EthNewBlockFeed.NAME),
                                       raw_block)
示例#27
0
    def get_info(self) -> Dict[str, Any]:
        interval_data = self.interval_data

        if len(interval_data.new_transactions_faster_than_pending_times) > 0:
            avg_new_transactions_faster_by_s = (
                sum(interval_data.new_transactions_faster_than_pending_times) /
                len(interval_data.new_transactions_faster_than_pending_times))
        else:
            avg_new_transactions_faster_by_s = 0
        new_transactions_faster_count = len([
            diff for diff in
            interval_data.new_transactions_faster_than_pending_times
            if diff > 0
        ])

        if len(interval_data.pending_from_internal_faster_than_local_times
               ) > 0:
            avg_pending_transactions_from_internal_faster_by_s = (sum(
                interval_data.pending_from_internal_faster_than_local_times
            ) / len(
                interval_data.pending_from_internal_faster_than_local_times))
        else:
            avg_pending_transactions_from_internal_faster_by_s = 0
        pending_transactions_from_internal_faster_count = len([
            diff for diff in
            interval_data.pending_from_internal_faster_than_local_times
            if diff > 0
        ])

        node = self.node
        assert node is not None
        feeds = node.feed_manager.feeds

        pending_transaction_feed = node.feed_manager.get_feed(
            FeedKey(EthPendingTransactionFeed.NAME))
        if pending_transaction_feed:
            pending_transaction_feed_subscribers = len(
                pending_transaction_feed.subscribers)
        else:
            pending_transaction_feed_subscribers = None
        new_transaction_feed = node.feed_manager.get_feed(
            FeedKey(EthNewTransactionFeed.NAME))
        if new_transaction_feed:
            new_transaction_feed_subscribers = len(
                new_transaction_feed.subscribers)
        else:
            new_transaction_feed_subscribers = None

        return {
            "start_time":
            self.interval_data.start_time,
            "end_time":
            self.interval_data.end_time,
            "new_transactions":
            len(interval_data.new_transaction_received_times),
            "pending_transactions":
            len(interval_data.pending_transaction_received_times),
            "pending_transactions_from_internal":
            len(interval_data.pending_transaction_from_internal_received_times
                ),
            "pending_transactions_from_local":
            len(interval_data.
                pending_transaction_from_local_blockchain_received_times),
            "avg_new_transactions_faster_by_s":
            avg_new_transactions_faster_by_s,
            "new_transactions_faster_count":
            new_transactions_faster_count,
            "avg_pending_transactions_from_internal_faster_by_s":
            avg_pending_transactions_from_internal_faster_by_s,
            "pending_transactions_from_internal_faster_count":
            pending_transactions_from_internal_faster_count,
            "pending_transactions_missing_contents":
            interval_data.pending_transactions_missing_contents,
            "pending_transaction_feed_subscribers":
            pending_transaction_feed_subscribers,
            "new_transaction_feed_subscribers":
            new_transaction_feed_subscribers,
            "gateway_transaction_streamers":
            node.get_gateway_transaction_streamers_count()
        }
示例#28
0
 def __contains__(self, item):
     if isinstance(item, FeedKey):
         return item in self.feeds
     else:
         return FeedKey(item) in self.feeds