From cd574c266c3edd69c3df1b38721130636f01ed2a Mon Sep 17 00:00:00 2001 From: "Akintayo A. Olusegun" Date: Wed, 22 Nov 2023 11:59:05 +0300 Subject: [PATCH 1/4] We should enabled it on the following networks: Ethereum Mainnet (already done) BNB chain Polygon Arbitrum Optimism Avalanche Test case for supported chain id Signed-off-by: Akintayo A. Olusegun Add linea mainnet to supported chain IDs. Lint fixes Fix tests Signed-off-by: Akintayo A. Olusegun --- .vscode/settings.json | 5 ++++ src/ppom-controller.test.ts | 40 +++++++++++++++++++++++---- src/ppom-controller.ts | 36 +++++++++++++++--------- test/test-utils.ts | 55 +++++++++++++++++++++---------------- 4 files changed, 93 insertions(+), 43 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..b242572e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "githubPullRequests.ignoredPullRequestBranches": [ + "main" + ] +} \ No newline at end of file diff --git a/src/ppom-controller.test.ts b/src/ppom-controller.test.ts index 9471375e..095d8ba6 100644 --- a/src/ppom-controller.test.ts +++ b/src/ppom-controller.test.ts @@ -195,7 +195,32 @@ describe('PPOMController', () => { }).rejects.toThrow('User has securityAlertsEnabled set to false'); }); - it('should throw error if the user is not on ethereum mainnet', async () => { + it('should NOT throw error if the user is on any supported chain id', async () => { + buildFetchSpy(); + ppomController = buildPPOMController({ + chainId: '0x38', + state: { + versionInfo: [ + { + name: 'blob', + chainId: '0x38', + version: '1.0.0', + checksum: + '409a7f83ac6b31dc8c77e3ec18038f209bd2f545e0f4177c2e2381aa4e067b49', + filePath: 'blob', + }, + ], + }, + }); + jest.runOnlyPendingTimers(); + const result = await ppomController.usePPOM(async () => { + return Promise.resolve(buildDummyResponse()); + }); + + expect(result).toStrictEqual(dummyResponse); + }); + + it('should throw error if the user is not on supported chain id', async () => { buildFetchSpy(); ppomController = buildPPOMController({ chainId: '0x2', @@ -206,7 +231,7 @@ describe('PPOMController', () => { return Promise.resolve(); }); }).rejects.toThrow( - 'Blockaid validation is available only on ethereum mainnet', + 'Blockaid validation is not available on selected network', ); }); @@ -460,7 +485,7 @@ describe('PPOMController', () => { await ppomController.updatePPOM(); jest.runOnlyPendingTimers(); await flushPromises(); - expect(spy).toHaveBeenCalledTimes(13); + expect(spy).toHaveBeenCalledTimes(12); }); it('should not re-throw error if file write fails', async () => { @@ -493,7 +518,7 @@ describe('PPOMController', () => { expect(spy).toHaveBeenCalledTimes(6); jest.advanceTimersByTime(REFRESH_TIME_INTERVAL); await flushPromises(); - expect(spy).toHaveBeenCalledTimes(8); + expect(spy).toHaveBeenCalledTimes(10); }); it('should delete network more than a week old from chainStatus', async () => { @@ -638,11 +663,14 @@ describe('PPOMController', () => { jest.useFakeTimers().setSystemTime(new Date('2023-01-04')); callBack({ providerConfig: { chainId: '0x6' } }); - expect(Object.keys(ppomController.state.chainStatus)).toHaveLength(5); + jest.useFakeTimers().setSystemTime(new Date('2023-01-04')); + callBack({ providerConfig: { chainId: '0x8' } }); + + expect(Object.keys(ppomController.state.chainStatus)).toHaveLength(6); jest.useFakeTimers().setSystemTime(new Date('2023-01-06')); callBack({ providerConfig: { chainId: '0x7' } }); - expect(Object.keys(ppomController.state.chainStatus)).toHaveLength(5); + expect(Object.keys(ppomController.state.chainStatus)).toHaveLength(6); expect(ppomController.state.chainStatus['0x1']).toBeUndefined(); }); diff --git a/src/ppom-controller.ts b/src/ppom-controller.ts index f7e513d8..47c92f30 100644 --- a/src/ppom-controller.ts +++ b/src/ppom-controller.ts @@ -51,7 +51,15 @@ const ALLOWED_PROVIDER_CALLS = [ 'trace_filter', ]; -const ETHEREUM_CHAIN_ID = '0x1'; +export const SUPPORTED_CHAIN_IDS = [ + '0x1', // mainnet chain id + '0x38', // bnb chain id + '0x89', // polygon chain id + '0xa4b1', // arbitrum chain id + '0xa', // optimism chain id + '0xa86a', // avalanche chain id + '0xe708', // Linea chain id +]; /** * @type PPOMFileVersion @@ -321,7 +329,7 @@ export class PPOMController extends BaseControllerV2< if (securityAlertsEnabled) { this.#updateVersionInfo() .then(async () => { - await this.#getNewFilesForChain(ETHEREUM_CHAIN_ID); + await this.#getNewFilesForChain(this.#chainId); // start scheduled task to fetch data files this.#checkScheduleFileDownloadForAllChains(); }) @@ -361,7 +369,7 @@ export class PPOMController extends BaseControllerV2< throw Error('User has securityAlertsEnabled set to false'); } if (!this.#networkIsSupported(this.#chainId)) { - throw Error('Blockaid validation is available only on ethereum mainnet'); + throw Error('Blockaid validation is not available on selected network'); } await this.#reinitPPOMForNetworkIfRequired(); @@ -407,11 +415,10 @@ export class PPOMController extends BaseControllerV2< } /* - * The function check if ethereum chainId is supported for validation - * Currently it checks for only Ethereum Mainnet but it will include more networks in future. + * The function check if chainId is supported for validation */ #networkIsSupported(chainId: string) { - return chainId === ETHEREUM_CHAIN_ID; + return SUPPORTED_CHAIN_IDS.includes(chainId); } /* @@ -494,7 +501,7 @@ export class PPOMController extends BaseControllerV2< this.#updateVersionInfo() .then(async () => { this.#checkScheduleFileDownloadForAllChains(); - await this.#getNewFilesForChain(ETHEREUM_CHAIN_ID); + await this.#getNewFilesForChain(this.#chainId); }) .catch((error: Error) => { console.error(`Error in initialising: ${error.message}`); @@ -774,8 +781,9 @@ export class PPOMController extends BaseControllerV2< const currentTimestamp = new Date().getTime(); const chainIds = Object.keys(this.state.chainStatus).filter( - (id) => id !== ETHEREUM_CHAIN_ID, + (id) => id !== this.#chainId, ); + const oldChaninIds: any[] = chainIds.filter( (chainId) => (this.state.chainStatus[chainId] as any).lastVisited < @@ -843,8 +851,8 @@ export class PPOMController extends BaseControllerV2< if (isLastFileOfNetwork) { // if this was last file for the chainId set dataFetched for chainId to true await this.#setChainIdDataFetched(fileVersionInfo.chainId); - if (fileVersionInfo.chainId === ETHEREUM_CHAIN_ID) { - await this.#reinitPPOM(ETHEREUM_CHAIN_ID); + if (fileVersionInfo.chainId === this.#chainId) { + await this.#reinitPPOM(this.#chainId); } } }) @@ -1000,9 +1008,11 @@ export class PPOMController extends BaseControllerV2< // thus it is added here to prevent validation from failing. await this.#initialisePPOM(); const { chainStatus } = this.state; - const versionInfo = - chainStatus[chainId]?.versionInfo ?? - this.state.versionInfo.filter(({ chainId: id }) => id === chainId); + console.log('chainStatus 1008', chainStatus); + const hasVersionInfo = chainStatus[chainId]?.versionInfo?.length; + const versionInfo = hasVersionInfo + ? chainStatus[chainId]?.versionInfo + : this.state.versionInfo.filter(({ chainId: id }) => id === chainId); if (!versionInfo?.length) { this.#ppomInitError = `Aborting validation as no files are found for the network with chainId: ${chainId}`; return undefined; diff --git a/test/test-utils.ts b/test/test-utils.ts index 34c282dd..1717cba4 100644 --- a/test/test-utils.ts +++ b/test/test-utils.ts @@ -1,8 +1,8 @@ import { ControllerMessenger } from '@metamask/base-controller'; import * as ControllerUtils from '@metamask/controller-utils'; -import { PPOMController } from '../src/ppom-controller'; -import { StorageKey } from '../src/ppom-storage'; +import { PPOMController, SUPPORTED_CHAIN_IDS } from '../src/ppom-controller'; +import { FileMetadata, StorageKey } from '../src/ppom-storage'; export const buildDummyResponse = ( resultType = 'DUMMY_RESULT_TYPE', @@ -54,28 +54,35 @@ export const storageBackendReturningData = buildStorageBackend({ Promise.resolve(DUMMY_ARRAY_BUFFER_DATA), }); -export const VERSION_INFO = [ - { - name: 'blob', - chainId: '0x1', - version: '1.0.0', - checksum: - '409a7f83ac6b31dc8c77e3ec18038f209bd2f545e0f4177c2e2381aa4e067b49', - signature: - '0x304402206d433e9172960de6717d94ae263e47eefacd3584a3274a452f8f9567b3a797db02201b2e423188fb3f9daa6ce6a8723f69df26bd3ceeee81f77250526b91e093614f', - filePath: 'blob', - }, - { - name: 'data', - chainId: '0x1', - version: '1.0.3', - checksum: - '409a7f83ac6b31dc8c77e3ec18038f209bd2f545e0f4177c2e2381aa4e067b49', - signature: - '0x304402206d433e9172960de6717d94ae263e47eefacd3584a3274a452f8f9567b3a797db02201b2e423188fb3f9daa6ce6a8723f69df26bd3ceeee81f77250526b91e093614f', - filePath: 'data', - }, -]; +export const VERSION_INFO: (FileMetadata & { + signature: string; + filePath: string; +})[] = []; + +SUPPORTED_CHAIN_IDS.forEach((chainId) => { + VERSION_INFO.push( + { + name: `${chainId}_blob`, + chainId, + version: '1.0.0', + checksum: + '409a7f83ac6b31dc8c77e3ec18038f209bd2f545e0f4177c2e2381aa4e067b49', + signature: + '0x304402206d433e9172960de6717d94ae263e47eefacd3584a3274a452f8f9567b3a797db02201b2e423188fb3f9daa6ce6a8723f69df26bd3ceeee81f77250526b91e093614f', + filePath: `${chainId}_blob`, + }, + { + name: `${chainId}_blob`, + chainId, + version: '1.0.3', + checksum: + '409a7f83ac6b31dc8c77e3ec18038f209bd2f545e0f4177c2e2381aa4e067b49', + signature: + '0x304402206d433e9172960de6717d94ae263e47eefacd3584a3274a452f8f9567b3a797db02201b2e423188fb3f9daa6ce6a8723f69df26bd3ceeee81f77250526b91e093614f', + filePath: `${chainId}_data`, + }, + ); +}); const PPOM_VERSION_PATH = 'https://ppom_cdn_base_url/ppom_version.json'; From 9bb6fe0a15883b6e469d26f58b9fd1f6184458fa Mon Sep 17 00:00:00 2001 From: "Akintayo A. Olusegun" Date: Wed, 6 Dec 2023 18:34:41 +0300 Subject: [PATCH 2/4] Lint and Test Fixes --- .vscode/settings.json | 5 ----- src/ppom-controller.test.ts | 25 ------------------------- src/ppom-controller.ts | 1 - 3 files changed, 31 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index b242572e..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "githubPullRequests.ignoredPullRequestBranches": [ - "main" - ] -} \ No newline at end of file diff --git a/src/ppom-controller.test.ts b/src/ppom-controller.test.ts index 095d8ba6..b6dbabca 100644 --- a/src/ppom-controller.test.ts +++ b/src/ppom-controller.test.ts @@ -195,31 +195,6 @@ describe('PPOMController', () => { }).rejects.toThrow('User has securityAlertsEnabled set to false'); }); - it('should NOT throw error if the user is on any supported chain id', async () => { - buildFetchSpy(); - ppomController = buildPPOMController({ - chainId: '0x38', - state: { - versionInfo: [ - { - name: 'blob', - chainId: '0x38', - version: '1.0.0', - checksum: - '409a7f83ac6b31dc8c77e3ec18038f209bd2f545e0f4177c2e2381aa4e067b49', - filePath: 'blob', - }, - ], - }, - }); - jest.runOnlyPendingTimers(); - const result = await ppomController.usePPOM(async () => { - return Promise.resolve(buildDummyResponse()); - }); - - expect(result).toStrictEqual(dummyResponse); - }); - it('should throw error if the user is not on supported chain id', async () => { buildFetchSpy(); ppomController = buildPPOMController({ diff --git a/src/ppom-controller.ts b/src/ppom-controller.ts index 47c92f30..726f3d33 100644 --- a/src/ppom-controller.ts +++ b/src/ppom-controller.ts @@ -1008,7 +1008,6 @@ export class PPOMController extends BaseControllerV2< // thus it is added here to prevent validation from failing. await this.#initialisePPOM(); const { chainStatus } = this.state; - console.log('chainStatus 1008', chainStatus); const hasVersionInfo = chainStatus[chainId]?.versionInfo?.length; const versionInfo = hasVersionInfo ? chainStatus[chainId]?.versionInfo From 4976b8cce7394f3e5c8321d39b910cd3a9fbf019 Mon Sep 17 00:00:00 2001 From: "Akintayo A. Olusegun" Date: Wed, 6 Dec 2023 20:50:38 +0300 Subject: [PATCH 3/4] lint fixes. --- src/ppom-controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ppom-controller.ts b/src/ppom-controller.ts index 726f3d33..1e537f2a 100644 --- a/src/ppom-controller.ts +++ b/src/ppom-controller.ts @@ -52,7 +52,7 @@ const ALLOWED_PROVIDER_CALLS = [ ]; export const SUPPORTED_CHAIN_IDS = [ - '0x1', // mainnet chain id + '0x1', // ethereum mainnet chain id '0x38', // bnb chain id '0x89', // polygon chain id '0xa4b1', // arbitrum chain id From 9152ff3bda81d1bef184cb4cfd2c348e83056e74 Mon Sep 17 00:00:00 2001 From: "Akintayo A. Olusegun" Date: Thu, 7 Dec 2023 18:01:45 +0300 Subject: [PATCH 4/4] Fix tests --- test/test-utils.ts | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/test/test-utils.ts b/test/test-utils.ts index 1717cba4..3a06a949 100644 --- a/test/test-utils.ts +++ b/test/test-utils.ts @@ -28,22 +28,25 @@ export const buildStorageBackend = (obj = {}) => { }; }; -export const StorageMetadata = [ - { - name: 'data', - chainId: '0x1', +export const StorageMetadata: FileMetadata[] = []; + +SUPPORTED_CHAIN_IDS.forEach((chainId) => { + const data = { + name: `${chainId}_data`, + chainId, version: '1.0.3', checksum: '409a7f83ac6b31dc8c77e3ec18038f209bd2f545e0f4177c2e2381aa4e067b49', - }, - { - name: 'blob', - chainId: '0x1', + }; + const blob = { + name: `${chainId}_blob`, + chainId, version: '1.0.0', checksum: '409a7f83ac6b31dc8c77e3ec18038f209bd2f545e0f4177c2e2381aa4e067b49', - }, -]; + }; + StorageMetadata.push(data, blob); +}); export const simpleStorageBackend = buildStorageBackend();