Skip to content

Commit f91d5e1

Browse files
committed
Keep network statuses up to date as requests are made
NetworkController has the ability to analyze an RPC endpoint and capture its availability status (that is, whether the controller is able to make successful requests to the endpoint). However, this step occurs automatically only once, when the RPC endpoint's network is switched to, and so any changes in status while the network is being used will not be reflected in state. This problem can be mitigated by periodically calling `lookupNetwork` manually, but this is awkward, and usage of this method should be kept in check so as not to create too many requests. Ideally, the controller should keep track of network status as requests are made. This commit implements this change by hooking into events published by the network client and added in a previous commit.
1 parent b16597a commit f91d5e1

File tree

7 files changed

+1005
-76
lines changed

7 files changed

+1005
-76
lines changed

packages/network-controller/src/NetworkController.ts

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,6 +1491,31 @@ export class NetworkController extends BaseController<
14911491
`${this.name}:updateNetwork`,
14921492
this.updateNetwork.bind(this),
14931493
);
1494+
1495+
this.messenger.subscribe(
1496+
`${this.name}:rpcEndpointChainUnavailable`,
1497+
({ networkClientId }) => {
1498+
this.#updateMetadataForNetwork(networkClientId, {
1499+
networkStatus: NetworkStatus.Unavailable,
1500+
});
1501+
},
1502+
);
1503+
this.messenger.subscribe(
1504+
`${this.name}:rpcEndpointChainDegraded`,
1505+
({ networkClientId }) => {
1506+
this.#updateMetadataForNetwork(networkClientId, {
1507+
networkStatus: NetworkStatus.Degraded,
1508+
});
1509+
},
1510+
);
1511+
this.messenger.subscribe(
1512+
`${this.name}:rpcEndpointChainAvailable`,
1513+
({ networkClientId }) => {
1514+
this.#updateMetadataForNetwork(networkClientId, {
1515+
networkStatus: NetworkStatus.Available,
1516+
});
1517+
},
1518+
);
14941519
}
14951520

14961521
/**
@@ -1898,11 +1923,11 @@ export class NetworkController extends BaseController<
18981923
async #lookupGivenNetwork(networkClientId: NetworkClientId) {
18991924
const { networkStatus, isEIP1559Compatible } =
19001925
await this.#determineNetworkMetadata(networkClientId);
1901-
this.#updateMetadataForNetwork(
1902-
networkClientId,
1926+
1927+
this.#updateMetadataForNetwork(networkClientId, {
19031928
networkStatus,
19041929
isEIP1559Compatible,
1905-
);
1930+
});
19061931
}
19071932

19081933
/**
@@ -1977,11 +2002,10 @@ export class NetworkController extends BaseController<
19772002
}
19782003
}
19792004

1980-
this.#updateMetadataForNetwork(
1981-
this.state.selectedNetworkClientId,
2005+
this.#updateMetadataForNetwork(this.state.selectedNetworkClientId, {
19822006
networkStatus,
19832007
isEIP1559Compatible,
1984-
);
2008+
});
19852009

19862010
if (isInfura) {
19872011
if (networkStatus === NetworkStatus.Available) {
@@ -2001,14 +2025,17 @@ export class NetworkController extends BaseController<
20012025
* Updates the metadata for the given network in state.
20022026
*
20032027
* @param networkClientId - The associated network client ID.
2004-
* @param networkStatus - The network status to store in state.
2005-
* @param isEIP1559Compatible - The EIP-1559 compatibility status to
2028+
* @param metadata - The metadata to store in state.
2029+
* @param metadata.networkStatus - The network status to store in state.
2030+
* @param metadata.isEIP1559Compatible - The EIP-1559 compatibility status to
20062031
* store in state.
20072032
*/
20082033
#updateMetadataForNetwork(
20092034
networkClientId: NetworkClientId,
2010-
networkStatus: NetworkStatus,
2011-
isEIP1559Compatible: boolean | undefined,
2035+
metadata: {
2036+
networkStatus: NetworkStatus;
2037+
isEIP1559Compatible?: boolean | undefined;
2038+
},
20122039
) {
20132040
this.update((state) => {
20142041
if (state.networksMetadata[networkClientId] === undefined) {
@@ -2017,12 +2044,15 @@ export class NetworkController extends BaseController<
20172044
EIPS: {},
20182045
};
20192046
}
2020-
const meta = state.networksMetadata[networkClientId];
2021-
meta.status = networkStatus;
2022-
if (isEIP1559Compatible === undefined) {
2023-
delete meta.EIPS[1559];
2024-
} else {
2025-
meta.EIPS[1559] = isEIP1559Compatible;
2047+
const newMetadata = state.networksMetadata[networkClientId];
2048+
newMetadata.status = metadata.networkStatus;
2049+
2050+
if ('isEIP1559Compatible' in metadata) {
2051+
if (metadata.isEIP1559Compatible === undefined) {
2052+
delete newMetadata.EIPS[1559];
2053+
} else {
2054+
newMetadata.EIPS[1559] = metadata.isEIP1559Compatible;
2055+
}
20262056
}
20272057
});
20282058
}

packages/network-controller/src/constants.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
/**
2-
* Represents the availability state of the currently selected network.
2+
* Represents the availability state of an RPC endpoint. (Yes, this is a
3+
* misnomer.)
34
*/
45
export enum NetworkStatus {
56
/**
6-
* The network may or may not be able to receive requests, but either no
7-
* attempt has been made to determine this, or an attempt was made but was
8-
* unsuccessful.
7+
* It is not determined yet whether the RPC endpoint is available.
98
*/
109
Unknown = 'unknown',
1110
/**
12-
* The network is able to receive and respond to requests.
11+
* The RPC endpoint is consistently returning successful responses.
1312
*/
1413
Available = 'available',
1514
/**
16-
* The network was unable to receive and respond to requests for unknown
17-
* reasons.
15+
* Requests to the RPC endpoint are either slow or are beginning to
16+
* consistently respond with errors.
17+
*/
18+
Degraded = 'degraded',
19+
/**
20+
* Requests to the RPC endpoint have responded with enough errors that it is
21+
* determined to be unavailable.
1822
*/
1923
Unavailable = 'unavailable',
2024
/**
21-
* The network is not only unavailable, but is also inaccessible for the user
22-
* specifically based on their location. This state only applies to Infura
23-
* networks.
25+
* The RPC endpoint is inaccessible for the user based on their location. This
26+
* status only applies to Infura networks.
2427
*/
2528
Blocked = 'blocked',
2629
}

packages/network-controller/src/rpc-service/rpc-service-chain.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import type {
2121
import { projectLogger, createModuleLogger } from '../logger';
2222

2323
const log = createModuleLogger(projectLogger, 'RpcServiceChain');
24+
// const log = console.log.bind(console);
2425

2526
/**
2627
* Statuses that the RPC service chain can be in.

packages/network-controller/src/rpc-service/rpc-service.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export type RpcServiceOptions = {
6161
};
6262

6363
const log = createModuleLogger(projectLogger, 'RpcService');
64+
// const log = console.log.bind(console);
6465

6566
/**
6667
* The maximum number of times that a failing service should be re-run before

0 commit comments

Comments
 (0)