コード例 #1
0
 def init_live_feeds(self) -> None:
     self.feed_manager.register_feed(EthNewTransactionFeed())
     self.feed_manager.register_feed(
         EthPendingTransactionFeed(self.alarm_queue))
     self.feed_manager.register_feed(EthOnBlockFeed(self))
     self.feed_manager.register_feed(EthNewBlockFeed(self))
     self.feed_manager.register_feed(EthTransactionReceiptsFeed(self))
コード例 #2
0
ファイル: test_ws_provider.py プロジェクト: CSeanXu/bxgateway
    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 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)
        }
コード例 #5
0
 def setUp(self) -> None:
     self.alarm_queue = AlarmQueue()
     self.sut = EthPendingTransactionFeed(self.alarm_queue)
コード例 #6
0
class EthPendingTransactionFeedTest(AbstractTestCase):
    def setUp(self) -> None:
        self.alarm_queue = AlarmQueue()
        self.sut = EthPendingTransactionFeed(self.alarm_queue)

    @async_test
    async def test_publish_transaction_bytes(self):
        subscriber = self.sut.subscribe({})

        tx_message = mock_eth_messages.generate_eth_tx_message()
        tx_hash_str = f"0x{str(tx_message.tx_hash())}"

        self.sut.publish(
            EthRawTransaction(tx_message.tx_hash(),
                              tx_message.tx_val(),
                              FeedSource.BDN_SOCKET,
                              local_region=True))

        received_tx = await subscriber.receive()
        self.assertEqual(tx_hash_str, received_tx["tx_hash"])
        self.assertEqual(tx_hash_str, received_tx["tx_contents"]["hash"])
        self.assertIn("from", received_tx["tx_contents"])
        self.assertIn("gas", received_tx["tx_contents"])
        self.assertIn("gas_price", received_tx["tx_contents"])
        self.assertIn("input", received_tx["tx_contents"])
        self.assertIn("value", received_tx["tx_contents"])
        self.assertIn("to", received_tx["tx_contents"])
        self.assertIn("nonce", received_tx["tx_contents"])
        self.assertIn("v", received_tx["tx_contents"])
        self.assertIn("r", received_tx["tx_contents"])
        self.assertIn("s", received_tx["tx_contents"])

    @async_test
    async def test_publish_transaction_dictionary(self):
        subscriber = self.sut.subscribe({})

        transaction_hash_str = SAMPLE_TRANSACTION_FROM_WS["hash"]
        transaction_hash = Sha256Hash(
            convert.hex_to_bytes(transaction_hash_str[2:]))

        self.sut.publish(
            EthRawTransaction(transaction_hash,
                              SAMPLE_TRANSACTION_FROM_WS,
                              FeedSource.BLOCKCHAIN_RPC,
                              local_region=True))

        received_tx = await subscriber.receive()
        self.assertEqual(transaction_hash_str, received_tx["tx_hash"])
        self.assertEqual(transaction_hash_str,
                         received_tx["tx_contents"]["hash"])
        self.assertIn("from", received_tx["tx_contents"])
        self.assertIn("gas", received_tx["tx_contents"])
        self.assertIn("gas_price", received_tx["tx_contents"])
        self.assertIn("input", received_tx["tx_contents"])
        self.assertIn("value", received_tx["tx_contents"])
        self.assertIn("to", received_tx["tx_contents"])
        self.assertIn("nonce", received_tx["tx_contents"])
        self.assertIn("v", received_tx["tx_contents"])
        self.assertIn("r", received_tx["tx_contents"])
        self.assertIn("s", received_tx["tx_contents"])

    @async_test
    async def test_publish_transaction_no_subscribers(self):
        self.sut.serialize = MagicMock(wraps=self.sut.serialize)

        self.sut.publish(mock_eth_messages.generate_eth_raw_transaction())

        self.sut.serialize.assert_not_called()

    @async_test
    async def test_publish_transaction_duplicate_transaction(self):
        self.sut.subscribe({})

        self.sut.serialize = MagicMock(wraps=self.sut.serialize)
        raw_transaction = mock_eth_messages.generate_eth_raw_transaction()

        self.sut.publish(raw_transaction)
        self.sut.publish(raw_transaction)

        self.sut.serialize.assert_called_once()

    @async_test
    async def test_publish_duplicate_transaction_subscriber_wants_duplicates(
            self):
        subscriber = self.sut.subscribe({"duplicates": True})

        self.sut.serialize = MagicMock(wraps=self.sut.serialize)
        subscriber.queue = MagicMock(wraps=subscriber.queue)
        raw_transaction = mock_eth_messages.generate_eth_raw_transaction()

        self.sut.publish(raw_transaction)
        self.sut.serialize.assert_called_once()
        self.sut.serialize.reset_mock()
        subscriber.queue.assert_called_once()
        subscriber.queue.reset_mock()

        self.sut.publish(raw_transaction)
        self.sut.serialize.assert_called_once()
        subscriber.queue.assert_called_once()

    @async_test
    async def test_publish_invalid_transaction(self):
        subscriber = self.sut.subscribe({})

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

        self.sut.publish(
            EthRawTransaction(transaction_hash,
                              transaction_contents,
                              FeedSource.BLOCKCHAIN_SOCKET,
                              local_region=True))

        self.assertEqual(0, subscriber.messages.qsize())

    @async_test
    async def test_publish_transaction_filtered_transaction(self):
        to = "0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be"
        subscriber = self.sut.subscribe({"filters": f"to = {to}"})
        self.sut.serialize = MagicMock(wraps=self.sut.serialize)
        subscriber.queue = MagicMock(wraps=subscriber.queue)
        raw_transaction = mock_eth_messages.generate_eth_raw_transaction_with_to_address(
            FeedSource.BLOCKCHAIN_SOCKET,
            "3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be")

        self.sut.publish(raw_transaction)
        received_tx = await subscriber.receive()
        self.assertTrue(received_tx)
        self.assertEqual(received_tx["tx_contents"].get("to", None), to)
        self.sut.serialize.assert_called_once()
        self.sut.serialize.reset_mock()
        subscriber.queue.assert_called_once()

    @async_test
    async def test_publish_transaction_denied_transaction(self):
        to = "0x1111111111111111111111111111111111111111"
        subscriber = self.sut.subscribe({"filters": f"to = {to}"})
        self.sut.serialize = MagicMock(wraps=self.sut.serialize)
        subscriber.queue = MagicMock(wraps=subscriber.queue)
        raw_transaction = mock_eth_messages.generate_eth_raw_transaction_with_to_address(
            FeedSource.BLOCKCHAIN_SOCKET,
            "3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be")

        self.sut.publish(raw_transaction)
        subscriber.queue.assert_not_called()

    @async_test
    async def test_validate_and_handle_filters1(self):
        t1 = "to == dai or to == eth"

        valid = self.sut.validate_filters(t1)
        self.assertTrue(valid)
        subscriber = self.sut.subscribe({"filters": t1})
        subscriber.queue = MagicMock(wraps=subscriber.queue)
        transaction_hash_str = SAMPLE_TRANSACTION_FROM_WS["hash"]
        transaction_hash = Sha256Hash(
            convert.hex_to_bytes(transaction_hash_str[2:]))

        self.sut.publish(
            EthRawTransaction(transaction_hash,
                              SAMPLE_TRANSACTION_FROM_WS,
                              FeedSource.BLOCKCHAIN_RPC,
                              local_region=True))
        subscriber.queue.assert_not_called()

    @async_test
    async def test_validate_and_handle_filters2(self):
        t2 = "value > 5534673480000000000 or to = 0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be"

        valid = self.sut.validate_filters(t2)
        self.assertTrue(valid)
        subscriber = self.sut.subscribe({"filters": t2})
        subscriber.queue = MagicMock(wraps=subscriber.queue)
        logger.error(
            subscriber.validator({
                "value":
                10,
                "from":
                "0xbd4e113ee68bcbbf768ba1d6c7a14e003362979a"
            }))
        raw_transaction = mock_eth_messages.generate_eth_raw_transaction_with_to_address(
            FeedSource.BLOCKCHAIN_SOCKET,
            "3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be")
        logger.error(raw_transaction.tx_contents)
        self.sut.publish(raw_transaction)
        subscriber.queue.assert_called_once()

    @async_test
    async def test_validate_and_handle_filters3(self):
        t3 = "value > 5534673480000000000 or (to = 0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be or to = 0xbd4e113ee68bcbbf768ba1d6c7a14e0033629792)"

        valid = self.sut.validate_filters(t3)
        self.assertTrue(valid)
        subscriber = self.sut.subscribe({"filters": t3})
        subscriber.queue = MagicMock(wraps=subscriber.queue)
        logger.error(
            subscriber.validator({
                "value":
                10,
                "from":
                "0xbd4e113ee68bcbbf768ba1d6c7a14e003362979a"
            }))
        raw_transaction = mock_eth_messages.generate_eth_raw_transaction_with_to_address(
            FeedSource.BLOCKCHAIN_SOCKET,
            "3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be")
        logger.error(raw_transaction.tx_contents)
        self.sut.publish(raw_transaction)
        subscriber.queue.assert_called_once()

    @async_test
    async def test_validate_and_handle_filters4(self):
        t3 = "to in [0x0000000000000000000000000000000000000001]"

        valid = self.sut.validate_filters(t3)
        self.assertTrue(valid)
        subscriber = self.sut.subscribe({"filters": t3})
        subscriber.queue = MagicMock(wraps=subscriber.queue)
        valid = subscriber.validator({
            "value":
            10,
            "to":
            eth_filter_handlers.reformat_address("0x")
        })
        self.assertFalse(valid)
        valid = subscriber.validator({"value": 10, "to": "0x"})
        self.assertTrue(valid)
        t4 = "to in [0x0000000000000000000000000000000000000000]"
        subscriber = self.sut.subscribe({"filters": t4})
        valid = subscriber.validator({
            "value":
            10,
            "to":
            eth_filter_handlers.reformat_address("0x")
        })
        self.assertTrue(valid)