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

fix splitting of transaction nonce groups in state #11103

Merged
merged 4 commits into from
May 17, 2021

Conversation

brad-decker
Copy link
Contributor

@brad-decker brad-decker commented May 14, 2021

Fixes: #11069

Explanation:
The tx-state-manager has always deleted the oldest "finalized" transaction from the state after the limit (default is 50), this is erroneous and can lead to UI issues when you split a cancel transaction away from the transaction that it was canceling and other various edge cases.

This change makes sure we remove entire groups of transactions after we hit a limit. This will result in a number greater than 50 transactions being possible, if large groups of transactions occur. Grouping is done by nonce by network, but only the ${limit} most recent unique nonces are considered.

@brad-decker brad-decker force-pushed the fix-splitting-of-transaction-groups branch from 8d885f5 to 531a804 Compare May 14, 2021 20:38
@metamaskbot
Copy link
Collaborator

Builds ready [531a804]
Page Load Metrics (587 ± 47 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint438062105
domContentLoaded3867185869747
load3877195879747
domInteractive3867185869747

@brad-decker brad-decker marked this pull request as ready for review May 14, 2021 21:13
@brad-decker brad-decker requested a review from a team as a code owner May 14, 2021 21:13
@brad-decker brad-decker requested a review from danjm May 14, 2021 21:13
this._deleteTransaction(transactions[index].id);
}
}
const nonceNetworkSet = new Set();
Copy link
Contributor

Choose a reason for hiding this comment

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

I want to make sure I understand this.

So the goal is to ensure that if there are two or more transactions with the same nonce in the transaction list, that they don't get deleted.

So we iterate through the transactions. If a transaction is either counted as below txHistoryLimit - 1 or is not in a final state, then it is NOT deleted. If a transaction is counted higher than txHistoryLimit - 1 or is in a final state BUT has the same nonce as a transaction already flagged as one that shouldn't be deleted, then it is NOT deleted. If a transaction is above the txHistoryLimit count or is in a final state and does not match the nonce of a transaction already identified as one that shouldn't be deleted, then it is deleted...

So something about this isn't adding up for me... probably me misunderstanding, but I want to check.

Suppose that there are only 10 transactions and they are all "final states". Wouldn't they all be deleted according to this logic?

Should the if (txCount > txHistoryLimit - 1) { that was removed above wrap this tx deletion code?

And this is in a function that only adds a single tx. Before it only removed a single tx. Why now attempt to remove multiple within this function?

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe I forget how filter works...

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe not

Copy link
Contributor

Choose a reason for hiding this comment

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

Based on my reading of the tests I think I did misunderstand the goal though

Copy link
Contributor

Choose a reason for hiding this comment

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

Can the purpose of this code change be stated as:

If the addition of a transaction brings the transaction count above the txHistoryLimit then all transactions that share a nonce with the oldest "finalized" transaction should be deleted.

?

Copy link
Member

Choose a reason for hiding this comment

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

So the goal is to ensure that if there are two or more transactions with the same nonce in the transaction list, that they don't get deleted.

It's to ensure that one transaction in a group isn't deleted without deleting the entire group.

We can't let all groups of more than 1 transaction persist indefinitely - then we'd have no limit on storage. But we can't break groups apart either without breaking the UI.

So the solution we went with here was to interpret the transaction history limit of 50 as meaning 50 groups of transactions. If there are over 50 groups, we delete any groups beyond that 50 (which should always be a single group if this is the only means of adding transactions, but might be more than 1 group if transactions are added elsewhere).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

when we return false from this method we are Not including it, when we return true we are including it. So when return true we are saying "this is an item we want to delete". if there are only ten transactions non will be deleted because they will never hit the limit and thus will all be added to the nonceSet

Copy link
Contributor Author

Choose a reason for hiding this comment

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

basically yes as stated that will work

// following cancel transaction with the same nonce. these two transactions should be dropped
// together as soon as the 11th unique nonce is attempted to be added, mocked here with limit + 1
const txs = generateTransactions(limit + 1, {
chainId: currentChainId,
Copy link
Contributor

Choose a reason for hiding this comment

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

should the nonce method param be defined here, to ensure more than once transaction of the same nonce is in the test?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes! must have dropped during code cleanup

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

@brad-decker brad-decker force-pushed the fix-splitting-of-transaction-groups branch from 531a804 to d6c9039 Compare May 14, 2021 22:38
@metamaskbot
Copy link
Collaborator

Builds ready [d6c9039]
Page Load Metrics (588 ± 51 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint46725974
domContentLoaded33272058710651
load33372158810651
domInteractive33272058610651

@danjm
Copy link
Contributor

danjm commented May 17, 2021

This looks good to me. One other non-blocking improvement I could suggest: add another test case for when there are transactions with the same nonce, but the number of generated transactions is less than the limit, and verify that entire groups of transactions are not cut off.

danjm
danjm previously approved these changes May 17, 2021
@brad-decker
Copy link
Contributor Author

@danjm added and also updated the test above it to be more specific because the last checks could have applied to either the first group of transactions or the second and the test was specifically checking that the first group was cut off and the second was not.

@metamaskbot
Copy link
Collaborator

Builds ready [f6f222d]
Page Load Metrics (549 ± 46 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint457762105
domContentLoaded4066695479646
load4086705499646
domInteractive4066695479646

@metamaskbot
Copy link
Collaborator

Builds ready [8f60118]
Page Load Metrics (667 ± 48 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint49906995
domContentLoaded37385666610148
load37585766710148
domInteractive37385666510148

@brad-decker brad-decker force-pushed the fix-splitting-of-transaction-groups branch from 01ffeb0 to 284c1b5 Compare May 17, 2021 17:03
@metamaskbot
Copy link
Collaborator

Builds ready [284c1b5]
Page Load Metrics (601 ± 51 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint508866105
domContentLoaded35277959810551
load35378060110551
domInteractive35277959810551

Copy link
Member

@Gudahtt Gudahtt left a comment

Choose a reason for hiding this comment

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

LGTM!

@brad-decker brad-decker merged commit 45cd987 into develop May 17, 2021
@brad-decker brad-decker deleted the fix-splitting-of-transaction-groups branch May 17, 2021 17:34
@github-actions github-actions bot locked and limited conversation to collaborators May 17, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MetaMask encountered an error
4 participants