feat(network-controller): force RPC failover via remote flag#9175
feat(network-controller): force RPC failover via remote flag#9175cryptodev-2s wants to merge 34 commits into
Conversation
Thread isRpcFailoverForced through createNetworkClient, createRpcServiceChain, and createAutoManagedNetworkClient. When the force flag is on for an Infura endpoint that has failover URLs, the endpoint chain is built from failovers only, bypassing Infura entirely.
… param Add a disableRpcFailoverForced reconstruction test mirroring the sibling, and add the missing isRpcFailoverForced JSDoc tags.
…e-enabled flag Subscribe to RemoteFeatureFlagController state changes and read the forced failover flag on init, reconstructing affected network clients. Add public enableRpcFailoverForced/disableRpcFailoverForced methods and their messenger action types. Update existing tests for the new createAutoManagedNetworkClient argument and the new auto-managed client methods.
Export NetworkControllerEnableRpcFailoverForcedAction and NetworkControllerDisableRpcFailoverForcedAction, and update the init JSDoc to mention both failover flags.
…form prefix Rename the remote flag key from wallet-framework-rpc-failover-force-enabled to core-platform-rpc-failover-force-enabled to match the team's new name.
a049dda to
0bd5566
Compare
|
@metamaskbot publish-preview |
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
54126df to
0bd5566
Compare
Resolve create-network-client.ts by keeping main's URL-based isInfura (#9125) plus the forced-failover branch. Resolve NetworkController.test.ts by dropping the stale megaeth-testnet expectation that main replaced with megaeth-testnet-v2.
|
@metamaskbot publish-preview |
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
|
@metamaskbot publish-preview |
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
|
@metamaskbot publish-preview |
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
| * @param newIsRpcFailoverForced - Whether or not to force RPC failover. | ||
| */ | ||
| #updateRpcFailoverForced(newIsRpcFailoverForced: boolean): void { | ||
| if (this.#isRpcFailoverForced === newIsRpcFailoverForced) { |
There was a problem hiding this comment.
If RPC failover is disabled generally, should this still work?
| this.#updateRpcFailoverEnabled(getIsRpcFailoverEnabled(state)); | ||
| this.#updateRpcFailoverForced(getIsRpcFailoverForced(state)); |
There was a problem hiding this comment.
I wonder if we can combine these two 🤔
There was a problem hiding this comment.
Pulled the duplicated registry walk into a shared #forEachNetworkClientWithFailover helper, so the two methods are now just their guard plus the per client action.
I stopped short of fully merging them into one pass. A true single rebuild per client would mean reworking the AutoManagedNetworkClient enable/disable methods (they each eagerly destroy and rebuild) and the public enableRpcFailover/disableRpcFailover path, which is the shipped isRpcFailoverEnabled feature. Felt out of scope here, happy to do it as a follow up if you want.
Drop the NetworkController enableRpcFailoverForced/disableRpcFailoverForced methods, their messenger actions, and exports. Forced failover is driven entirely by the remote feature flag; nothing calls these imperatively.
…eForcedRpcFailover
…loverMode Replace the boolean walletFrameworkRpcFailoverEnabled and the forced flag with a single corePlatformRpcFailoverMode flag (disabled/enabled/forced). The selectors derive both isRpcFailoverEnabled and isRpcFailoverForced from it, defaulting to disabled. NetworkController no longer reads walletFrameworkRpcFailoverEnabled.
| #isRpcFailoverEnabled = false; | ||
|
|
||
| #isRpcFailoverForced = false; |
There was a problem hiding this comment.
Instead of having two booleans, let's bring the state directly into the controller. Then we can simplify to one RemoteFeatureFlagController:stateChange subscription too
There was a problem hiding this comment.
Done in e690b24. The controller now tracks a single #rpcFailoverMode field with one RemoteFeatureFlagController:stateChange subscription via getRpcFailoverMode, and the createAutoManagedNetworkClient call sites derive the enabled/forced booleans from the mode.
| }); | ||
|
|
||
| this.#isRpcFailoverEnabled = newIsRpcFailoverEnabled; | ||
| } |
There was a problem hiding this comment.
Since we are making a breaking change we can remove enableRpcFailover and disableRpcFailover on NetworkController
There was a problem hiding this comment.
Yes I am planning to do this in a follow up PR
There was a problem hiding this comment.
Finally made part of this pr to close #9175 (comment)
…controller Replace the two #isRpcFailover* booleans and their two RemoteFeatureFlagController subscriptions with a single #rpcFailoverMode field, one subscription via getRpcFailoverMode, and one #updateRpcFailover method. The createAutoManagedNetworkClient call sites derive the enabled/forced booleans from the mode inline.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e690b24. Configure here.
…lover Remove the imperative enableRpcFailover/disableRpcFailover methods, their messenger actions, and exported types. RPC failover is driven entirely by the corePlatformRpcFailoverMode remote feature flag.
|
@metamaskbot publish-preview |
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |

Explanation
RPC failover is now controlled by a single remote feature flag,
corePlatformRpcFailoverMode, a string with three values:disabled: failover URLs are ignored. Traffic stays on the primary endpoint (Infura only).enabled: traffic diverts to the configured failover URLs when the primary endpoint is unavailable. This is the existing automatic failover behavior.forced: Infura endpoints that have failover URLs route all traffic (including block tracker polling) to those failover URLs, bypassing Infura entirely. Infura endpoints without failover URLs stay on Infura, and custom endpoints are unaffected.The value defaults to
disabledwhen the flag is absent or unrecognized.forcedis the emergency kill switch: if the automatic failover logic itself ever misbehaves, it deterministically takes Infura out of the path.BREAKING: the controller no longer reads
walletFrameworkRpcFailoverEnabled(theenabledmode replaces it), and the imperativeNetworkController.enableRpcFailover/disableRpcFailovermethods and their messenger actions are removed. Failover is driven entirely by the remote flag. Internally the controller tracks a singleRpcFailoverModeapplied through oneRemoteFeatureFlagController:stateChangesubscription.Note:
corePlatformRpcFailoverModeis a server side contract, delivered camelCase by the ClientConfigAPI. The oldwalletFrameworkRpcFailoverEnabledflag stays in LaunchDarkly for already shipped clients.References
Checklist
Note
High Risk
Breaking API and flag contract changes affect all wallet RPC traffic paths;
forcedcan shift production Infura load to failovers cluster-wide when the flag is set.Overview
BREAKING: RPC failover is controlled only by the remote string flag
corePlatformRpcFailoverMode(disabled|enabled|forced), replacingwalletFrameworkRpcFailoverEnabledand removingNetworkController.enableRpcFailover/disableRpcFailoverand their messenger actions.enabledkeeps the existing behavior (Infura primary, divert tofailoverRpcUrlswhen unavailable).forcedis new: for Infura hosts with failover URLs, the RPC chain uses only those failovers (including block polling), skipping Infura; custom primaries are unchanged.NetworkControllertracksRpcFailoverMode, applies flag changes via#updateRpcFailoveron clients with failovers, and passesisRpcFailoverForcedinto network client creation.getAvailableEndpointscentralizes endpoint ordering; auto-managed clients gainenableForcedRpcFailover/disableForcedRpcFailoverfor internal rebuilds.Changelog, exports, and tests (including forced routing integration tests) are updated accordingly.
Reviewed by Cursor Bugbot for commit 0f31429. Bugbot is set up for automated code reviews on this repo. Configure here.