Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem: walletconnnect requests would not be cleared if no response (fix #302) #303

Merged
merged 8 commits into from
Dec 12, 2022

Conversation

damoncro
Copy link
Contributor

@damoncro damoncro commented Dec 8, 2022

Close:

Solution:

  • Add pending_requests_timeout and pending_requests_limit

👮🏻👮🏻👮🏻 !!!! REFERENCE THE PROBLEM YOUR ARE SOLVING IN THE PR TITLE AND DESCRIBE YOUR SOLUTION HERE !!!! DO NOT FORGET !!!! 👮🏻👮🏻👮🏻

PR Checklist:

  • Have you read the CONTRIBUTING.md?
  • Does your PR follow the C4 patch requirements?
  • Have you rebased your work on top of the latest main?
  • Have you checked your code compiles? (cargo build)
  • Have you included tests for any non-trivial functionality?
  • Have you checked your code passes the unit tests? (cargo test)
  • Have you checked your code formatting is correct? (cargo fmt -- --check --color=auto)
  • Have you checked your basic code style is fine? (cargo clippy)
  • If you added any dependencies, have you checked they do not contain any known vulnerabilities? (cargo audit)
  • If your changes affect public APIs, does your PR follow the C4 evolution of public contracts?
  • If your code changes public APIs, have you incremented the crate version numbers and documented your changes in the CHANGELOG.md?
  • If you are contributing for the first time, please read the agreement in CONTRIBUTING.md now and add a comment to this pull request stating that your PR is in accordance with the Developer's Certificate of Origin.

Thank you for your code, it's appreciated! :)

@damoncro
Copy link
Contributor Author

damoncro commented Dec 8, 2022

Unreal test logs:

LogBlueprintUserMessages: [ConnectWalletConnect_C_0] 
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] PlayCppSdk SignPersonal Error: sign_personal error Reached the limit (2) pending requests, please clear all pending requests before making new requests
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] 
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] PlayCppSdk SignPersonal Error: sign_personal error Reached the limit (2) pending requests, please clear all pending requests before making new requests
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] 
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] PlayCppSdk SignPersonal Error: sign_personal error Reached the limit (2) pending requests, please clear all pending requests before making new requests
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] 
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] PlayCppSdk SignPersonal Error: sign_personal error Reached the limit (2) pending requests, please clear all pending requests before making new requests
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] 
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] PlayCppSdk SignPersonal Error: sign_personal error Reached the limit (2) pending requests, please clear all pending requests before making new requests
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] 
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] PlayCppSdk SignPersonal Error: sign_personal error Reached the limit (2) pending requests, please clear all pending requests before making new requests
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] 
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] PlayCppSdk SignPersonal Error: sign_personal error Reached the limit (2) pending requests, please clear all pending requests before making new requests
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] 
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] PlayCppSdk SignPersonal Error: sign_personal error Reached the limit (2) pending requests, please clear all pending requests before making new requests
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] 
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] PlayCppSdk SignPersonal Error: sign_personal error Reached the limit (2) pending requests, please clear all pending requests before making new requests
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] 
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] PlayCppSdk SignPersonal Error: sign_personal error Reached the limit (2) pending requests, please clear all pending requests before making new requests
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] 
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] PlayCppSdk SignPersonal Error: sign_personal error Reached the limit (2) pending requests, please clear all pending requests before making new requests
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] 
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] PlayCppSdk SignPersonal Error: sign_personal error Reached the limit (2) pending requests, please clear all pending requests before making new requests
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] C1E3555516984B53C275264AE159CCC5804279D9DEA0C6CA9DBA80DDE993C8CA3016665687A30FB6FDB8B99B54DBC48AB39D0DE22A9D721B0C2D059B7115E9FD1C
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] 
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] 
LogBlueprintUserMessages: [ConnectWalletConnect_C_0] PlayCppSdk SignEip155Transaction Error: sign_typed_transaction error client error: channel closed

Copy link
Contributor

@tomtau tomtau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't read the original code in a while and feel a bit sick today. the patch looks ok, but can't confirm for 100%

@codecov-commenter
Copy link

codecov-commenter commented Dec 8, 2022

Codecov Report

Merging #303 (d3979dc) into main (9998589) will decrease coverage by 0.32%.
The diff coverage is 0.00%.

@@            Coverage Diff             @@
##             main     #303      +/-   ##
==========================================
- Coverage   25.59%   25.27%   -0.33%     
==========================================
  Files          20       20              
  Lines        2188     2216      +28     
==========================================
  Hits          560      560              
- Misses       1628     1656      +28     
Impacted Files Coverage Δ
wallet-connect/src/client/core.rs 8.65% <0.00%> (-0.17%) ⬇️
wallet-connect/src/client/socket.rs 0.00% <0.00%> (ø)

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@damoncro damoncro changed the title Problem: walletconnnect requests would not be cleared if no response fix (#302) Problem: walletconnnect requests would not be cleared if no response (fix #302) Dec 8, 2022
@leejw51crypto
Copy link
Collaborator

leejw51crypto commented Dec 8, 2022

  • if blocking is 10 minutes, how can it be stopped?
  • it's sleeping for the duration, when user successfully finished signing, how sleeping thread stopped?

@damoncro
Copy link
Contributor Author

damoncro commented Dec 8, 2022

  • if blocking is 10 minutes, how can it be stopped?
  • it's sleeping for the duration, when user successfully finished signing, how sleeping thread stopped?

It is hardcoded as 1 minute. What operations could be 10 minutes?

@damoncro
Copy link
Contributor Author

damoncro commented Dec 8, 2022

  • if blocking is 10 minutes, how can it be stopped?
  • it's sleeping for the duration, when user successfully finished signing, how sleeping thread stopped?

The clear thread would not stop, if succeeded, pending_requests would be removed on the normal thread, while on the clear thread, calling remove on pending_reqeusts would return None. Nothing would happen.

@leejw51crypto
Copy link
Collaborator

ok

@leejw51crypto
Copy link
Collaborator

instead sleep,
how about polling with 1 second interval?
while for maxium waitiing time
{
// check pending task
// if it's done
// exit, finisht thread
}
// do current

@leejw51crypto
Copy link
Collaborator

because, it waits let's say 1 minute sleep,
spawing thread can be too many

@damoncro
Copy link
Contributor Author

damoncro commented Dec 9, 2022

instead sleep, how about polling with 1 second interval? while for maxium waitiing time { // check pending task // if it's done // exit, finisht thread } // do current

It is a different purpose. This PR is about cleaning up the pending request no matter it is valid or not, after timeout, to handle no response case (thread may never end if we only query it and wait it to end).

@damoncro
Copy link
Contributor Author

damoncro commented Dec 9, 2022

because, it waits let's say 1 minute sleep, spawing thread can be too many

Spawning would not be too many, it has pending_requests_limit which is 2, only 2 at most is permitted. If 3 or more, game will halt, as I reported on the issue.

@leejw51crypto
Copy link
Collaborator

leejw51crypto commented Dec 9, 2022

socket sender is changed to bounded, but it can cause waiting , if there are multiple requests.
how about using unbounded channel, and check count beforehand,
return false?

@leejw51crypto
Copy link
Collaborator

and

                    (Ok(_), Some(id)) => {
                        // clean up pending request after timeout
                        let _ = tokio::spawn(async move {

if signing is done fast, how this async finishes?

@damoncro
Copy link
Contributor Author

damoncro commented Dec 9, 2022

socket sender is changed to bounded, but it can cause waiting , if there are multiple requests. how about using unbounded channel, and check count beforehand, return false?

Bound is enough, and more performant, bounded buffer size is defined by pending_requests_limit. As only 2 requests
at most are permitted, it is not necessary to use unbounded.

@leejw51crypto
Copy link
Collaborator

leejw51crypto commented Dec 9, 2022

yes, if called , 3 times, 3rd connect will keep waiting until it can send.

and socket.rs 258 line

(Ok(_), Some(id)) => {
                        // clean up pending request after timeout
                        let _ = tokio::spawn(async move {
                            let context = context.clone();                            sleep(Duration::from_millis(context.pending_requests_timeout)).await;   

this will be alive , no matter succeed or not, for pending_requests_timeout time

so this can cause dead-lock in application side.

@damoncro
Copy link
Contributor Author

damoncro commented Dec 9, 2022

and

                    (Ok(_), Some(id)) => {
                        // clean up pending request after timeout
                        let _ = tokio::spawn(async move {

if signing is done fast, how this async finishes?

It will still run, after timeout, it would return None. Since the corresponding request of that id is already removed, please check https://github.com/cronos-labs/play-cpp-sdk/blob/main/wallet-connect/src/client/socket.rs#L54

@leejw51crypto
Copy link
Collaborator

yes, it's already removed at the stage.
but it will wait anyway for that time whether finished or not.

@damoncro
Copy link
Contributor Author

damoncro commented Dec 9, 2022

yes, it's already removed at the stage. but it will wait anyway for that time whether finished or not.

Let me check if close the timeout thread if got response.

@leejw51crypto
Copy link
Collaborator

ok, i'll read more.
i'm looking into any side-effect

@damoncro
Copy link
Contributor Author

damoncro commented Dec 9, 2022

yes, if called , 3 times, 3rd connect will keep waiting until it can send.

This would not happen. Since https://github.com/cronos-labs/play-cpp-sdk/pull/303/files#diff-0fb0fbb1ca52eaa6fa7aa5c4b0958e9b85d6907737ac1fd25c1e48ce90205691R126 already limit it to at most 2. Please see the example and verify.

Besides, deadlock would not happen since no mutex is used here.

@damoncro
Copy link
Contributor Author

damoncro commented Dec 9, 2022

yes, it's already removed at the stage. but it will wait anyway for that time whether finished or not.

I agree with this, the timeout thread should be closed if got response. Let me do this.

@damoncro damoncro marked this pull request as draft December 9, 2022 04:34
fix (cronos-labs#302)

Close:
- cronos-labs#302

Solution:
- Add pending_requests_timeout and pending_requests_limit
- Use channel instead of unbounded_channel to improve performance
@damoncro damoncro force-pushed the bug/wc_request_do_not_clear branch from fc848e1 to 94b8593 Compare December 9, 2022 10:25
@damoncro damoncro marked this pull request as ready for review December 12, 2022 04:40
@damoncro
Copy link
Contributor Author

damoncro commented Dec 12, 2022

https://github.com/cronos-labs/play-cpp-sdk/blob/main/wallet-connect/src/client/socket.rs#L182
In create_session, I guess, we may not need to make it timeout? @leejw51crypto @tomtau

Or we could make the timeout long, long enough to let the user finish the first connection? Or make a new QR expired timeout for user to configure?

@tomtau
Copy link
Contributor

tomtau commented Dec 12, 2022

https://github.com/cronos-labs/play-cpp-sdk/blob/main/wallet-connect/src/client/socket.rs#L182 In create_session, I guess, we may not need to make it timeout? @leejw51crypto @tomtau

Or we could make the timeout long, long enough to let the user finish the first connection? Or make a new QR expired timeout for user to configure?

maybe easiest not to timeout? one can still try to recreate/restart if it fails?

Copy link
Contributor

@tomtau tomtau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quite simple and nice with the timeout... just a nit that duration could just be stored in the struct directly

@leejw51crypto
Copy link
Collaborator

make 60000 as definition

Copy link
Collaborator

@leejw51crypto leejw51crypto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@leejw51crypto
Copy link
Collaborator

i think current approach is simplest

@leejw51crypto leejw51crypto merged commit 495e0cc into cronos-labs:main Dec 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants