Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/network-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- The event payload has been changed as well: `failoverEndpointUrl` has been renamed to `endpointUrl`, and `endpointUrl` has been renamed to `primaryEndpointUrl`. In addition, `networkClientId` and `attempt` have been added to the payload.
- **BREAKING:** Update `AbstractRpcService`/`RpcServiceRequestable` to remove `{ isolated: true }` from the `onBreak` event data type ([#7166](https://github.com/MetaMask/core/pull/7166))
- This represented the error produced when `.isolate` is called on a Cockatiel circuit breaker policy, which we never do.
- Statuses of networks (captured in the NetworkController `networksMetadata` state property) are now kept up to date as requests are made ([#7186](https://github.com/MetaMask/core/pull/7186))
- Move peer dependencies for controller and service packages to direct dependencies ([#7209](https://github.com/MetaMask/core/pull/7209))
- The dependencies moved are:
- `@metamask/error-reporting-service` (^3.0.0)
Expand Down
62 changes: 46 additions & 16 deletions packages/network-controller/src/NetworkController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1451,6 +1451,31 @@ export class NetworkController extends BaseController<
`${this.name}:updateNetwork`,
this.updateNetwork.bind(this),
);

this.messenger.subscribe(
`${this.name}:rpcEndpointChainUnavailable`,
({ networkClientId }) => {
this.#updateMetadataForNetwork(networkClientId, {
networkStatus: NetworkStatus.Unavailable,
});
},
);
this.messenger.subscribe(
`${this.name}:rpcEndpointChainDegraded`,
({ networkClientId }) => {
this.#updateMetadataForNetwork(networkClientId, {
networkStatus: NetworkStatus.Degraded,
});
},
);
this.messenger.subscribe(
`${this.name}:rpcEndpointChainAvailable`,
({ networkClientId }) => {
this.#updateMetadataForNetwork(networkClientId, {
networkStatus: NetworkStatus.Available,
});
},
);
}

/**
Expand Down Expand Up @@ -1858,11 +1883,11 @@ export class NetworkController extends BaseController<
async #lookupGivenNetwork(networkClientId: NetworkClientId) {
const { networkStatus, isEIP1559Compatible } =
await this.#determineNetworkMetadata(networkClientId);
this.#updateMetadataForNetwork(
networkClientId,

this.#updateMetadataForNetwork(networkClientId, {
networkStatus,
isEIP1559Compatible,
);
});
}

/**
Expand Down Expand Up @@ -1937,11 +1962,10 @@ export class NetworkController extends BaseController<
}
}

this.#updateMetadataForNetwork(
this.state.selectedNetworkClientId,
this.#updateMetadataForNetwork(this.state.selectedNetworkClientId, {
networkStatus,
isEIP1559Compatible,
);
});

if (isInfura) {
if (networkStatus === NetworkStatus.Available) {
Expand All @@ -1961,14 +1985,17 @@ export class NetworkController extends BaseController<
* Updates the metadata for the given network in state.
*
* @param networkClientId - The associated network client ID.
* @param networkStatus - The network status to store in state.
* @param isEIP1559Compatible - The EIP-1559 compatibility status to
* @param metadata - The metadata to store in state.
* @param metadata.networkStatus - The network status to store in state.
* @param metadata.isEIP1559Compatible - The EIP-1559 compatibility status to
* store in state.
*/
#updateMetadataForNetwork(
networkClientId: NetworkClientId,
networkStatus: NetworkStatus,
isEIP1559Compatible: boolean | undefined,
metadata: {
networkStatus: NetworkStatus;
isEIP1559Compatible?: boolean | undefined;
},
) {
this.update((state) => {
if (state.networksMetadata[networkClientId] === undefined) {
Expand All @@ -1977,12 +2004,15 @@ export class NetworkController extends BaseController<
EIPS: {},
};
}
const meta = state.networksMetadata[networkClientId];
meta.status = networkStatus;
if (isEIP1559Compatible === undefined) {
delete meta.EIPS[1559];
} else {
meta.EIPS[1559] = isEIP1559Compatible;
const newMetadata = state.networksMetadata[networkClientId];
newMetadata.status = metadata.networkStatus;

if ('isEIP1559Compatible' in metadata) {
if (metadata.isEIP1559Compatible === undefined) {
delete newMetadata.EIPS[1559];
} else {
newMetadata.EIPS[1559] = metadata.isEIP1559Compatible;
}
}
});
}
Expand Down
28 changes: 18 additions & 10 deletions packages/network-controller/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
/**
* Represents the availability state of the currently selected network.
* Represents the availability status of an RPC endpoint. (Regrettably, the
* name of this type is a misnomer.)
*
* The availability status is set both automatically (as requests are made) and
* manually (when `lookupNetwork` is called).
*/
export enum NetworkStatus {
/**
* The network may or may not be able to receive requests, but either no
* attempt has been made to determine this, or an attempt was made but was
* unsuccessful.
* Either the availability status of the RPC endpoint has not been determined,
* or request that `lookupNetwork` performed returned an unknown error.
*/
Unknown = 'unknown',
/**
* The network is able to receive and respond to requests.
* The RPC endpoint is consistently returning successful (2xx) responses.
*/
Available = 'available',
/**
* The network was unable to receive and respond to requests for unknown
* reasons.
* Either the last request to the RPC endpoint was either too slow, or the
* endpoint is consistently returning errors and the number of retries has
* been reached.
*/
Degraded = 'degraded',
/**
* The RPC endpoint is consistently returning enough 5xx errors that requests
* have been paused.
*/
Unavailable = 'unavailable',
/**
* The network is not only unavailable, but is also inaccessible for the user
* specifically based on their location. This state only applies to Infura
* networks.
* The RPC endpoint is inaccessible for the user based on their location. This
* status only applies to Infura networks.
*/
Blocked = 'blocked',
}
Expand Down
Loading