Skip to content

Commit

Permalink
perf: Filter out certain Snaps fields in Engine redux slice
Browse files Browse the repository at this point in the history
  • Loading branch information
FrederikBolding committed Jul 1, 2024
1 parent 2478527 commit 0efd8f1
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 3 deletions.
47 changes: 47 additions & 0 deletions app/core/redux/slices/engine/engineReducer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,51 @@ describe('engineReducer', () => {
AccountTrackerController: Engine.state[key],
});
});

it('should filter out unnecesary Snaps state', () => {
const reduxInitialState = {
backgroundState: {
SnapController: {
snaps: {},
snapStates: {},
unencryptedSnapStates: {},
},
},
};

const key = 'SnapController';
// changing the mock version to suit this test manually due to our current global mock
// TODO: Replace "any" with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(Engine as any).state = {
SnapController: {
snaps: {

Check failure on line 73 in app/core/redux/slices/engine/engineReducer.test.tsx

View workflow job for this annotation

GitHub Actions / scripts (lint)

Insert `··`
'npm:@metamask/bip32-example-snap': {

Check failure on line 74 in app/core/redux/slices/engine/engineReducer.test.tsx

View workflow job for this annotation

GitHub Actions / scripts (lint)

Insert `··`
id: 'npm:@metamask/bip32-example-snap',

Check failure on line 75 in app/core/redux/slices/engine/engineReducer.test.tsx

View workflow job for this annotation

GitHub Actions / scripts (lint)

Insert `··`
sourceCode: 'foo bar',

Check failure on line 76 in app/core/redux/slices/engine/engineReducer.test.tsx

View workflow job for this annotation

GitHub Actions / scripts (lint)

Insert `··`
},

Check failure on line 77 in app/core/redux/slices/engine/engineReducer.test.tsx

View workflow job for this annotation

GitHub Actions / scripts (lint)

Insert `··`
},

Check failure on line 78 in app/core/redux/slices/engine/engineReducer.test.tsx

View workflow job for this annotation

GitHub Actions / scripts (lint)

Insert `··`
snapStates: {},

Check failure on line 79 in app/core/redux/slices/engine/engineReducer.test.tsx

View workflow job for this annotation

GitHub Actions / scripts (lint)

Insert `··`
unencryptedSnapStates: {

Check failure on line 80 in app/core/redux/slices/engine/engineReducer.test.tsx

View workflow job for this annotation

GitHub Actions / scripts (lint)

Insert `··`
'npm:@metamask-bip32-example-snap': JSON.stringify({ foo: 'bar' }),

Check failure on line 81 in app/core/redux/slices/engine/engineReducer.test.tsx

View workflow job for this annotation

GitHub Actions / scripts (lint)

Insert `··`
},

Check failure on line 82 in app/core/redux/slices/engine/engineReducer.test.tsx

View workflow job for this annotation

GitHub Actions / scripts (lint)

Insert `··`
}
};
const { backgroundState } = engineReducer(
reduxInitialState,
updateBgState({ key }),
);
expect(backgroundState).toEqual({
...reduxInitialState.backgroundState,
SnapController: {
snaps: {
'npm:@metamask/bip32-example-snap': {
id: 'npm:@metamask/bip32-example-snap',
},
},
snapStates: {},
unencryptedSnapStates: {},
}
});
});
});
37 changes: 35 additions & 2 deletions app/core/redux/slices/engine/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { cloneDeep } from 'lodash';
import Engine from '../../../Engine';
import { createAction, PayloadAction } from '@reduxjs/toolkit';
///: BEGIN:ONLY_INCLUDE_IF(preinstalled-snaps,external-snaps)
import { PersistedSnap } from '@metamask/snaps-utils';
///: END:ONLY_INCLUDE_IF

const initialState = {
// TODO: Replace "any" with type
Expand All @@ -18,6 +21,34 @@ export const updateBgState = createAction('UPDATE_BG_STATE', (key) => ({
payload: key,
}));

/**
* Filters out state values that we do not want to include in the Redux store.
*
* @param key The state key, which should also be the controller name.
* @param value The state blob for a controller.
* @returns A filtered state blob for a given controller.
*/
function filterState(key: string, value: any) {
///: BEGIN:ONLY_INCLUDE_IF(preinstalled-snaps,external-snaps)
if (key === 'SnapController') {
return {
snapStates: {},
unencryptedSnapStates: {},
snaps: Object.values(value.snaps as Record<string, PersistedSnap>).reduce<
Record<string, Omit<PersistedSnap, 'sourceCode'>>
>((acc, snap) => {
// eslint-disable-next-line no-unused-vars
const { sourceCode, auxiliaryFiles, ...rest } = snap;
acc[snap.id] = rest;
return acc;
}, {}),
};
}
///: END:ONLY_INCLUDE_IF

return value;
}

// TODO: Replace "any" with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const counter: any = {};
Expand Down Expand Up @@ -46,10 +77,12 @@ const engineReducer = (
// - Deep comparison selectors do not fire since the cached objects are references to the original
// state object which has been mutated.
// This is resolved by doing a deep clone in this scenario to force an entirely new object.
newState.backgroundState[action.payload?.key] =
newState.backgroundState[action.payload?.key] = filterState(
action.payload.key,
legacyControllers.includes(action.payload.key)
? cloneDeep(newControllerState)
: newControllerState;
: newControllerState,
);
}

return newState;
Expand Down
1 change: 0 additions & 1 deletion app/selectors/snaps/snapController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { RootState } from '../../reducers';
import { createDeepEqualSelector } from '../util';
import { getLocalizedSnapManifest } from '@metamask/snaps-utils';

// TODO: Filter out huge values
export const selectSnapControllerState = (state: RootState) =>
state.engine.backgroundState.SnapController;

Expand Down

0 comments on commit 0efd8f1

Please sign in to comment.