diff --git a/libp2p/network/connection/raw_connection.py b/libp2p/network/connection/raw_connection.py index 4ad9eff3..25211c88 100644 --- a/libp2p/network/connection/raw_connection.py +++ b/libp2p/network/connection/raw_connection.py @@ -26,10 +26,11 @@ class RawConnection(IRawConnection): async def write(self, data: bytes) -> None: """Raise `RawConnError` if the underlying connection breaks.""" - try: - self.writer.write(data) - except ConnectionResetError as error: - raise RawConnError() from error + # Detect if underlying transport is closing before write data to it + # ref: https://github.com/ethereum/trinity/pull/614 + if self.writer.transport.is_closing(): + raise RawConnError("Transport is closing") + self.writer.write(data) # Reference: https://github.com/ethereum/lahja/blob/93610b2eb46969ff1797e0748c7ac2595e130aef/lahja/asyncio/endpoint.py#L99-L102 # noqa: E501 # Use a lock to serialize drain() calls. Circumvents this bug: # https://bugs.python.org/issue29930 @@ -52,7 +53,13 @@ class RawConnection(IRawConnection): raise RawConnError() from error async def close(self) -> None: + if self.writer.transport.is_closing(): + return self.writer.close() if sys.version_info < (3, 7): return - await self.writer.wait_closed() + try: + await self.writer.wait_closed() + # In case the connection is already reset. + except ConnectionResetError: + return diff --git a/setup.py b/setup.py index 356487a8..2d0b6f35 100644 --- a/setup.py +++ b/setup.py @@ -66,7 +66,7 @@ install_requires = [ "pycryptodome>=3.9.2,<4.0.0", "base58>=1.0.3,<2.0.0", "pymultihash>=0.8.2", - "multiaddr>=0.0.8,<0.1.0", + "multiaddr>=0.0.9,<0.1.0", "rpcudp>=3.0.0,<4.0.0", "lru-dict>=1.1.6", "protobuf>=3.10.0,<4.0.0",