Example #1
0
    async def test_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())
        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(
                "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["tx_hash"])

            # will publish twice
            self.gateway_node.feed_manager.publish_to_feed(
                "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["tx_hash"])
Example #2
0
    async def test_eth_pending_tx_feed_subscribe_handles_no_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)
        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": False})

            self.gateway_node.feed_manager.publish_to_feed(
                "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 not publish twice
            self.gateway_node.feed_manager.publish_to_feed(
                "pendingTxs", eth_transaction)
            with self.assertRaises(asyncio.TimeoutError):
                await asyncio.wait_for(
                    ws.get_next_subscription_notification_by_id(
                        subscription_id), 0.1)
Example #3
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(
                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)
        }
Example #4
0
    async def test_compare_tx_feeds_script_pending_txs(self):
        self.gateway_node.feed_manager.feeds.clear()
        self.gateway_node.feed_manager.register_feed(
            EthPendingTransactionFeed(self.gateway_node.alarm_queue)
        )

        sys.argv = [
            "main.py",
            "--gateway", "ws://127.0.0.1:8005",
            "--eth", "ws://123.4.5.6:7890",
            "--feed-name", "pendingTxs",
            "--num-intervals", "1",
            "--interval", "2",
            "--lead-time", "0",
            "--trail-time", "0",
        ]
        compare_tx_feeds.process_new_txs_eth = AsyncMock()
        asyncio.create_task(self.send_tx_to_pending_txs_feed())
        try:
            await compare_tx_feeds.main()
        except SystemExit:
            print("Script exited normally.")
Example #5
0
    async def test_eth_pending_transactions_feed_default_subscribe(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)
        expected_tx_hash = f"0x{str(eth_transaction.tx_hash)}"

        async with WsProvider(self.ws_uri) as ws:
            subscription_id = await ws.subscribe("pendingTxs")

            self.gateway_node.feed_manager.publish_to_feed(
                "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"])
Example #6
0
    async def setUp(self) -> None:
        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()
        self.eth_subscription_id = "sub_id"
        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.feed_manager.register_feed(
            EthPendingTransactionFeed(self.gateway_node.alarm_queue)
        )

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

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

        self.assertIsNotNone(self.eth_ws_subscriber.receiving_task)
        self.assertEqual(0, self.subscriber.messages.qsize())

        self.sample_transactions = {
            i: mock_eth_messages.get_dummy_transaction(i) for i in range(10)
        }
Example #7
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))
Example #8
0
 def setUp(self) -> None:
     self.alarm_queue = AlarmQueue()
     self.sut = EthPendingTransactionFeed(self.alarm_queue)
Example #9
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))

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

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

        self.assertEqual(0, subscriber.messages.qsize())
 def setUp(self) -> None:
     self.alarm_queue = AlarmQueue()
     self.sut = EthPendingTransactionFeed(self.alarm_queue)
     self.message_converter = EthNormalMessageConverter()
class EthPendingTransactionFeedTest(AbstractTestCase):

    def setUp(self) -> None:
        self.alarm_queue = AlarmQueue()
        self.sut = EthPendingTransactionFeed(self.alarm_queue)
        self.message_converter = EthNormalMessageConverter()

    def generate_new_eth_transaction(self) -> TxMessage:
        transaction = mock_eth_messages.get_dummy_transaction(1)
        transactions_eth_message = TransactionsEthProtocolMessage(None, [transaction])
        tx_message = self.message_converter.tx_to_bx_txs(
            transactions_eth_message, 5
        )[0][0]
        return tx_message

    def generate_eth_raw_transaction(self) -> EthRawTransaction:
        tx_message = self.generate_new_eth_transaction()
        return EthRawTransaction(tx_message.tx_hash(), tx_message.tx_val())

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

        tx_message = self.generate_new_eth_transaction()
        tx_hash_str = f"0x{str(tx_message.tx_hash())}"

        self.sut.publish(
            EthRawTransaction(tx_message.tx_hash(), tx_message.tx_val())
        )

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

        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(self.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 = self.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 = self.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)
        )

        self.assertEqual(0, subscriber.messages.qsize())
Example #12
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))

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

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

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

    @async_test
    async def test_publish_transaction_filtered_transaction(self):
        to = "0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be"
        subscriber = self.sut.subscribe({"filters": {"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": {"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_filters(self):
        filters_test = {
            "AND": [{
                "to": ["dai", "eth"]
            }, {
                "OR": [
                    {
                        "transaction_value_range_eth": ['0', '1']
                    },
                    {
                        "from": [
                            '0x8fdc5df186c58cdc2c22948beee12b1ae1406c6f',
                            '0x77e2b72689fc954c16b37fbcf1b0b1d395a0e288'
                        ]
                    },
                ]
            }]
        }
        f = {
            "AND": [{
                "transaction_value_range_eth":
                ["187911390000000000", "450550050000000000"]
            }]
        }

        valid = self.sut.reformat_filters(filters_test)
        self.assertTrue(valid)

        valid = self.sut.reformat_filters(f)
        self.assertTrue(valid)

        filters_test = {
            "AND": [{
                "to": ["dai", "eth"]
            }, {
                "OR": [
                    {
                        "hello": [0.0, 2.1]
                    },
                    {
                        "from": [
                            '0x8fdc5df186c58cdc2c22948beee12b1ae1406c6f',
                            '0x77e2b72689fc954c16b37fbcf1b0b1d395a0e288'
                        ]
                    },
                ]
            }]
        }
        with self.assertRaises(Exception):
            self.sut.reformat_filters(filters_test)