diff --git a/packages/network-controller/src/NetworkController.ts b/packages/network-controller/src/NetworkController.ts index 25b449cc0a..c90d2fab0e 100644 --- a/packages/network-controller/src/NetworkController.ts +++ b/packages/network-controller/src/NetworkController.ts @@ -302,7 +302,6 @@ export class NetworkController extends BaseControllerV2< default: throw new Error(`Unrecognized network type: '${type}'`); } - this.getEIP1559Compatibility(); } getProviderAndBlockTracker(): { @@ -421,7 +420,10 @@ export class NetworkController extends BaseControllerV2< } /** - * Refreshes the current network code. + * Performs side effects after switching to a network. If the network is + * available, updates the network state with the network ID of the network and + * stores whether the network supports EIP-1559; otherwise clears said + * information about the network that may have been previously stored. */ async lookupNetwork() { if (!this.#ethQuery) { @@ -431,7 +433,10 @@ export class NetworkController extends BaseControllerV2< try { try { - const networkId = await this.#getNetworkId(); + const [networkId] = await Promise.all([ + this.#getNetworkId(), + this.getEIP1559Compatibility(), + ]); if (this.state.networkId === networkId) { return; } diff --git a/packages/network-controller/tests/NetworkController.test.ts b/packages/network-controller/tests/NetworkController.test.ts index 5677649e33..d98bc7d264 100644 --- a/packages/network-controller/tests/NetworkController.test.ts +++ b/packages/network-controller/tests/NetworkController.test.ts @@ -107,8 +107,8 @@ const POST_1559_BLOCK = { // initializeProvider refreshNetwork // │ │ └────────────────────────────────────────────┬──────────────────────────────────────────────┘ │ // │ │ configureProvider │ -// │ │ ┌─────────────────────────┘ │ └─────────────────────────┐ │ -// │ │ setupInfuraProvider setupStandardProvider getEIP1559Compatibility │ +// │ │ ┌─────────────────────────┘ │ | +// │ │ setupInfuraProvider setupStandardProvider │ // │ │ └─────────────┬─────────────┘ │ // │ │ updateProvider │ // │ └───────────────┬───────────────┘ └───────────────────────────────┐ │ @@ -1295,6 +1295,137 @@ describe('NetworkController', () => { }); }); + describe('assuming that the network details of the current network are different from the network in state', () => { + it('updates the network in state to match', async () => { + const messenger = buildMessenger(); + await withController( + { + messenger, + state: { networkDetails: { isEIP1559Compatible: false } }, + }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + response: { + result: { + baseFeePerGas: '0x1', + }, + }, + }, + ], + }); + + await controller.lookupNetwork(); + + expect(controller.state.networkDetails).toStrictEqual({ + isEIP1559Compatible: true, + }); + }, + ); + }); + }); + + describe('if the network details of the current network are the same as that in state', () => { + it('does not change network in state', async () => { + const messenger = buildMessenger(); + await withController( + { + messenger, + state: { networkDetails: { isEIP1559Compatible: true } }, + }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + response: { + result: { + baseFeePerGas: '0x1', + }, + }, + }, + ], + }); + const promiseForNetworkDetailChanges = waitForStateChanges( + messenger, + { + propertyPath: ['networkDetails'], + }, + ); + + await controller.lookupNetwork(); + + await expect(promiseForNetworkDetailChanges).toNeverResolve(); + }, + ); + }); + }); + + describe('if an RPC error is encountered while retrieving the network details of the current network', () => { + it('updates the network in state to "unavailable"', async () => { + const messenger = buildMessenger(); + await withController( + { messenger, state: { networkId: '1' } }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + error: ethErrors.rpc.limitExceeded('some error'), + }, + ], + stubGetEIP1559CompatibilityWhileSetting: true, + }); + + await controller.lookupNetwork(); + + expect(controller.state.networkStatus).toBe( + NetworkStatus.Unavailable, + ); + }, + ); + }); + }); + + describe('if an internal error is encountered while retrieving the network details of the current network', () => { + it('updates the network in state to "unknown"', async () => { + const messenger = buildMessenger(); + await withController( + { messenger, state: { networkId: '1' } }, + async ({ controller }) => { + await setFakeProvider(controller, { + stubs: [ + { + request: { + method: 'eth_getBlockByNumber', + params: ['latest', false], + }, + error: ethErrors.rpc.internal('some error'), + }, + ], + }); + + await controller.lookupNetwork(); + + expect(controller.state.networkStatus).toBe( + NetworkStatus.Unknown, + ); + }, + ); + }); + }); + describe('if lookupNetwork is called multiple times in quick succession', () => { it('waits until each call finishes before resolving the next', async () => { const messenger = buildMessenger(); @@ -4975,7 +5106,7 @@ describe('NetworkController', () => { await waitForStateChanges(messenger, { propertyPath: ['networkId'], - count: 1, + count: 2, produceStateChanges: () => { controller.rollbackToPreviousProvider(); }, @@ -5445,7 +5576,7 @@ describe('NetworkController', () => { await waitForStateChanges(messenger, { propertyPath: ['networkId'], - count: 1, + count: 2, produceStateChanges: () => { controller.rollbackToPreviousProvider(); },