From 372c36c2b9eff16330b0874958d354c3604907f7 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Date: Wed, 29 Nov 2023 13:16:49 +0200 Subject: [PATCH] lightclient: Fix wasm socket closure called after being dropped (#1289) * lightclient: Close wasm socket while dropping from connecting state Signed-off-by: Alexandru Vasile * lightclient: Construct one time only closures Signed-off-by: Alexandru Vasile * testing: Enable console logs for lightclient WASM testing Signed-off-by: Alexandru Vasile * lightclient: Separate wakes and check connectivity on poll_read Signed-off-by: Alexandru Vasile * lightclient: Close the socket depending on internal state Signed-off-by: Alexandru Vasile * Revert "lightclient: Separate wakes and check connectivity on poll_read" This reverts commit 866094001d4c0b119a80ed681a74b323f74eae1b. * lightclient: Return pending if socket is opening from poll_read Signed-off-by: Alexandru Vasile * lightclient: Close the socket on `poll_close` Signed-off-by: Alexandru Vasile * lightclient: Reset closures on Drop to avoid recursive invokation Signed-off-by: Alexandru Vasile * lightclient: Close the socket if not already closing Signed-off-by: Alexandru Vasile --------- Signed-off-by: Alexandru Vasile --- lightclient/src/platform/wasm_socket.rs | 31 +++++++++++++++----- testing/wasm-lightclient-tests/tests/wasm.rs | 2 ++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/lightclient/src/platform/wasm_socket.rs b/lightclient/src/platform/wasm_socket.rs index 3d212a3506..abe67e7c2d 100644 --- a/lightclient/src/platform/wasm_socket.rs +++ b/lightclient/src/platform/wasm_socket.rs @@ -122,7 +122,7 @@ impl WasmSocket { let error_callback = Closure::::new({ let inner = inner.clone(); - move |_| { + move |_event: web_sys::Event| { // Callback does not provide useful information, signal it back to the stream. let mut inner = inner.lock().expect("Mutex is poised; qed"); inner.state = ConnectionState::Error; @@ -136,7 +136,7 @@ impl WasmSocket { let close_callback = Closure::::new({ let inner = inner.clone(); - move |_| { + move |_event: web_sys::CloseEvent| { let mut inner = inner.lock().expect("Mutex is poised; qed"); inner.state = ConnectionState::Closed; @@ -171,6 +171,10 @@ impl AsyncRead for WasmSocket { let mut inner = self.inner.lock().expect("Mutex is poised; qed"); inner.waker = Some(cx.waker().clone()); + if self.socket.ready_state() == web_sys::WebSocket::CONNECTING { + return Poll::Pending; + } + match inner.state { ConnectionState::Error => { Poll::Ready(Err(io::Error::new(io::ErrorKind::Other, "Socket error"))) @@ -221,17 +225,30 @@ impl AsyncWrite for WasmSocket { Poll::Ready(Ok(())) } - fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { - Poll::Ready(Ok(())) + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + if self.socket.ready_state() == web_sys::WebSocket::CLOSED { + return Poll::Ready(Ok(())); + } + + if self.socket.ready_state() != web_sys::WebSocket::CLOSING { + let _ = self.socket.close(); + } + + let mut inner = self.inner.lock().expect("Mutex is poised; qed"); + inner.waker = Some(cx.waker().clone()); + Poll::Pending } } impl Drop for WasmSocket { fn drop(&mut self) { - let inner = self.inner.lock().expect("Mutex is poised; qed"); - - if inner.state == ConnectionState::Opened { + if self.socket.ready_state() != web_sys::WebSocket::CLOSING { let _ = self.socket.close(); } + + self.socket.set_onopen(None); + self.socket.set_onmessage(None); + self.socket.set_onerror(None); + self.socket.set_onclose(None); } } diff --git a/testing/wasm-lightclient-tests/tests/wasm.rs b/testing/wasm-lightclient-tests/tests/wasm.rs index ed3ee77a70..04018babeb 100644 --- a/testing/wasm-lightclient-tests/tests/wasm.rs +++ b/testing/wasm-lightclient-tests/tests/wasm.rs @@ -32,6 +32,8 @@ wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); #[wasm_bindgen_test] async fn light_client_works() { + console_error_panic_hook::set_once(); + let api: LightClient = LightClientBuilder::new() .build_from_url("wss://rpc.polkadot.io:443") .await