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

Synchronously update transaction status #8563

Merged
merged 1 commit into from
May 9, 2020

Conversation

Gudahtt
Copy link
Member

@Gudahtt Gudahtt commented May 9, 2020

All transaction status updates were moved into a setTimeout callback and wrapped in a try...catch block in #4131, apparently in an attempt to prevent failures in event subscribers from interrupting the transaction logic. The try...catch block did accomplish that, but by putting the status update in a setTimeout callback the operation was made asynchronous.

Transaction status updates now happen unpredictably, in some future event loop from when they're triggered. This creates a race condition, where the transaction status update may occur before or after subsequent state changes. This also introduces a risk of accidentally undoing a change to the transaction state, as the update made to the transaction inside the setTimeout callback uses a reference to txMeta obtained synchronously before the setTimeout call. Any replacement of the txMeta between the setTxStatus call and the execution of the timeout would be erased. Luckily the txMeta object is more often than not mutated rather than replaced, which may explain why we haven't seen this happen yet.

Everything seems to work correctly with the setTimeout call removed, and now the transaction logic is easier to understand.

@Gudahtt Gudahtt requested a review from a team as a code owner May 9, 2020 03:47
All transaction status updates were moved into a `setTimeout` callback
and wrapped in a `try...catch` block in #4131, apparently in an attempt
to prevent failures in event subscribers from interrupting the
transaction logic. The `try...catch` block did accomplish that, but by
putting the status update in a `setTimeout` callback the operation was
made asynchronous.

Transaction status updates now happen unpredictably, in some future
event loop from when they're triggered. This creates a race condition,
where the transaction status update may occur before or after
subsequent state changes. This also introduces a risk of accidentally
undoing a change to the transaction state, as the update made to the
transaction inside the `setTimeout` callback uses a reference to
`txMeta` obtained synchronously before the `setTimeout` call. Any
replacement of the `txMeta` between the `setTxStatus` call and the
execution of the timeout would be erased. Luckily the `txMeta` object
is more often than not mutated rather than replaced, which may explain
why we haven't seen this happen yet.

Everything seems to work correctly with the `setTimeout` call removed,
and now the transaction logic is easier to understand.
@Gudahtt Gudahtt force-pushed the synchronously-update-transaction-state branch from 61b1fd2 to 8234d5e Compare May 9, 2020 03:50
Copy link
Contributor

@brad-decker brad-decker left a comment

Choose a reason for hiding this comment

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

Noice, Does this make the logic we discussed in slack more reliable vis-a-vis the nonce sorted list being dependant on the first tx to be resolved before the second tx can be processed? Thus making a sort of 'queue' terminology or ux pattern appropriate?

@Gudahtt
Copy link
Member Author

Gudahtt commented May 9, 2020

This was the result of the investigation I did in attempting to answer that question 😅 . I don't think this changes anything regarding the transaction list UI - both before and after this change, the queue UX pattern was appropriate. But the logic should be easier to follow now - this should ensure that if the transaction has a nonce, it must have been approved as well (previously it may have been given a nonce first, before being set to approved). it might also prevent some bug that I'm not aware of, e.g. a transaction getting into an invalid state. I plan on doing more investigation later into what problems this may have caused - I didn't find any bugs yet, but I haven't yet looked very hard.

@metamaskbot
Copy link
Collaborator

Builds ready [8234d5e]
Page Load Metrics (680 ± 29 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint318039115
domContentLoaded6108116796029
load6128136806029
domInteractive6108116785929

Copy link
Contributor

@whymarrh whymarrh left a comment

Choose a reason for hiding this comment

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

It’s also worth noting that #4131 was before “safe-event-emitter” as well 🤦🏽‍♂️

@Gudahtt Gudahtt merged commit 9c06b07 into develop May 9, 2020
@Gudahtt Gudahtt deleted the synchronously-update-transaction-state branch May 9, 2020 13:47
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