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

feat: Network Controller to version 11.0.0 #8812

Merged
merged 10 commits into from
Mar 7, 2024
2 changes: 1 addition & 1 deletion app/components/Views/LedgerAccountInfo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ const LedgerAccountInfo = () => {
index={1}
address={account}
balance={accountBalance}
ticker={provider.ticker || 'ETH'}
ticker={provider.ticker}
toBlockExplorer={toBlockExplorer}
/>
</View>
Expand Down
4 changes: 1 addition & 3 deletions app/core/Engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -542,8 +542,6 @@ class Engine {
onNetworkStateChange: (listener) =>
this.controllerMessenger.subscribe(
AppConstants.NETWORK_STATE_CHANGE_EVENT,
// @ts-expect-error network controller will be updated on this PR: https://github.com/MetaMask/metamask-mobile/pull/8812 and this type error will be addressed
// This is not a blocker because gas fee controller does not need ticker to be defined
listener,
),
getCurrentNetworkEIP1559Compatibility: async () =>
Expand Down Expand Up @@ -999,7 +997,7 @@ class Engine {
onPreferencesStateChange: (listener) =>
preferencesController.subscribe(listener),
chainId: networkController.state.providerConfig.chainId,
ticker: networkController.state.providerConfig.ticker ?? 'ETH',
ticker: networkController.state.providerConfig.ticker,
selectedAddress: preferencesController.state.selectedAddress,
tokenPricesService: codefiTokenApiV2,
interval: 30 * 60 * 1000,
Expand Down
9 changes: 9 additions & 0 deletions app/core/RPCMethods/RPCMethodMiddleware.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ function setupSignature() {
providerConfig: {
chainId: '0x1',
type: RPC,
ticker: 'ETH',
},
selectedAddress: addressMock,
permittedAccounts: { [hostMock]: [addressMock] },
Expand Down Expand Up @@ -522,6 +523,7 @@ describe('getRpcMethodMiddleware', () => {
providerConfig: {
chainId: '0x1',
type: RPC,
ticker: 'ETH',
},
});
const middleware = getRpcMethodMiddleware({
Expand Down Expand Up @@ -556,6 +558,7 @@ describe('getRpcMethodMiddleware', () => {
providerConfig: {
chainId: '0x1',
type: RPC,
ticker: 'ETH',
},
});
const middleware = getRpcMethodMiddleware({
Expand Down Expand Up @@ -592,6 +595,7 @@ describe('getRpcMethodMiddleware', () => {
providerConfig: {
chainId: '0x1',
type: RPC,
ticker: 'ETH',
},
});
const middleware = getRpcMethodMiddleware({
Expand Down Expand Up @@ -629,6 +633,7 @@ describe('getRpcMethodMiddleware', () => {
providerConfig: {
chainId: '0x1',
type: RPC,
ticker: 'ETH',
},
selectedAddress: mockAddress,
});
Expand Down Expand Up @@ -661,6 +666,7 @@ describe('getRpcMethodMiddleware', () => {
providerConfig: {
chainId: '0x1',
type: RPC,
ticker: 'ETH',
},
selectedAddress: differentMockAddress,
});
Expand Down Expand Up @@ -700,6 +706,7 @@ describe('getRpcMethodMiddleware', () => {
providerConfig: {
chainId: '0x1',
type: RPC,
ticker: 'ETH',
},
selectedAddress: mockAddress,
});
Expand Down Expand Up @@ -732,6 +739,7 @@ describe('getRpcMethodMiddleware', () => {
providerConfig: {
chainId: '0x1',
type: RPC,
ticker: 'ETH',
},
selectedAddress: differentMockAddress,
});
Expand Down Expand Up @@ -767,6 +775,7 @@ describe('getRpcMethodMiddleware', () => {
providerConfig: {
chainId: '0x1',
type: RPC,
ticker: 'ETH',
},
});
const middleware = getRpcMethodMiddleware({
Expand Down
2 changes: 2 additions & 0 deletions app/store/migrations/024.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ describe('Migration #24', () => {
networkStatus: 'unknown',
providerConfig: {
chainId: '0x1',
ticker: 'ETH',
type: 'mainnet',
},
});
Expand Down Expand Up @@ -101,6 +102,7 @@ describe('Migration #24', () => {
providerConfig: {
chainId: '0x1',
type: 'mainnet',
ticker: 'ETH',
},
});
});
Expand Down
125 changes: 125 additions & 0 deletions app/store/migrations/032.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import migrate from './032';
import { merge } from 'lodash';
import { captureException } from '@sentry/react-native';
import initialRootState from '../../util/test/initial-root-state';

const expectedState = {
engine: {
backgroundState: {
NetworkController: {
providerConfig: {
type: 'mainnet',
chainId: '0x1',
rpcUrl: 'https://api.avax.network/ext/bc/C/rpc',
ticker: 'ETH',
},
},
},
},
};

jest.mock('@sentry/react-native', () => ({
captureException: jest.fn(),
}));
const mockedCaptureException = jest.mocked(captureException);

describe('Migration #32', () => {
beforeEach(() => {
jest.restoreAllMocks();
jest.resetAllMocks();
});

const invalidStates = [
{
state: null,
errorMessage: "Migration 32: Invalid root state: 'object'",
scenario: 'state is invalid',
},
{
state: merge({}, initialRootState, {
engine: null,
}),
errorMessage: "Migration 32: Invalid root engine state: 'object'",
scenario: 'engine state is invalid',
},
{
state: merge({}, initialRootState, {
engine: {
backgroundState: null,
},
}),
errorMessage:
"Migration 32: Invalid root engine backgroundState: 'object'",
scenario: 'backgroundState is invalid',
},
{
state: merge({}, initialRootState, {
engine: {
backgroundState: { NetworkController: null },
},
}),
errorMessage: "Migration 32: Invalid NetworkController state: 'object'",
scenario: 'NetworkController is invalid',
},
{
state: merge({}, initialRootState, {
engine: {
backgroundState: { NetworkController: { providerConfig: null } },
},
}),
errorMessage:
"Migration 32: Invalid NetworkController providerConfig: 'object'",
scenario: 'providerConfig is invalid',
},
];

for (const { errorMessage, scenario, state } of invalidStates) {
it(`should capture exception if ${scenario}`, () => {
const newState = migrate(state);

expect(newState).toStrictEqual(state);
expect(mockedCaptureException).toHaveBeenCalledWith(expect.any(Error));
expect(mockedCaptureException.mock.calls[0][0].message).toBe(
errorMessage,
);
});
}

it('should not change ticker if ticker was defined', () => {
const oldState = {
engine: {
backgroundState: {
NetworkController: {
providerConfig: {
type: 'mainnet',
chainId: '0x1',
rpcUrl: 'https://api.avax.network/ext/bc/C/rpc',
ticker: 'AVAX',
},
},
},
},
};

const migratedState = migrate(oldState);
expect(migratedState).toStrictEqual(oldState);
});

it('should add ticker when no ticker is defined', () => {
const oldState = {
engine: {
backgroundState: {
NetworkController: {
providerConfig: {
type: 'mainnet',
chainId: '0x1',
rpcUrl: 'https://api.avax.network/ext/bc/C/rpc',
},
},
},
},
};
const migratedState = migrate(oldState);
expect(migratedState).toStrictEqual(expectedState);
});
});
68 changes: 68 additions & 0 deletions app/store/migrations/032.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { captureException } from '@sentry/react-native';
import { isObject, hasProperty } from '@metamask/utils';
import type { NetworkState } from '@metamask/network-controller';

/**
* This migration addresses the ticker be required
* if it is not defined for the current network it will add the value ETH
* @param {unknown} state - Redux state.
* @returns Migrated Redux state.
*/
export default function migrate(state: unknown) {
if (!isObject(state)) {
captureException(
new Error(`Migration 32: Invalid root state: '${typeof state}'`),
);
return state;
}

if (!isObject(state.engine)) {
captureException(
new Error(
`Migration 32: Invalid root engine state: '${typeof state.engine}'`,
),
);
return state;
}

if (!isObject(state.engine.backgroundState)) {
captureException(
new Error(
`Migration 32: Invalid root engine backgroundState: '${typeof state
.engine.backgroundState}'`,
),
);
return state;
}

const networkControllerState = state.engine.backgroundState.NetworkController;
const newNetworkControllerState = state.engine.backgroundState
.NetworkController as NetworkState;

if (!isObject(networkControllerState)) {
captureException(
new Error(
`Migration 32: Invalid NetworkController state: '${typeof networkControllerState}'`,
),
);
return state;
}

if (
!hasProperty(networkControllerState, 'providerConfig') ||
!isObject(networkControllerState.providerConfig)
) {
captureException(
new Error(
`Migration 32: Invalid NetworkController providerConfig: '${typeof networkControllerState.providerConfig}'`,
),
);
return state;
}

if (!networkControllerState.providerConfig.ticker) {
newNetworkControllerState.providerConfig.ticker = 'ETH';
}

return state;
}
2 changes: 2 additions & 0 deletions app/store/migrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import migration28 from './028';
import migration29 from './029';
import migration30 from './030';
import migration31 from './031';
import migration32 from './032';

// We do not keep track of the old state
// We create this type for better readability
Expand Down Expand Up @@ -70,6 +71,7 @@ export const migrations: MigrationManifest = {
29: migration29 as unknown as (state: OldState) => PersistedState,
30: migration30 as unknown as (state: OldState) => PersistedState,
31: migration31 as unknown as (state: OldState) => PersistedState,
32: migration32 as unknown as (state: OldState) => PersistedState,
};

// The latest (i.e. highest) version number.
Expand Down
3 changes: 2 additions & 1 deletion app/util/test/initial-background-state.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@
"networkConfigurations": {},
"providerConfig": {
"type": "mainnet",
"chainId": "0x1"
"chainId": "0x1",
"ticker": "ETH"
},
"networkDetails": {
"EIPS": {}
Expand Down
1 change: 1 addition & 0 deletions e2e/fixtures/fixture-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ class FixtureBuilder {
providerConfig: {
type: 'mainnet',
chainId: '0x1',
ticker: 'ETH',
},
networkDetails: {
EIPS: {},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@
"@metamask/key-tree": "^9.0.0",
"@metamask/keyring-controller": "^8.1.0",
"@metamask/logging-controller": "^1.0.1",
"@metamask/network-controller": "^10.0.0",
"@metamask/network-controller": "^11.0.0",
"@metamask/permission-controller": "7.1.0",
"@metamask/phishing-controller": "6.0.0",
"@metamask/post-message-stream": "8.0.0",
Expand Down
Loading
Loading