async def setUp(self) -> None: pub_key = "a04f30a45aae413d0ca0f219b4dcb7049857bc3f91a6351288cce603a2c9646294a02b987bf6586b370b2c22d74662355677007a14238bb037aedf41c2d08866" opts = gateway_helpers.get_gateway_opts( 8000, include_default_eth_args=True, pub_key=pub_key, ) if opts.use_extensions: helpers.set_extensions_parallelism() node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE, MagicMock()) self.node = EthGatewayNode(opts, node_ssl_service) self.feed_manager = FeedManager(self.node) self.node.feed_manager = self.feed_manager self.rpc = SubscriptionRpcHandler(self.node, self.feed_manager, Case.SNAKE) self.feed_name = NewTransactionFeed.NAME self.node.init_live_feeds() self.feed_service_model = FeedServiceModelBase( allow_filtering=True, available_fields=["all"]) self.base_feed_service_model = BdnFeedServiceModelConfigBase( expire_date="2999-01-01", feed=self.feed_service_model) self.node.account_model = BdnAccountModelBase( account_id="account_id", certificate="", logical_account_name="test", new_transaction_streaming=self.base_feed_service_model, )
def setUp(self) -> None: pub_key = "a04f30a45aae413d0ca0f219b4dcb7049857bc3f91a6351288cce603a2c9646294a02b987bf6586b370b2c22d74662355677007a14238bb037aedf41c2d08866" opts = gateway_helpers.get_gateway_opts(8000, pub_key=pub_key) node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE, MagicMock()) self.node = EthGatewayNode(opts, node_ssl_service) self.relay_1 = MockNode( helpers.get_common_opts(8000, region="us-east-1")) self.relay_connection_1 = helpers.create_connection( EthRelayConnection, self.node, node_opts=self.relay_1.opts, file_no=1, ip="1.2.3.4") self.relay_2 = MockNode( helpers.get_common_opts(8001, region="eu-west-1")) self.relay_connection_2 = helpers.create_connection( EthRelayConnection, self.node, node_opts=self.relay_2.opts, file_no=1, ip="1.2.3.5") self.node.broadcast = MagicMock() self.node.has_active_blockchain_peer = MagicMock(return_value=True)
def setUp(self) -> None: pub_key = "a04f30a45aae413d0ca0f219b4dcb7049857bc3f91a6351288cce603a2c9646294a02b987bf6586b370b2c22d74662355677007a14238bb037aedf41c2d08866" opts = gateway_helpers.get_gateway_opts(8000, pub_key=pub_key) node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE, MagicMock()) self.node = EthGatewayNode(opts, node_ssl_service) self.connection = helpers.create_connection(EthRelayConnection, self.node) self.node.broadcast = MagicMock() self.node.has_active_blockchain_peer = MagicMock(return_value=True)
def setUp(self) -> None: pub_key = "a04f30a45aae413d0ca0f219b4dcb7049857bc3f91a6351288cce603a2c9646294a02b987bf6586b370b2c22d74662355677007a14238bb037aedf41c2d08866" node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE, MagicMock()) opts = gateway_helpers.get_gateway_opts( 8000, include_default_eth_args=True, blockchain_protocol=BlockchainProtocol.ETHEREUM.name, blockchain_network_num=5, pub_key=pub_key, ) self.node = EthGatewayNode(opts, node_ssl_service) self.enqueued_messages = [] self.broadcast_to_node_messages = [] self.broadcast_messages = [] self.node.opts.has_fully_updated_tx_service = True self.node.init_live_feeds() self.connection = helpers.create_connection( EthNodeConnection, self.node, opts, port=opts.blockchain_port ) gateway_helpers.add_blockchain_peer(self.node, self.connection) self.block_queuing_service = self.node.block_queuing_service_manager.get_designated_block_queuing_service() self.connection.on_connection_established() self.node.node_conn = self.connection gateway_bdn_performance_stats_service.set_node(self.node) def mocked_enqueue_msg(msg, prepend=False): self.enqueued_messages.append(msg) self.connection.enqueue_msg = mocked_enqueue_msg def mocked_broadcast(msg, broadcasting_conn=None, prepend_to_queue=False, connection_types=None): if connection_types is None: connection_types = [ConnectionType.RELAY_ALL] if len(connection_types) == 1 and connection_types[0] == ConnectionType.BLOCKCHAIN_NODE: self.broadcast_to_node_messages.append(msg) else: self.broadcast_messages.append(msg) self.node.broadcast = mocked_broadcast self.cleanup_service = self.node.block_cleanup_service self.node.block_processing_service.queue_block_for_processing = MagicMock() self.sut = self.connection.connection_protocol self.sut._waiting_checkpoint_headers_request = False self.node.opts.ws = True self.node.publish_block = MagicMock()
def setUp(self) -> None: crypto_utils.recover_public_key = MagicMock( return_value=bytes(32)) pub_key = "a04f30a45aae413d0ca0f219b4dcb7049857bc3f91a6351288cce603a2c9646294a02b987bf6586b370b2c22d74662355677007a14238bb037aedf41c2d08866" opts = gateway_helpers.get_gateway_opts(8000, include_default_eth_args=True, pub_key=pub_key, track_detailed_sent_messages=True) if opts.use_extensions: helpers.set_extensions_parallelism() node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE, MagicMock()) self.node = EthGatewayNode(opts, node_ssl_service) self.sut = EthNewBlockFeed(self.node)
def setUp(self) -> None: pub_key = "a04f30a45aae413d0ca0f219b4dcb7049857bc3f91a6351288cce603a2c9646294a02b987bf6586b370b2c22d74662355677007a14238bb037aedf41c2d08866" opts = gateway_helpers.get_gateway_opts( 8000, include_default_eth_args=True, pub_key=pub_key, track_detailed_sent_messages=True) if opts.use_extensions: helpers.set_extensions_parallelism() node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE, MagicMock()) self.node = EthGatewayNode(opts, node_ssl_service) self.connection_fileno = 1 self.connection = helpers.create_connection( EthNodeConnection, node=self.node, file_no=self.connection_fileno) cipher1, cipher2 = AbstractRLPxCipherTest().setup_ciphers() self.connection.connection_protocol.rlpx_cipher = cipher1
class EthNodeConnectionTest(AbstractTestCase): def setUp(self) -> None: pub_key = "a04f30a45aae413d0ca0f219b4dcb7049857bc3f91a6351288cce603a2c9646294a02b987bf6586b370b2c22d74662355677007a14238bb037aedf41c2d08866" opts = gateway_helpers.get_gateway_opts( 8000, include_default_eth_args=True, pub_key=pub_key, track_detailed_sent_messages=True) if opts.use_extensions: helpers.set_extensions_parallelism() node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE, MagicMock()) self.node = EthGatewayNode(opts, node_ssl_service) self.connection_fileno = 1 self.connection = helpers.create_connection( EthNodeConnection, node=self.node, file_no=self.connection_fileno, port=opts.blockchain_port) cipher1, cipher2 = AbstractRLPxCipherTest().setup_ciphers() self.connection.connection_protocol.rlpx_cipher = cipher1 def test_message_tracked_correctly_when_framed(self): block_stats.add_block_event_by_block_hash = MagicMock() # send the handshake message self.node.on_bytes_sent(self.connection_fileno, 307) self.node.on_bytes_written_to_socket(self.connection_fileno, 307) block_message = NewBlockEthProtocolMessage( None, mock_eth_messages.get_dummy_block( 1, mock_eth_messages.get_dummy_block_header(5, int(time.time()))), 10) block_message.serialize() self.connection.enqueue_msg(block_message) message_length = self.connection.outputbuf.length for message in self.connection.message_tracker.messages: print(message.length) block_stats.add_block_event_by_block_hash.assert_not_called() self.assertEqual(message_length, self.connection.message_tracker.messages[0].length) self.node.on_bytes_sent(self.connection_fileno, message_length) self.node.on_bytes_written_to_socket(self.connection_fileno, message_length) block_stats.add_block_event_by_block_hash.assert_called_once()
def setUp(self) -> None: crypto_utils.recover_public_key = MagicMock(return_value=bytes(32)) pub_key = "a04f30a45aae413d0ca0f219b4dcb7049857bc3f91a6351288cce603a2c9646294a02b987bf6586b370b2c22d74662355677007a14238bb037aedf41c2d08866" opts = gateway_helpers.get_gateway_opts(8000, include_default_eth_args=True, pub_key=pub_key) if opts.use_extensions: helpers.set_extensions_parallelism() node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE, MagicMock()) self.node = EthGatewayNode(opts, node_ssl_service) self.node_conn = MockConnection( MockSocketConnection(1, self.node, ip_address=LOCALHOST, port=8002), self.node) self.node.connection_pool.add(1, LOCALHOST, 8002, self.node_conn) gateway_helpers.add_blockchain_peer(self.node, self.node_conn) self.block_queuing_service = self.node.block_queuing_service_manager.get_designated_block_queuing_service( ) self.sut = EthNewBlockFeed(self.node)
def _set_up_test_node(self, initialize_handshake, generate_pub_key=False): # Dummy address self.server_ip = "127.0.0.1" self.server_port = 1234 self.blockchain_ip = "0.0.0.0" self.blockchain_port = 30303 # Setting up dummy server addresses self.servers = [ OutboundPeerModel("172.0.0.1", 2222, node_type=NodeType.GATEWAY), OutboundPeerModel("172.0.0.2", 3333, node_type=NodeType.GATEWAY), OutboundPeerModel("172.0.0.3", 4444, node_type=NodeType.GATEWAY) ] if generate_pub_key: pub_key = convert.bytes_to_hex(self._get_dummy_public_key()) else: pub_key = None opts = gateway_helpers.get_gateway_opts( self.server_port, sid_expire_time=0, external_ip=self.server_ip, test_mode=[], peer_gateways=[], peer_relays=self.servers, blockchain_address=(self.blockchain_ip, self.blockchain_port), include_default_eth_args=True, pub_key=pub_key, no_discovery=not initialize_handshake) if opts.use_extensions: helpers.set_extensions_parallelism() node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE, MagicMock()) self.node = EthGatewayNode(opts, node_ssl_service) self.node.requester = MagicMock() self.assertTrue(self.node) return self.node
class EthNewBlockFeedPublishTest(AbstractTestCase): def setUp(self) -> None: crypto_utils.recover_public_key = MagicMock(return_value=bytes(32)) pub_key = "a04f30a45aae413d0ca0f219b4dcb7049857bc3f91a6351288cce603a2c9646294a02b987bf6586b370b2c22d74662355677007a14238bb037aedf41c2d08866" opts = gateway_helpers.get_gateway_opts( 8000, include_default_eth_args=True, pub_key=pub_key, track_detailed_sent_messages=True) if opts.use_extensions: helpers.set_extensions_parallelism() node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE, MagicMock()) self.node = EthGatewayNode(opts, node_ssl_service) self.node_conn = MockConnection( MockSocketConnection(1, self.node, ip_address=LOCALHOST, port=8002), self.node) self.node.connection_pool.add(1, LOCALHOST, 8002, self.node_conn) gateway_helpers.add_blockchain_peer(self.node, self.node_conn) self.block_queuing_service = self.node.block_queuing_service_manager.get_designated_block_queuing_service( ) self.sut = EthNewBlockFeed(self.node) def generate_new_eth_block(self, block_number=10) -> InternalEthBlockInfo: block_message = NewBlockEthProtocolMessage( None, mock_eth_messages.get_dummy_block( 1, mock_eth_messages.get_dummy_block_header( 5, int(time.time()), block_number=block_number)), 10) block_message.serialize() internal_block_message = InternalEthBlockInfo.from_new_block_msg( block_message) return internal_block_message def generate_raw_block_msg(self, block_number=10, source=FeedSource.BLOCKCHAIN_SOCKET): block_msg = self.generate_new_eth_block(block_number) return EthRawBlock(block_msg.block_number(), block_msg.block_hash(), source, self.node._get_block_message_lazy(block_msg, None)) def tearDown(self) -> None: crypto_utils.recover_public_key = _recover_public_key def test_lazy_get_block(self): block_msg = self.generate_new_eth_block() block_hash = block_msg.block_hash() # raises when block is absent from block queueing service lazy_block = self.node._get_block_message_lazy(None, block_hash) with self.assertRaises(StopIteration): block = next(lazy_block) self.assertIsNone(block) # returns block self.node.block_parts_storage[ block_hash] = block_msg.to_new_block_parts() lazy_block = self.node._get_block_message_lazy(None, block_hash) block = next(lazy_block) self.assertEqual(block.block_hash(), block_hash) # returns block lazy_block = self.node._get_block_message_lazy(block_msg, None) next(lazy_block) self.assertEqual(block.block_hash(), block_hash) def test_block_seen_from_node(self): self.node.publish_block = MagicMock() block_msg = self.generate_new_eth_block() block_hash = block_msg.block_hash() block_number = block_msg.block_number() # called without block_msg self.block_queuing_service.mark_block_seen_by_blockchain_node( block_hash, None, block_number, ) # called once with block self.node.publish_block.assert_not_called() # called for same block with message self.node.publish_block = MagicMock() self.block_queuing_service.mark_block_seen_by_blockchain_node( block_hash, block_msg, block_number, ) self.node.publish_block.assert_called_with( block_number, block_hash, block_msg, FeedSource.BLOCKCHAIN_SOCKET) # call for stale block stale_block_msg = self.generate_new_eth_block(9) stale_block_hash = stale_block_msg.block_hash() stale_block_number = stale_block_msg.block_number() self.node.publish_block = MagicMock() self.block_queuing_service.mark_block_seen_by_blockchain_node( stale_block_hash, stale_block_msg, stale_block_number, ) self.node.publish_block.assert_not_called() def test_push_block(self): self.node.publish_block = MagicMock() block_msg = self.generate_new_eth_block() block_hash = block_msg.block_hash() block_number = block_msg.block_number() self.node.block_queuing_service_manager.push(block_hash, block_msg) self.node.publish_block.assert_called_once() self.node.publish_block.assert_called_with(block_number, block_hash, block_msg, FeedSource.BDN_SOCKET) def test_publish_fork(self): # in case of a fork publish current block, # and attempt to publish all following blocks from the queueing service self.sut.subscriber_count = MagicMock(return_value=10) self.sut.publish_blocks_from_queue = MagicMock() self.sut.publish(self.generate_raw_block_msg(10)) self.sut.publish(self.generate_raw_block_msg(11)) self.sut.publish(self.generate_raw_block_msg(12)) fork_msg = self.generate_raw_block_msg(10) self.sut.publish(fork_msg) self.assertIn(fork_msg.block_hash, self.sut.published_blocks.contents) self.sut.publish_blocks_from_queue.assert_called_with(11, 12) def test_publish_gap(self): # in case of a gap attempt to publish all intermediate blocks from the queueing service # and publish current block self.sut.subscriber_count = MagicMock(return_value=10) self.sut.publish_blocks_from_queue = MagicMock() self.sut.publish(self.generate_raw_block_msg(10)) msg = self.generate_raw_block_msg(20) self.sut.publish(msg) self.assertIn(msg.block_hash, self.sut.published_blocks.contents) self.sut.publish_blocks_from_queue.assert_called_once() self.sut.publish_blocks_from_queue.assert_called_with(11, 19) def test_publish_from_queue(self): self.sut.subscriber_count = MagicMock(return_value=10) self.sut.publish = MagicMock() self.sut.publish_blocks_from_queue(10, 20) # no blocks in queueing service self.sut.publish.assert_not_called() self.block_queuing_service.accepted_block_hash_at_height[11] = "11" self.sut.publish_blocks_from_queue(10, 20) # only one block in queueing service self.sut.publish.assert_called_once() self.sut.publish = MagicMock() for i in range(10, 20): self.block_queuing_service.accepted_block_hash_at_height[i] = str( i) self.sut.publish_blocks_from_queue(10, 20) # only one block in queueing service call_args = self.sut.publish.call_args_list self.assertTrue(10, len(call_args)) published_blocks = set({}) for _call in call_args: published_blocks.add(_call[0][0].block_number) self.assertEqual(set(range(10, 20)), published_blocks)
class EthNodeConnectionProtocolTest(AbstractTestCase): def setUp(self) -> None: pub_key = "a04f30a45aae413d0ca0f219b4dcb7049857bc3f91a6351288cce603a2c9646294a02b987bf6586b370b2c22d74662355677007a14238bb037aedf41c2d08866" node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE, MagicMock()) opts = gateway_helpers.get_gateway_opts( 8000, include_default_eth_args=True, blockchain_protocol=BlockchainProtocol.ETHEREUM.name, blockchain_network_num=5, pub_key=pub_key, ) self.node = EthGatewayNode(opts, node_ssl_service) self.enqueued_messages = [] self.broadcast_to_node_messages = [] self.broadcast_messages = [] self.node.opts.has_fully_updated_tx_service = True self.node.init_live_feeds() self.connection = helpers.create_connection( EthNodeConnection, self.node, opts, port=opts.blockchain_port ) gateway_helpers.add_blockchain_peer(self.node, self.connection) self.block_queuing_service = self.node.block_queuing_service_manager.get_designated_block_queuing_service() self.connection.on_connection_established() self.node.node_conn = self.connection gateway_bdn_performance_stats_service.set_node(self.node) def mocked_enqueue_msg(msg, prepend=False): self.enqueued_messages.append(msg) self.connection.enqueue_msg = mocked_enqueue_msg def mocked_broadcast(msg, broadcasting_conn=None, prepend_to_queue=False, connection_types=None): if connection_types is None: connection_types = [ConnectionType.RELAY_ALL] if len(connection_types) == 1 and connection_types[0] == ConnectionType.BLOCKCHAIN_NODE: self.broadcast_to_node_messages.append(msg) else: self.broadcast_messages.append(msg) self.node.broadcast = mocked_broadcast self.cleanup_service = self.node.block_cleanup_service self.node.block_processing_service.queue_block_for_processing = MagicMock() self.sut = self.connection.connection_protocol self.sut._waiting_checkpoint_headers_request = False self.node.opts.ws = True self.node.publish_block = MagicMock() def test_request_block_bodies(self): self.cleanup_service.clean_block_transactions_by_block_components = ( MagicMock() ) block_hashes_sets = [ [helpers.generate_object_hash(), helpers.generate_object_hash()], [helpers.generate_object_hash()], [helpers.generate_object_hash()], ] block_bodies_messages = [ BlockBodiesEthProtocolMessage( None, [ mock_eth_messages.get_dummy_transient_block_body(1), mock_eth_messages.get_dummy_transient_block_body(2), ], ), BlockBodiesEthProtocolMessage( None, [mock_eth_messages.get_dummy_transient_block_body(3)] ), BlockBodiesEthProtocolMessage( None, [mock_eth_messages.get_dummy_transient_block_body(4)] ), ] transactions = [ [ [ tx.hash() for tx in BlockBodiesEthProtocolMessage.from_body_bytes( block_body_bytes ) .get_blocks()[0] .transactions ] for block_body_bytes in msg.get_block_bodies_bytes() ] for msg in block_bodies_messages ] for block_bodies_message in block_bodies_messages: block_bodies_message.serialize() for block_hashes_set in block_hashes_sets: for block_hash in block_hashes_set: self.node.block_cleanup_service._block_hash_marked_for_cleanup.add( block_hash ) self.sut.request_block_body(block_hashes_set) self.sut.msg_block_bodies(block_bodies_messages[0]) call_args_list = ( self.cleanup_service.clean_block_transactions_by_block_components.call_args_list ) first_call = call_args_list[0] first_kwargs = first_call[1] self.assertEqual( first_kwargs["transaction_service"], self.node.get_tx_service() ) self.assertEqual(first_kwargs["block_hash"], block_hashes_sets[0][0]) self.assertEqual( list(first_kwargs["transactions_list"]), transactions[0][0] ) second_call = call_args_list[1] second_kwargs = second_call[1] self.assertEqual( second_kwargs["transaction_service"], self.node.get_tx_service() ) self.assertEqual(second_kwargs["block_hash"], block_hashes_sets[0][1]) self.assertEqual( list(second_kwargs["transactions_list"]), transactions[0][1] ) self.cleanup_service.clean_block_transactions_by_block_components.reset_mock() self.sut.msg_block_bodies(block_bodies_messages[1]) call_args_list = ( self.cleanup_service.clean_block_transactions_by_block_components.call_args_list ) first_call = call_args_list[0] first_kwargs = first_call[1] self.assertEqual( first_kwargs["transaction_service"], self.node.get_tx_service() ) self.assertEqual(first_kwargs["block_hash"], block_hashes_sets[1][0]) self.assertEqual( list(first_kwargs["transactions_list"]), transactions[1][0] ) self.cleanup_service.clean_block_transactions_by_block_components.reset_mock() self.sut.msg_block_bodies(block_bodies_messages[2]) call_args_list = ( self.cleanup_service.clean_block_transactions_by_block_components.call_args_list ) first_call = call_args_list[0] first_kwargs = first_call[1] self.assertEqual( first_kwargs["transaction_service"], self.node.get_tx_service() ) self.assertEqual(first_kwargs["block_hash"], block_hashes_sets[2][0]) self.assertEqual( list(first_kwargs["transactions_list"]), transactions[2][0] ) def test_msg_get_block_headers_unknown(self): block_hash = helpers.generate_hash() self.sut.msg_proxy_request = MagicMock() message = GetBlockHeadersEthProtocolMessage(None, block_hash, 1, 0, 0) self.sut.msg_get_block_headers(message) self.sut.msg_proxy_request.assert_called_once() def test_msg_get_block_headers_known_single(self): header = mock_eth_messages.get_dummy_block_header(12) block = mock_eth_messages.get_dummy_block(1, header) raw_hash = header.hash() block_hash = header.hash_object() new_block_message = NewBlockEthProtocolMessage(None, block, 10) eth_block_info = InternalEthBlockInfo.from_new_block_msg( new_block_message ) self.node.block_queuing_service_manager.push(block_hash, eth_block_info) self.enqueued_messages.clear() self.sut.msg_proxy_request = MagicMock() message = GetBlockHeadersEthProtocolMessage(None, raw_hash, 1, 0, 0) self.sut.msg_get_block_headers(message) self.sut.msg_proxy_request.assert_not_called() self.assertEqual(1, len(self.enqueued_messages)) headers_sent = self.enqueued_messages[0] self.assertIsInstance(headers_sent, BlockHeadersEthProtocolMessage) self.assertEqual(1, len(headers_sent.get_block_headers())) self.assertEqual( block_hash, headers_sent.get_block_headers()[0].hash_object() ) self.block_queuing_service.mark_block_seen_by_blockchain_node( block_hash, eth_block_info ) self.sut.msg_get_block_headers(message) self.sut.msg_proxy_request.assert_not_called() self.assertEqual(2, len(self.enqueued_messages)) def test_msg_get_block_headers_block_number(self): block_number = 123456 header = mock_eth_messages.get_dummy_block_header( 12, block_number=block_number ) block = mock_eth_messages.get_dummy_block(1, header) block_hash = header.hash_object() new_block_message = NewBlockEthProtocolMessage(None, block, 10) eth_block_info = InternalEthBlockInfo.from_new_block_msg( new_block_message ) self.node.block_queuing_service_manager.push(block_hash, eth_block_info) self.enqueued_messages.clear() self.sut.msg_proxy_request = MagicMock() block_number_bytes = struct.pack(">I", block_number) message = GetBlockHeadersEthProtocolMessage( None, block_number_bytes, 1, 0, 0 ) self.sut.msg_get_block_headers(message) self.sut.msg_proxy_request.assert_not_called() self.assertEqual(1, len(self.enqueued_messages)) headers_sent = self.enqueued_messages[0] self.assertIsInstance(headers_sent, BlockHeadersEthProtocolMessage) self.assertEqual(1, len(headers_sent.get_block_headers())) self.assertEqual( block_hash, headers_sent.get_block_headers()[0].hash_object() ) def test_msg_get_block_headers_known_many(self): self.node.opts.max_block_interval_s = 0 block_hashes = [] block_hash = None for i in range(20): block_message = InternalEthBlockInfo.from_new_block_msg( mock_eth_messages.new_block_eth_protocol_message( i, i + 1000, block_hash ) ) block_hash = block_message.block_hash() block_hashes.append(block_hash) self.node.block_queuing_service_manager.push(block_hash, block_message) self.block_queuing_service.best_sent_block = (1019, block_hashes[-1], 0) self.enqueued_messages.clear() self.sut.msg_proxy_request = MagicMock() message = GetBlockHeadersEthProtocolMessage( None, block_hashes[10].binary, 10, 0, 0 ) self.sut.msg_get_block_headers(message) self.sut.msg_proxy_request.assert_not_called() self.assertEqual(1, len(self.enqueued_messages)) headers_sent = self.enqueued_messages[0] self.assertIsInstance(headers_sent, BlockHeadersEthProtocolMessage) self.assertEqual(10, len(headers_sent.get_block_headers())) for i in range(10): self.assertEqual( block_hashes[i + 10], headers_sent.get_block_headers()[i].hash_object(), ) def test_msg_get_block_headers_fork(self): self.node.opts.max_block_interval_s = 0 block_hashes = [] for i in range(20): block_message = InternalEthBlockInfo.from_new_block_msg( mock_eth_messages.new_block_eth_protocol_message(i, i + 1000) ) block_hash = block_message.block_hash() block_hashes.append(block_hash) self.node.block_queuing_service_manager.push(block_hash, block_message) # create fork block_message = InternalEthBlockInfo.from_new_block_msg( mock_eth_messages.new_block_eth_protocol_message(34, 1017) ) block_hash = block_message.block_hash() block_hashes.append(block_hash) self.node.block_queuing_service_manager.push(block_hash, block_message) self.enqueued_messages.clear() self.sut.msg_proxy_request = MagicMock() message = GetBlockHeadersEthProtocolMessage( None, block_hashes[-1].binary, 10, 0, 1 ) self.sut.msg_get_block_headers(message) self.sut.msg_proxy_request.assert_called_once() self.assertEqual(0, len(self.enqueued_messages)) def test_msg_get_block_headers_missing_block(self): self.node.opts.max_block_interval_s = 0 block_hashes = [] for i in (j for j in range(20) if j != 17): block_message = InternalEthBlockInfo.from_new_block_msg( mock_eth_messages.new_block_eth_protocol_message(i, i + 1000) ) block_hash = block_message.block_hash() block_hashes.append(block_hash) self.node.block_queuing_service_manager.push(block_hash, block_message) self.enqueued_messages.clear() self.sut.msg_proxy_request = MagicMock() message = GetBlockHeadersEthProtocolMessage( None, block_hashes[-1].binary, 10, 0, 1 ) self.sut.msg_get_block_headers(message) self.sut.msg_proxy_request.assert_called_once() self.assertEqual(0, len(self.enqueued_messages)) def test_msg_get_block_headers_future_block(self): self.node.opts.max_block_interval_s = 0 block_hashes = [] block_heights = [] for i in range(20): block_message = InternalEthBlockInfo.from_new_block_msg( mock_eth_messages.new_block_eth_protocol_message(i, i + 1000) ) block_hash = block_message.block_hash() block_heights.append(block_message.block_number()) block_hashes.append(block_hash) self.node.block_queuing_service_manager.push(block_hash, block_message) self.enqueued_messages.clear() self.sut.msg_proxy_request = MagicMock() block_height_bytes = block_heights[-1] + 4 block_height_bytes = block_height_bytes.to_bytes(8, "big") message = GetBlockHeadersEthProtocolMessage( None, block_height_bytes, 1, 0, 0 ) self.sut.msg_get_block_headers(message) self.sut.msg_proxy_request.assert_not_called() self.assertEqual(1, len(self.enqueued_messages)) headers_sent = self.enqueued_messages[0] self.assertIsInstance(headers_sent, BlockHeadersEthProtocolMessage) self.assertEqual(0, len(headers_sent.get_block_headers())) def test_msg_block_adds_headers_and_bodies(self): self.node.opts.max_block_interval_s = 0 self.sut.is_valid_block_timestamp = MagicMock(return_value=True) block_hashes = [] block_messages = [] block_hash = None for i in range(20): block_message = InternalEthBlockInfo.from_new_block_msg( mock_eth_messages.new_block_eth_protocol_message(i, i + 1000, block_hash) ) block_hash = block_message.block_hash() block_hashes.append(block_hash) block_messages.append(block_message) # push all blocks, except for # 17 for i in (j for j in range(20) if j != 17): self.node.block_queuing_service_manager.push( block_hashes[i], block_messages[i] ) self.block_queuing_service.remove_from_queue(block_hashes[i]) self.block_queuing_service.best_sent_block = (1019, block_hashes[-1], 0) self.enqueued_messages.clear() self.sut.msg_proxy_request = MagicMock() message = GetBlockHeadersEthProtocolMessage( None, block_hashes[10].binary, 10, 0, 0 ) self.sut.msg_get_block_headers(message) self.sut.msg_proxy_request.assert_called_once() self.sut.msg_proxy_request.reset_mock() self.sut.msg_block(block_messages[17].to_new_block_msg()) self.node.publish_block.assert_called() self.sut.msg_get_block_headers(message) self.sut.msg_proxy_request.assert_not_called() self.assertEqual(1, len(self.enqueued_messages)) headers_sent = self.enqueued_messages[0] self.assertIsInstance(headers_sent, BlockHeadersEthProtocolMessage) self.assertEqual(10, len(headers_sent.get_block_headers())) for i in range(10): self.assertEqual( block_hashes[i + 10], headers_sent.get_block_headers()[i].hash_object(), ) 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)) def test_handle_tx_with_an_invalid_signature(self): tx_bytes = \ b"\xf8k" \ b"!" \ b"\x85\x0b\xdf\xd6>\x00" \ b"\x82R\x08\x94" \ b"\xf8\x04O\xf8$\xc2\xdc\xe1t\xb4\xee\x9f\x95\x8c*s\x84\x83\x18\x9e" \ b"\x87\t<\xaf\xacj\x80\x00\x80" \ b"!" \ b"\xa0-\xbf,\xa9+\xae\xabJ\x03\xcd\xfa\xe3<\xbf$\x00e\xe2N|\xc9\xf7\xe2\xa9\x9c>\xdfn\x0cO\xc0\x16" \ b"\xa0)\x11K=;\x96X}a\xd5\x00\x06eSz\xd1,\xe4>\xa1\x8c\xf8\x7f>\x0e:\xd1\xcd\x00?'?" result = transaction_validation.validate_transaction( tx_bytes, BlockchainProtocol(self.node.network.protocol.lower()), self.node.get_network_min_transaction_fee() ) self.assertEqual(TxValidationStatus.INVALID_SIGNATURE, result) def test_handle_tx_with_an_invalid_format(self): tx_bytes = \ b"\xf8k" \ b"!" \ b"\x85\x0b\xdf\xd6>\x00\x82R\x08\x94\xf8\x04O\xf8$\xc2\xdc\xe1t\xb4\xee\x9f\x95\x8c*s\x84\x83" \ b"\x18\x9e\x87\t<\xaf\xacj\x80\x00\x80&\xa0-\xbf,\xa9+\xae\xabJ\x03\xcd\xfa\xe3<\xbf$\x00e\xe2N|\xc9" \ b"\xf7\xe2\xa9\x9c>\xdfn\x0cO\xc0\x16" result = transaction_validation.validate_transaction( tx_bytes, BlockchainProtocol(self.node.network.protocol.lower()), self.node.get_network_min_transaction_fee() ) self.assertEqual(TxValidationStatus.INVALID_FORMAT, result) def test_handle_tx_with_low_fee(self): self.node.feed_manager.publish_to_feed = MagicMock() self.node.opts.ws = False tx_bytes = \ b"\xf8k" \ b"!" \ b"\x85\x0b\xdf\xd6>\x00\x82R\x08\x94\xf8\x04O\xf8$\xc2\xdc\xe1t\xb4\xee\x9f\x95\x8c*s\x84\x83" \ b"\x18\x9e\x87\t<\xaf\xacj\x80\x00\x80" \ b"&" \ b"\xa0" \ b"-\xbf,\xa9+\xae\xabJ\x03\xcd\xfa\xe3<\xbf$\x00e\xe2N|\xc9\xf7\xe2\xa9\x9c>\xdfn\x0cO\xc0\x16" \ b"\xa0)\x11K=;\x96X}a\xd5\x00\x06eSz\xd1,\xe4>\xa1\x8c\xf8\x7f>\x0e:\xd1\xcd\x00?'\x15" result = transaction_validation.validate_transaction( tx_bytes, BlockchainProtocol(self.node.network.protocol.lower()), 510000000000 ) self.assertEqual(TxValidationStatus.LOW_FEE, result) def test_complete_header_body_fetch(self): self.node.block_processing_service.queue_block_for_processing = MagicMock() self.node.block_queuing_service_manager.push = MagicMock() self.node.on_block_seen_by_blockchain_node = MagicMock(return_value=False) self.sut.is_valid_block_timestamp = MagicMock(return_value=True) header = mock_eth_messages.get_dummy_block_header(1) block = mock_eth_messages.get_dummy_block(1, header) block_hash = header.hash_object() new_block_hashes_message = NewBlockHashesEthProtocolMessage.from_block_hash_number_pair( block_hash, 1 ) header_message = BlockHeadersEthProtocolMessage(None, [header]) bodies_message = BlockBodiesEthProtocolMessage(None, [TransientBlockBody(block.transactions, block.uncles)]) self.sut.msg_new_block_hashes(new_block_hashes_message) self.node.on_block_seen_by_blockchain_node.assert_called_once() self.assertEqual(1, len(self.sut.pending_new_block_parts.contents)) self.assertEqual(2, len(self.enqueued_messages)) self.node.on_block_seen_by_blockchain_node.reset_mock() self.sut.msg_block_headers(header_message) self.sut.msg_block_bodies(bodies_message) self.node.block_queuing_service_manager.push.assert_called_once() self.node.on_block_seen_by_blockchain_node.assert_called_once() self.node.block_processing_service.queue_block_for_processing.assert_called_once() def test_complete_header_body_fetch_already_seen(self): self.node.block_processing_service.queue_block_for_processing = MagicMock() self.node.block_queuing_service_manager.push = MagicMock() self.node.on_block_seen_by_blockchain_node = MagicMock() self.sut.is_valid_block_timestamp = MagicMock(return_value=True) header = mock_eth_messages.get_dummy_block_header(1) block = mock_eth_messages.get_dummy_block(1, header) block_hash = header.hash_object() new_block_hashes_message = NewBlockHashesEthProtocolMessage.from_block_hash_number_pair( block_hash, 1 ) header_message = BlockHeadersEthProtocolMessage(None, [header]) bodies_message = BlockBodiesEthProtocolMessage(None, [TransientBlockBody(block.transactions, block.uncles)]) self.sut.msg_new_block_hashes(new_block_hashes_message) self.node.on_block_seen_by_blockchain_node.assert_called_once() self.assertEqual(1, len(self.sut.pending_new_block_parts.contents)) self.assertEqual(2, len(self.enqueued_messages)) self.node.on_block_seen_by_blockchain_node.reset_mock() self.node.blocks_seen.add(block_hash) self.sut.msg_block_headers(header_message) self.sut.msg_block_bodies(bodies_message) self.node.block_queuing_service_manager.push.assert_not_called() self.node.on_block_seen_by_blockchain_node.assert_called_once() self.node.block_processing_service.queue_block_for_processing.assert_not_called() def test_complete_header_body_recovery(self): self.node.block_processing_service.queue_block_for_processing = MagicMock() self.node.block_queuing_service_manager.push = MagicMock() self.node.on_block_seen_by_blockchain_node = MagicMock(return_value=False) self.sut.is_valid_block_timestamp = MagicMock(return_value=True) header = mock_eth_messages.get_dummy_block_header(1) block = mock_eth_messages.get_dummy_block(1, header) block_hash = header.hash_object() new_block_hashes_message = NewBlockHashesEthProtocolMessage.from_block_hash_number_pair( block_hash, 1 ) header_message = BlockHeadersEthProtocolMessage(None, [header]) bodies_message = BlockBodiesEthProtocolMessage(None, [TransientBlockBody(block.transactions, block.uncles)]) self.sut.msg_new_block_hashes(new_block_hashes_message) self.node.on_block_seen_by_blockchain_node.assert_called_once() self.assertEqual(1, len(self.sut.pending_new_block_parts.contents)) self.assertEqual(2, len(self.enqueued_messages)) self.node.on_block_seen_by_blockchain_node.reset_mock() self.node.on_block_seen_by_blockchain_node = MagicMock(return_value=True) self.sut.msg_block_headers(header_message) self.sut.msg_block_bodies(bodies_message) self.assertEqual(1, 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_blockchain_node) self.assertEqual(0, stats.new_blocks_received_from_bdn) self.node.on_block_seen_by_blockchain_node.assert_called_once() self.node.block_queuing_service_manager.push.assert_not_called() self.node.block_processing_service.queue_block_for_processing.assert_not_called() def test_header_body_fetch_abort_from_bdn(self): self.node.block_processing_service.queue_block_for_processing = MagicMock() self.sut.is_valid_block_timestamp = MagicMock(return_value=True) header = mock_eth_messages.get_dummy_block_header(1) block = mock_eth_messages.get_dummy_block(1, header) block_hash = header.hash_object() new_block_hashes_message = NewBlockHashesEthProtocolMessage.from_block_hash_number_pair( block_hash, 1 ) header_message = BlockHeadersEthProtocolMessage(None, [header]) bodies_message = BlockBodiesEthProtocolMessage(None, [TransientBlockBody(block.transactions, block.uncles)]) internal_block_info = InternalEthBlockInfo.from_new_block_msg(NewBlockEthProtocolMessage(None, block, 1)) self.sut.msg_new_block_hashes(new_block_hashes_message) self.assertEqual(1, len(self.sut.pending_new_block_parts.contents)) self.assertEqual(2, len(self.enqueued_messages)) self.node.on_block_received_from_bdn(block_hash, internal_block_info) self.sut.msg_block_headers(header_message) self.sut.msg_block_bodies(bodies_message) self.node.block_processing_service.queue_block_for_processing.assert_not_called()
class EthRelayConnectionTest(AbstractTestCase): def setUp(self) -> None: pub_key = "a04f30a45aae413d0ca0f219b4dcb7049857bc3f91a6351288cce603a2c9646294a02b987bf6586b370b2c22d74662355677007a14238bb037aedf41c2d08866" opts = gateway_helpers.get_gateway_opts(8000, pub_key=pub_key) node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE, MagicMock()) self.node = EthGatewayNode(opts, node_ssl_service) self.relay_1 = MockNode( helpers.get_common_opts(8000, region="us-east-1")) self.relay_connection_1 = helpers.create_connection( EthRelayConnection, self.node, node_opts=self.relay_1.opts, file_no=1, ip="1.2.3.4") self.relay_2 = MockNode( helpers.get_common_opts(8001, region="eu-west-1")) self.relay_connection_2 = helpers.create_connection( EthRelayConnection, self.node, node_opts=self.relay_2.opts, file_no=1, ip="1.2.3.5") self.node.broadcast = MagicMock() self.node.has_active_blockchain_peer = MagicMock(return_value=True) 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) 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 test_publish_new_transaction_low_gas(self): bx_tx_message = self._convert_to_bx_message( mock_eth_messages.EIP_155_TRANSACTIONS_MESSAGE) self.node.feed_manager.publish_to_feed = MagicMock() self.node.get_blockchain_network().min_tx_network_fee = ( mock_eth_messages.EIP_155_TRANSACTION_GAS_PRICE + 10) self.relay_connection_1.msg_tx(bx_tx_message) self.node.feed_manager.publish_to_feed.assert_not_called() def test_transaction_updates_filters_based_on_factor(self): self.node.opts.filter_txs_factor = 1 self._set_bc_connection() transactions = [ mock_eth_messages.get_dummy_transaction(i, 10) for i in range(100) ] self.node.on_transactions_in_block(transactions) cheap_tx = self._convert_to_bx_message( TransactionsEthProtocolMessage( None, [mock_eth_messages.get_dummy_transaction(1, 5)])) self.relay_connection_1.msg_tx(cheap_tx) self.node.broadcast.assert_not_called() expensive_tx = self._convert_to_bx_message( TransactionsEthProtocolMessage( None, [mock_eth_messages.get_dummy_transaction(1, 15)])) self.relay_connection_1.msg_tx(expensive_tx) self._assert_tx_sent() def _convert_to_bx_message( self, transactions_eth_msg: TransactionsEthProtocolMessage) -> TxMessage: bx_tx_message, _, _ = self.node.message_converter.tx_to_bx_txs( transactions_eth_msg, 5)[0] return bx_tx_message def _set_bc_connection(self) -> None: self.node.on_connection_added( MockSocketConnection(1, self.node, ip_address=LOCALHOST, port=7000)) self.assertEqual( 1, len( list( self.node.connection_pool.get_by_connection_types( [ConnectionType.BLOCKCHAIN_NODE])))) self.assertEqual(1, len(self.node.blockchain_peers)) blockchain_conn = next( iter( self.node.connection_pool.get_by_connection_types( [ConnectionType.BLOCKCHAIN_NODE]))) self.node.requester.send_threaded_request = MagicMock() self.node.on_blockchain_connection_ready(blockchain_conn) self.assertIsNone(self.node._blockchain_liveliness_alarm) def _assert_tx_sent(self): self.node.broadcast.assert_called_once() calls = self.node.broadcast.call_args_list ((sent_tx_msg, ), connection_info) = calls[0] self.assertIsInstance(sent_tx_msg, TransactionsEthProtocolMessage) connection_types = connection_info["connection_types"] self.assertEqual(len(connection_types), 1) connection_type = connection_types[0] self.assertEqual(connection_type, ConnectionType.BLOCKCHAIN_NODE)
class EthRelayConnectionTest(AbstractTestCase): def setUp(self) -> None: pub_key = "a04f30a45aae413d0ca0f219b4dcb7049857bc3f91a6351288cce603a2c9646294a02b987bf6586b370b2c22d74662355677007a14238bb037aedf41c2d08866" opts = gateway_helpers.get_gateway_opts(8000, pub_key=pub_key) node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE, MagicMock()) self.node = EthGatewayNode(opts, node_ssl_service) self.connection = helpers.create_connection(EthRelayConnection, self.node) self.node.broadcast = MagicMock() self.node.has_active_blockchain_peer = MagicMock(return_value=True) def test_publish_new_transaction(self): bx_tx_message = self._convert_to_bx_message( mock_eth_messages.EIP_155_TRANSACTIONS_MESSAGE) self.node.feed_manager.publish_to_feed = MagicMock() self.connection.msg_tx(bx_tx_message) expected_publication = EthRawTransaction(bx_tx_message.tx_hash(), bx_tx_message.tx_val(), FeedSource.BDN_SOCKET) self.node.feed_manager.publish_to_feed.assert_called_once_with( NewTransactionFeed.NAME, expected_publication) def test_transaction_updates_filters_based_on_factor(self): self.node.opts.filter_txs_factor = 1 self._set_bc_connection() transactions = [ mock_eth_messages.get_dummy_transaction(i, 10) for i in range(100) ] self.node.on_transactions_in_block(transactions) cheap_tx = self._convert_to_bx_message( TransactionsEthProtocolMessage( None, [mock_eth_messages.get_dummy_transaction(1, 5)])) self.connection.msg_tx(cheap_tx) self.node.broadcast.assert_not_called() expensive_tx = self._convert_to_bx_message( TransactionsEthProtocolMessage( None, [mock_eth_messages.get_dummy_transaction(1, 15)])) self.connection.msg_tx(expensive_tx) self.node.broadcast.assert_called_once() def _convert_to_bx_message( self, transactions_eth_msg: TransactionsEthProtocolMessage) -> TxMessage: bx_tx_message, _, _ = self.node.message_converter.tx_to_bx_txs( transactions_eth_msg, 5)[0] return bx_tx_message def _set_bc_connection(self) -> None: self.node.on_connection_added( MockSocketConnection(1, self.node, ip_address=LOCALHOST, port=7000)) self.assertEqual( 1, len( list( self.node.connection_pool.get_by_connection_types( [ConnectionType.BLOCKCHAIN_NODE])))) self.assertEqual(1, len(self.node.blockchain_peers)) blockchain_conn = next( iter( self.node.connection_pool.get_by_connection_types( [ConnectionType.BLOCKCHAIN_NODE]))) self.node.requester.send_threaded_request = MagicMock() self.node.on_blockchain_connection_ready(blockchain_conn) self.assertIsNone(self.node._blockchain_liveliness_alarm)
class GatewaySubscribeRpcRequestTest(AbstractTestCase): @async_test async def setUp(self) -> None: pub_key = "a04f30a45aae413d0ca0f219b4dcb7049857bc3f91a6351288cce603a2c9646294a02b987bf6586b370b2c22d74662355677007a14238bb037aedf41c2d08866" opts = gateway_helpers.get_gateway_opts( 8000, include_default_eth_args=True, pub_key=pub_key, ) if opts.use_extensions: helpers.set_extensions_parallelism() node_ssl_service = MockNodeSSLService(EthGatewayNode.NODE_TYPE, MagicMock()) self.node = EthGatewayNode(opts, node_ssl_service) self.feed_manager = FeedManager(self.node) self.node.feed_manager = self.feed_manager self.rpc = SubscriptionRpcHandler(self.node, self.feed_manager, Case.SNAKE) self.feed_name = NewTransactionFeed.NAME self.node.init_live_feeds() self.feed_service_model = FeedServiceModelBase( allow_filtering=True, available_fields=["all"]) self.base_feed_service_model = BdnFeedServiceModelConfigBase( expire_date="2999-01-01", feed=self.feed_service_model) self.node.account_model = BdnAccountModelBase( account_id="account_id", certificate="", logical_account_name="test", new_transaction_streaming=self.base_feed_service_model, ) @async_test async def tearDown(self) -> None: pass @async_test async def test_subscribe_to_feed_with_no_includes_specified(self): subscribe_request1 = BxJsonRpcRequest( "1", RpcRequestType.SUBSCRIBE, [self.feed_name, {}], ) rpc_handler = self.rpc.get_request_handler(subscribe_request1) result = await rpc_handler.process_request() self.assertTrue(result) @async_test async def test_subscribe_to_feed_with_all_available_fields(self): subscribe_request1 = BxJsonRpcRequest( "1", RpcRequestType.SUBSCRIBE, [ self.feed_name, { "include": ["tx_hash", "tx_contents.gas_price"] } ], ) rpc_handler = self.rpc.get_request_handler(subscribe_request1) result = await rpc_handler.process_request() self.assertTrue(result) @async_test async def test_subscribe_to_feed_with_specific_available_field(self): feed_service_model = FeedServiceModelBase( allow_filtering=True, available_fields=["tx_contents.nonce"]) base_feed_service_model = BdnFeedServiceModelConfigBase( expire_date="2999-01-01", feed=feed_service_model) self.node.account_model.new_transaction_streaming = base_feed_service_model subscribe_request1 = BxJsonRpcRequest( "1", RpcRequestType.SUBSCRIBE, [self.feed_name, { "include": ["tx_contents.nonce"] }], ) rpc_handler = self.rpc.get_request_handler(subscribe_request1) result = await rpc_handler.process_request() self.assertTrue(result) @async_test async def test_subscribe_to_feed_with_unavailable_field(self): feed_service_model = FeedServiceModelBase( allow_filtering=True, available_fields=["tx_hash", "tx_contents.nonce"]) base_feed_service_model = BdnFeedServiceModelConfigBase( expire_date="2999-01-01", feed=feed_service_model) self.node.account_model.new_transaction_streaming = base_feed_service_model subscribe_request1 = BxJsonRpcRequest( "1", RpcRequestType.SUBSCRIBE, [ self.feed_name, { "include": ["tx_hash", "tx_contents.gas_price"] } ], ) with self.assertRaises(RpcInvalidParams): rpc_handler = self.rpc.get_request_handler(subscribe_request1) await rpc_handler.process_request() @async_test async def test_subscribe_to_feed_with_feed_not_set_in_account(self): subscribe_request1 = BxJsonRpcRequest( "1", RpcRequestType.SUBSCRIBE, ["pendingTxs", {}], ) with self.assertRaises(RpcAccountIdError): rpc_handler = self.rpc.get_request_handler(subscribe_request1) await rpc_handler.process_request() @async_test async def test_subscribe_to_feed_no_feed_service(self): # allow feed if service is not defined (old account) self.node.account_model.new_transaction_streaming = BdnFeedServiceModelConfigBase( expire_date="2999-01-01") subscribe_request1 = BxJsonRpcRequest( "1", RpcRequestType.SUBSCRIBE, [self.feed_name, {}], ) subscribe_request2 = BxJsonRpcRequest( "1", RpcRequestType.SUBSCRIBE, [ self.feed_name, { "include": ["tx_hash", "tx_contents.gas_price"] } ], ) rpc_handler = self.rpc.get_request_handler(subscribe_request1) result = await rpc_handler.process_request() self.assertTrue(result) rpc_handler = self.rpc.get_request_handler(subscribe_request2) result = await rpc_handler.process_request() self.assertTrue(result)
def _get_gateway_node(self) -> AbstractGatewayNode: mock_ssl_service = MagicMock() return EthGatewayNode(self.opts, mock_ssl_service)
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"