Commit 57ca8f6
committed
chore(runway): cherry-pick fix(perps): fix HIP-3 asset ID lookup failure from dual-cache desync cp-7.70.1 (#27854)
## **Description**
Fix HIP-3 asset ID lookup failure (`"Asset ID not found for
xyz:BRENTOIL"`) that blocked trading on HIP-3 markets when navigating
via the old Perps tab layout.
**Root cause**: Dual-cache desync between `#cachedValidatedDexs` (string
DEX names) and `#cachedAllPerpDexs` (raw API objects for `perpDexIndex`
computation). The standalone preload path
(`#getStandaloneValidatedDexs`) populated one cache but not the other.
When `#buildAssetMapping` later ran, it found "xyz" in `dexsToMap` but
couldn't compute its `perpDexIndex` because `#cachedAllPerpDexs` was
null.
**Why old Perps tab vs new Homepage Sections**: Both layouts sit inside
`Wallet/index.tsx`, which calls `startMarketDataPreload()` on mount.
This fires standalone HTTP calls that populate `#cachedValidatedDexs`
but not `#cachedAllPerpDexs`.
- **New homepage sections**: `PerpsSectionWithProvider` mounts
immediately. Stream hooks fire `ensureReady()` before or concurrently
with the standalone preload. Since `#cachedValidatedDexs` is often still
null, `fetchValidatedDexsInternal` runs fresh and sets **both** caches
correctly.
- **Old tab layout**: The Perps tab doesn't mount until the user taps
it. By that time, `startMarketDataPreload()` has already completed →
`#cachedValidatedDexs` is populated by standalone. When the tab mounts →
`getValidatedDexs()` → **cache hit** → `fetchValidatedDexsInternal` is
never called → `#cachedAllPerpDexs` stays null → `buildAssetMapping`
can't find "xyz".
**Changes (1 file, 3 sites)**:
1. **Root cause fix**: `#getStandaloneValidatedDexs` now sets
`this.#cachedAllPerpDexs = allDexs` after a successful `perpDexs()`
call, keeping both caches in sync.
2. **Cache poisoning fix**: Removed `this.#cachedAllPerpDexs =
this.#cachedAllPerpDexs ?? [null]` from the catch block in
`#buildAssetMapping`.
3. **Cache poisoning fix**: Replaced persistent `if (!cache) { cache =
[null] }` with local `const allPerpDexs = cache ?? [null]` — consumers
read the cache, only the owner writes it.
## **Changelog**
CHANGELOG entry: Fixed a bug where closing positions on HIP-3 markets
(e.g., xyz:BRENTOIL) failed with "Asset ID not found" when navigating
via the Perps tab
## **Related issues**
Fixes: HIP-3 asset ID lookup failure on old Perps tab layout
## **Manual testing steps**
```gherkin
Feature: HIP-3 position management via Perps tab
Scenario: user closes a HIP-3 position from the old Perps tab
Given user has an open position on a HIP-3 market (e.g., xyz:BRENTOIL)
And user is using the old tab layout (homepage redesign v1 disabled)
When user navigates to the Perps tab
And user taps close on the xyz:BRENTOIL position
Then the position closes successfully without "Asset ID not found" error
Scenario: user opens a HIP-3 position from the old Perps tab
Given user is on the Perps tab (old layout)
When user navigates to xyz:BRENTOIL market and places a market order
Then the order executes successfully with correct asset ID routing
```
## **Screenshots/Recordings**
### **Before**
Metro logs show the desync:
```
getValidatedDexs CACHE HIT {"cachedAllNull": true, "dexs": [null, "xyz"]}
buildAssetMapping state {"allPerpDexsLen": 1, "cachedAllNull": true}
Could not find perpDexIndex for DEX xyz
Asset ID not found for xyz:BRENTOIL
```
### **After**
Metro logs show both caches in sync:
```
buildAssetMapping state {"allPerpDexsLen": 8, "cachedAllNull": false, "dexsToMap": [null, "xyz"]}
Asset map state at order time {"assetExistsInMap": true, "hip3AssetsCount": 54, "totalAssetsInMap": 283}
Resolved DEX-specific asset ID {"assetId": 110049, "coin": "xyz:BRENTOIL"}
usePerpsClosePosition: Close result {"success": true, "orderId": "359617825254"}
```
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches HIP-3 market routing/asset-ID mapping in
`HyperLiquidProvider`, so a mistake could break trading on some perps
markets; scope is small and localized to cache population/fallback
behavior.
>
> **Overview**
> Fixes a HIP-3 asset mapping failure where `#cachedValidatedDexs` could
be populated via the standalone preload path while `#cachedAllPerpDexs`
stayed `null`, leading to missing `perpDexIndex` during
`#buildAssetMapping`.
>
> `#getStandaloneValidatedDexs()` now also populates
`#cachedAllPerpDexs` after a successful `perpDexs()` call, and
`#buildAssetMapping()` no longer “poisons” the shared cache with a
persistent `[null]` fallback (it uses a local fallback instead).
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c925609. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->1 parent 9f24f30 commit 57ca8f6
1 file changed
Lines changed: 10 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2119 | 2119 | | |
2120 | 2120 | | |
2121 | 2121 | | |
2122 | | - | |
2123 | 2122 | | |
2124 | 2123 | | |
2125 | 2124 | | |
2126 | | - | |
2127 | | - | |
2128 | | - | |
2129 | | - | |
2130 | | - | |
2131 | | - | |
| 2125 | + | |
| 2126 | + | |
| 2127 | + | |
| 2128 | + | |
2132 | 2129 | | |
2133 | 2130 | | |
2134 | 2131 | | |
| |||
4772 | 4769 | | |
4773 | 4770 | | |
4774 | 4771 | | |
| 4772 | + | |
| 4773 | + | |
| 4774 | + | |
| 4775 | + | |
| 4776 | + | |
| 4777 | + | |
4775 | 4778 | | |
4776 | 4779 | | |
4777 | 4780 | | |
| |||
0 commit comments