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

feat(connect): dispatch call in progress event - needed for immediate… #14717

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

mroz22
Copy link
Contributor

@mroz22 mroz22 commented Oct 3, 2024

  1. introduce a new connect "call in progress" event
  2. use this event to set suite.locks[device lock] in suite and get rid of the whitelist of wrapped methods. From now on, the lock is set whenever the connect method that is called works with a device and released when this method posts response.

cherry-picked from #14690

@mroz22 mroz22 requested a review from marekrjpolak October 3, 2024 14:37
@mroz22 mroz22 force-pushed the connect-call-progress-event branch 3 times, most recently from a2cb343 to 8da4a49 Compare October 4, 2024 09:50
@@ -45,7 +46,9 @@ export const connectInitThunk = createThunk(
});

TrezorConnect.on(UI_EVENT, ({ event: _, ...action }) => {
// dispatch event as action
if (action.type === 'ui-call_in_progress') {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmmm maybe it should be DEVICE_EVENT 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that DEVICE_EVENT sounds a bit better.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, I thought it's more obvious not to edit Connect events here in connectInitThunks but pass them directly as redux actions whenever possible. So I tried to catch this event in Suite middleware and transform it to SUITE.LOCK_DEVICE there, but then it probably wouldn't work in native, because they don't use the same middlewares? So I'm not sure about that now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, middleware sounds like a place to put it. I just don't like to use middleware if there is only a single use of something. In that case, it feels more readable without it.

🤔 but there are also ui-* device-related events

'ui-device_needs_backup'
'ui-request_passphrase_on_device'
'ui-request_pin'

Copy link
Contributor

Choose a reason for hiding this comment

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

I just don't like to use middleware if there is only a single use of something

Yes, I agree, that's why my first idea was to directly replace SUITE.LOCK_DEVICE with UI.CALL_IN_PROGRESS everywhere. But that would be a bigger change.

@mroz22
Copy link
Contributor Author

mroz22 commented Oct 7, 2024

not finished, to be discussed, I'd like to nominate @marekrjpolak 🎖️

Comment on lines 520 to 538
sendCoreMessage(createUiMessage(UI.CALL_IN_PROGRESS, { value: true }));

try {
return await onCallDevice(context, message, method);
} finally {
sendCoreMessage(createUiMessage(UI.CALL_IN_PROGRESS, { value: false }));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe that the lock should be removed at all cases, even when the method throws or returns prematurely. So I proposed a fixup.

Comment on lines 82 to 84
if (selectIsDeviceLocked(getState())) {
return await synchronize(() => original(params));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm afraid this won't work as expected. When the first locking call is executed, there's no device lock yet so it would be out of synchronize() and the next call in synchronize() will run in parallel.

There should be something like when locked is true, wait until locked is false and go? But when you accidentally start two methods at once, you're still fucked.

Maybe, if we want the lock to be unpenetrable, it has to be defined at the same place as consumed? Meaning that if you want to await the lock from Connect in Suite, it will always be prone to race condition?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds right. Maybe I can sort of go back to the previous behaviour, but still more robust simply by defining a new utility method on connect, something like

TrezorConnect.getMethods

Which would return method details, in this case I would be interested in all methods that have method.useDevice=true and create a wrapper for them.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, that would be an improvement.

And why do we even need these locks on Suite side? If it is impossible to do two calls in parallel because of Connect, shouldn't Connect handle it? Maybe we can add a new general method param, something like allowQueue, which will cause synchronization on Connect's side instead of throwing call in progress?

@@ -45,7 +46,9 @@ export const connectInitThunk = createThunk(
});

TrezorConnect.on(UI_EVENT, ({ event: _, ...action }) => {
// dispatch event as action
if (action.type === 'ui-call_in_progress') {
Copy link
Contributor

Choose a reason for hiding this comment

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

Also, I thought it's more obvious not to edit Connect events here in connectInitThunks but pass them directly as redux actions whenever possible. So I tried to catch this event in Suite middleware and transform it to SUITE.LOCK_DEVICE there, but then it probably wouldn't work in native, because they don't use the same middlewares? So I'm not sure about that now.

@mroz22 mroz22 force-pushed the connect-call-progress-event branch from 4a7866d to f4fa8b0 Compare October 21, 2024 13:52
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.

2 participants