async def test_processing_messages(self): settings.network.magic = 769 socket_mock = NeoNodeSocketMock(self.loop, '127.0.0.1', 1111) m_addr = message.Message(msg_type=message.MessageType.ADDR, payload=payloads.AddrPayload([])) m_block = message.Message(msg_type=message.MessageType.BLOCK, payload=payloads.EmptyPayload()) m_inv1 = message.Message(msg_type=message.MessageType.INV, payload=payloads.InventoryPayload( payloads.InventoryType.BLOCK, hashes=[types.UInt256.from_string("65793a030c0dcd4fff4da8a6a6d5daa8b570750da4fdeea1bbc43bdf124aedc9")] )) m_inv2 = message.Message(msg_type=message.MessageType.INV, payload=payloads.InventoryPayload(payloads.InventoryType.TX, [])) m_getaddr = message.Message(msg_type=message.MessageType.GETADDR, payload=payloads.EmptyPayload()) m_mempool = message.Message(msg_type=message.MessageType.MEMPOOL, payload=payloads.EmptyPayload()) # taken from the Headers testcase in `test_payloads` raw_headers_payload = binascii.unhexlify(b'0000000001FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00A402FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00A400000000000000007B00000000F7B4D00143932F3B6243CFC06CB4A68F22C739E201020102020304') m_headers = message.Message(msg_type=message.MessageType.HEADERS, payload=payloads.HeadersPayload.deserialize_from_bytes(raw_headers_payload)) m_ping = message.Message(msg_type=message.MessageType.PING, payload=payloads.PingPayload(0)) m_pong = message.Message(msg_type=message.MessageType.PONG, payload=payloads.PingPayload(0)) m_reject = message.Message(msg_type=message.MessageType.REJECT, payload=payloads.EmptyPayload()) def _recv_data2(self): # first do handshake yield self.m_send_version.to_array() yield self.m_verack.to_array() # next send all types of messages we handle yield m_addr.to_array() yield m_block.to_array() yield m_inv1.to_array() yield m_inv2.to_array() yield m_getaddr.to_array() yield m_mempool.to_array() yield m_headers.to_array() yield m_ping.to_array() yield m_pong.to_array() yield m_reject.to_array() socket_mock.recv_data = _recv_data2(socket_mock) with self.assertLogs(network_logger, 'DEBUG') as log_context: try: n, _ = await node.NeoNode.connect_to(socket=socket_mock) except Exception as e: print(f"GVD {e}") await asyncio.sleep(0.5) await n.disconnect(payloads.DisconnectReason.SHUTTING_DOWN)
async def test_processing_messages3(self): # we got 2 cases for which we need to test without using a backend settings.network.magic = 769 settings.storage.use_default = False socket_mock = NeoNodeSocketMock(self.loop, '127.0.0.1', 1111) m_inv1 = message.Message( msg_type=message.MessageType.INV, payload=payloads.InventoryPayload( payloads.InventoryType.BLOCK, hashes=[ types.UInt256.from_string( "65793a030c0dcd4fff4da8a6a6d5daa8b570750da4fdeea1bbc43bdf124aedc9" ) ])) m_ping = message.Message(msg_type=message.MessageType.PING, payload=payloads.PingPayload(0)) def _recv_data2(self): print("my recv data 2 called ") # first do handshake yield self.m_send_version.to_array() yield self.m_verack.to_array() yield m_inv1.to_array() yield m_ping.to_array() socket_mock.recv_data = _recv_data2(socket_mock) with self.assertLogs(network_logger, 'DEBUG') as log_context: with mock.patch('neo3.network.node.NeoNode.send_message', new_callable=asynctest.CoroutineMock): # with asynctest.patch('neo3.network.node.NeoNode.send_message', return_value=asynctest.CoroutineMock()): n, _ = await node.NeoNode.connect_to(socket=socket_mock) await asyncio.sleep(0.1) await n.disconnect(payloads.DisconnectReason.SHUTTING_DOWN)
async def _monitor_node_height(self) -> None: now = datetime.utcnow().timestamp() for node in self.nodes: if now - node.best_height_last_update > self.MAX_HEIGHT_UPDATE_DURATION: logger.debug( f"Disconnecting node {node.nodeid} Reason: max height update threshold exceeded." ) asyncio.create_task( node.disconnect( reason=payloads.DisconnectReason.POOR_PERFORMANCE)) else: logger.debug( f"Asking node {node.nodeid_human} to send us a height update (PING)" ) # Request latest height from node if settings.database: height = max(0, blockchain.Blockchain().height) else: height = 0 m = message.Message( msg_type=message.MessageType.PING, payload=payloads.PingPayload(height=height)) task = asyncio.create_task(node.send_message(m)) self.tasks.append(task) task.add_done_callback(lambda fut: self.tasks.remove(fut))
async def send_ping(self): if settings.database: height = max(0, blockchain.Blockchain().height) else: height = 0 ping = payloads.PingPayload(height) m = message.Message(msg_type=message.MessageType.PING, payload=ping) await self.send_message(m)
def handler_ping(self, msg: message.Message) -> None: """ Handler for a message with the PING type. Args: msg: """ if settings.database: height = max(0, blockchain.Blockchain().height) else: height = 0 m = message.Message(msg_type=message.MessageType.PONG, payload=payloads.PingPayload(height=height)) self._create_task_with_cleanup(self.send_message(m))
def handler_inv(self, msg: message.Message) -> None: """ Handler for a message with the INV type. Args: msg: """ payload = cast(payloads.InventoryPayload, msg.payload) if payload.type == payloads.InventoryType.BLOCK: # neo-cli broadcasts INV messages on a regular interval. We can use those as trigger to request # their latest block height if len(payload.hashes) > 0: if settings.database: height = max(0, blockchain.Blockchain().height) else: height = 0 m = message.Message( msg_type=message.MessageType.PING, payload=payloads.PingPayload(height=height)) self._create_task_with_cleanup(self.send_message(m)) else: logger.debug( f"Message with type INV received. No processing for payload type " # type:ignore f"{payload.type.name} implemented")