diff --git a/test/functional/abc-invalid-message.py b/test/functional/abc-invalid-message.py --- a/test/functional/abc-invalid-message.py +++ b/test/functional/abc-invalid-message.py @@ -23,7 +23,7 @@ def msg_bad_checksum(connection, original_message): - message_data = bytearray(connection.format_message(original_message)) + message_data = bytearray(connection._build_message(original_message)) data = original_message.serialize() i = 0 @@ -48,7 +48,8 @@ vt.addrFrom.ip = "0.0.0.0" vt.addrFrom.port = 0 invalid_vt = msg_bad_checksum(self, vt) - self.send_raw_message(invalid_vt, True) + # Will be sent right after handle_connect + self.sendbuf = invalid_vt class InvalidMessageTest(BitcoinTestFramework): diff --git a/test/functional/feature_assumevalid.py b/test/functional/feature_assumevalid.py --- a/test/functional/feature_assumevalid.py +++ b/test/functional/feature_assumevalid.py @@ -75,12 +75,12 @@ def send_blocks_until_disconnected(self, p2p_conn): """Keep sending blocks to the node until we're disconnected.""" for i in range(len(self.blocks)): - if p2p_conn.state != "connected": + if not p2p_conn.is_connected: break try: p2p_conn.send_message(msg_block(self.blocks[i])) - except IOError as e: - assert str(e) == 'Not connected, no pushbuf' + except IOError: + assert not p2p_conn.is_connected break def assert_blockchain_height(self, node, height): diff --git a/test/functional/p2p_compactblocks.py b/test/functional/p2p_compactblocks.py --- a/test/functional/p2p_compactblocks.py +++ b/test/functional/p2p_compactblocks.py @@ -126,7 +126,7 @@ This is used when we want to send a message into the node that we expect will get us disconnected, eg an invalid block.""" self.send_message(message) - wait_until(lambda: self.state != "connected", + wait_until(lambda: not self.is_connected, timeout=timeout, lock=mininode_lock) diff --git a/test/functional/p2p_leak.py b/test/functional/p2p_leak.py --- a/test/functional/p2p_leak.py +++ b/test/functional/p2p_leak.py @@ -158,7 +158,7 @@ time.sleep(5) # This node should have been banned - assert no_version_bannode.state != "connected" + assert not no_version_bannode.is_connected self.nodes[0].disconnect_p2ps() diff --git a/test/functional/p2p_timeouts.py b/test/functional/p2p_timeouts.py --- a/test/functional/p2p_timeouts.py +++ b/test/functional/p2p_timeouts.py @@ -51,9 +51,9 @@ sleep(1) - assert no_verack_node.connected - assert no_version_node.connected - assert no_send_node.connected + assert no_verack_node.is_connected + assert no_version_node.is_connected + assert no_send_node.is_connected no_verack_node.send_message(msg_ping()) no_version_node.send_message(msg_ping()) @@ -62,18 +62,18 @@ assert "version" in no_verack_node.last_message - assert no_verack_node.connected - assert no_version_node.connected - assert no_send_node.connected + assert no_verack_node.is_connected + assert no_version_node.is_connected + assert no_send_node.is_connected no_verack_node.send_message(msg_ping()) no_version_node.send_message(msg_ping()) sleep(31) - assert not no_verack_node.connected - assert not no_version_node.connected - assert not no_send_node.connected + assert not no_verack_node.is_connected + assert not no_version_node.is_connected + assert not no_send_node.is_connected if __name__ == '__main__': diff --git a/test/functional/test_framework/mininode.py b/test/functional/test_framework/mininode.py --- a/test/functional/test_framework/mininode.py +++ b/test/functional/test_framework/mininode.py @@ -110,6 +110,12 @@ super().__init__(map=mininode_socket_map) + self._conn_open = False + + @property + def is_connected(self): + return self._conn_open + def peer_connect(self, dstaddr, dstport, net="regtest"): self.dstaddr = dstaddr self.dstport = dstport @@ -117,7 +123,7 @@ self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) self.sendbuf = b"" self.recvbuf = b"" - self.state = "connecting" + self._asyncore_pre_connection = True self.network = net self.disconnect = False @@ -131,24 +137,26 @@ def peer_disconnect(self): # Connection could have already been closed by other end. - if self.state == "connected": - self.disconnect_node() + if self.is_connected: + # Signal asyncore to disconnect + self.disconnect = True # Connection and disconnection methods def handle_connect(self): """asyncore callback when a connection is opened.""" - if self.state != "connected": + if not self.is_connected: logger.debug("Connected & Listening: {}:{}".format( self.dstaddr, self.dstport)) - self.state = "connected" + self._conn_open = True + self._asyncore_pre_connection = False self.on_open() def handle_close(self): """asyncore callback when a connection is closed.""" logger.debug("Closing connection to: {}:{}".format( self.dstaddr, self.dstport)) - self.state = "closed" + self._conn_open = False self.recvbuf = b"" self.sendbuf = b"" try: @@ -157,13 +165,6 @@ pass self.on_close() - def disconnect_node(self): - """Disconnect the p2p connection. - - Called by the test logic thread. Causes the p2p connection - to be disconnected on the next iteration of the asyncore loop.""" - self.disconnect = True - # Socket read methods def handle_read(self): @@ -225,9 +226,8 @@ def writable(self): """asyncore method to determine whether the handle_write() callback should be called on the next loop.""" with mininode_lock: - pre_connection = self.state == "connecting" length = len(self.sendbuf) - return (length > 0 or pre_connection) + return length > 0 or self._asyncore_pre_connection def handle_write(self): """asyncore callback when data should be written to the socket.""" @@ -235,7 +235,7 @@ # asyncore does not expose socket connection, only the first read/write # event, thus we must check connection manually here to know when we # actually connect - if self.state == "connecting": + if self._asyncore_pre_connection: self.handle_connect() if not self.writable(): return @@ -247,39 +247,26 @@ return self.sendbuf = self.sendbuf[sent:] - def format_message(self, message): - command = message.command - data = message.serialize() - tmsg = MAGIC_BYTES[self.network] - tmsg += command - tmsg += b"\x00" * (12 - len(command)) - tmsg += struct.pack("