Skip to content

Commit 024efbe

Browse files
authored
feat(account-tree-controller): do not enqueue single syncs during full syncs (#6651)
## Explanation This PR prevents single sync events from being enqueued if a full sync is already in progress. This prevents unnecessary client side network calls. ## References Fixes: https://consensyssoftware.atlassian.net/browse/MUL-901 ## Checklist - [x] I've updated the test suite for new or updated code as appropriate - [x] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [x] I've communicated my changes to consumers by [updating changelogs for packages I've changed](https://github.com/MetaMask/core/tree/main/docs/contributing.md#updating-changelogs), highlighting breaking changes as necessary - [ ] I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes
1 parent 05b39bc commit 024efbe

File tree

3 files changed

+73
-1
lines changed

3 files changed

+73
-1
lines changed

packages/account-tree-controller/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
12+
- Single group sync events will not get enqueued anymore if a full sync is in progress ([#6651](https://github.com/MetaMask/core/pull/6651))
13+
- This prevents too many unnecessary storage fetches (which would prevent being rate limited).
14+
- This could rarely lead to inconsistencies until the next single updates or next full sync.
15+
1016
## [0.16.1]
1117

1218
### Added

packages/account-tree-controller/src/backup-and-sync/service/index.test.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ describe('BackupAndSync - Service - BackupAndSyncService', () => {
9494
expect(mockContext.messenger.call).toHaveBeenCalledWith(
9595
'UserStorageController:getState',
9696
);
97+
expect(mockContext.messenger.call).not.toHaveBeenCalledWith(
98+
'UserStorageController:performGetStorage',
99+
);
97100
});
98101

99102
it('returns early when account syncing is disabled', () => {
@@ -106,6 +109,23 @@ describe('BackupAndSync - Service - BackupAndSyncService', () => {
106109
expect(mockContext.messenger.call).toHaveBeenCalledWith(
107110
'UserStorageController:getState',
108111
);
112+
expect(mockContext.messenger.call).not.toHaveBeenCalledWith(
113+
'UserStorageController:performGetStorage',
114+
);
115+
});
116+
117+
it('returns early when a full sync has not completed at least once', () => {
118+
mockContext.controller.state.hasAccountTreeSyncingSyncedAtLeastOnce =
119+
false;
120+
backupAndSyncService.enqueueSingleWalletSync('entropy:wallet-1');
121+
// Should not have called any messenger functions beyond the state check
122+
expect(mockContext.messenger.call).toHaveBeenCalledTimes(1);
123+
expect(mockContext.messenger.call).toHaveBeenCalledWith(
124+
'UserStorageController:getState',
125+
);
126+
expect(mockContext.messenger.call).not.toHaveBeenCalledWith(
127+
'UserStorageController:performGetStorage',
128+
);
109129
});
110130

111131
it('enqueues single wallet sync when enabled and synced at least once', async () => {
@@ -158,6 +178,9 @@ describe('BackupAndSync - Service - BackupAndSyncService', () => {
158178
expect(mockContext.messenger.call).toHaveBeenCalledWith(
159179
'UserStorageController:getState',
160180
);
181+
expect(mockContext.messenger.call).not.toHaveBeenCalledWith(
182+
'UserStorageController:performGetStorage',
183+
);
161184
});
162185

163186
it('returns early when account syncing is disabled', () => {
@@ -170,6 +193,40 @@ describe('BackupAndSync - Service - BackupAndSyncService', () => {
170193
expect(mockContext.messenger.call).toHaveBeenCalledWith(
171194
'UserStorageController:getState',
172195
);
196+
expect(mockContext.messenger.call).not.toHaveBeenCalledWith(
197+
'UserStorageController:performGetStorage',
198+
);
199+
});
200+
201+
it('returns early when a full sync is already in progress', () => {
202+
mockContext.controller.state.isAccountTreeSyncingInProgress = true;
203+
204+
backupAndSyncService.enqueueSingleGroupSync('entropy:wallet-1/1');
205+
206+
// Should not have called any messenger functions beyond the state check
207+
expect(mockContext.messenger.call).toHaveBeenCalledTimes(1);
208+
expect(mockContext.messenger.call).toHaveBeenCalledWith(
209+
'UserStorageController:getState',
210+
);
211+
expect(mockContext.messenger.call).not.toHaveBeenCalledWith(
212+
'UserStorageController:performGetStorage',
213+
);
214+
});
215+
216+
it('returns early when a full sync has not completed at least once', () => {
217+
mockContext.controller.state.hasAccountTreeSyncingSyncedAtLeastOnce =
218+
false;
219+
220+
backupAndSyncService.enqueueSingleGroupSync('entropy:wallet-1/1');
221+
222+
// Should not have called any messenger functions beyond the state check
223+
expect(mockContext.messenger.call).toHaveBeenCalledTimes(1);
224+
expect(mockContext.messenger.call).toHaveBeenCalledWith(
225+
'UserStorageController:getState',
226+
);
227+
expect(mockContext.messenger.call).not.toHaveBeenCalledWith(
228+
'UserStorageController:performGetStorage',
229+
);
173230
});
174231

175232
it('enqueues group sync when enabled and synced at least once', async () => {

packages/account-tree-controller/src/backup-and-sync/service/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,16 @@ export class BackupAndSyncService {
184184
* @param groupId - The group ID to sync.
185185
*/
186186
enqueueSingleGroupSync(groupId: AccountGroupId): void {
187-
if (!this.isBackupAndSyncEnabled || !this.hasSyncedAtLeastOnce) {
187+
if (
188+
!this.isBackupAndSyncEnabled ||
189+
!this.hasSyncedAtLeastOnce ||
190+
// This prevents rate limiting scenarios where full syncs trigger group creations
191+
// that in turn enqueue the same single group syncs that the full sync just did.
192+
// This can very rarely lead to inconsistencies, but will be fixed on the next full sync.
193+
// TODO: let's improve this in the future by tracking the updates done in the full sync and
194+
// comparing against that.
195+
this.isInProgress
196+
) {
188197
return;
189198
}
190199

0 commit comments

Comments
 (0)