Skip to content

fix: include hip3 dexes when building position map on init cp-7.61.6#24293

Merged
gambinish merged 5 commits intomainfrom
fix/hip-3-market-ld-race-condition
Jan 7, 2026
Merged

fix: include hip3 dexes when building position map on init cp-7.61.6#24293
gambinish merged 5 commits intomainfrom
fix/hip-3-market-ld-race-condition

Conversation

@gambinish
Copy link
Copy Markdown
Member

@gambinish gambinish commented Jan 7, 2026

Description

After the HIP-3 refactor that replaced webData3 with individual clearinghouseState/openOrders subscriptions, HIP-3 market positions were not showing up on initial load. Additionally, when they did appear (e.g., after switching accounts), there was a ~1 second delay between crypto perps and HIP-3 positions appearing.

Root Cause

A race condition between subscription creation and DEX discovery:

  1. HyperLiquidSubscriptionService initializes with empty enabledDexs
    subscribeToPositions() creates subscriptions using empty enabledDexs (main DEX only)
  2. DEX discovery runs asynchronously via buildAssetMapping()
  3. updateFeatureFlags() is called with discovered DEXs, but subscriptions already exist for main DEX only
  4. HIP-3 positions never appear because no subscriptions were created for HIP-3 DEXs

Why switching accounts worked: Account switching triggers reconnectWithNewContext() which performs a full reinitialization. During reconnection, buildAssetMapping() (DEX discovery) completes before createUserDataSubscription() is called, so enabledDexs is already populated and HIP-3 subscriptions are correctly created.

Solution

  1. Promise-based DEX discovery wait
    Added dexDiscoveryPromise and dexDiscoveryResolver fields
    createUserDataSubscription() waits for DEX discovery when HIP-3 is enabled but enabledDexs is empty
    updateFeatureFlags() resolves the promise when DEXs are discovered
    5-second timeout prevents indefinite waiting
  2. Synchronized position subscription notifications
    Added expectedDexs and initializedDexs tracking sets
    aggregateAndNotifySubscribers() waits for ALL expected DEXs to send initial data before notifying
    Ensures crypto and HIP-3 positions appear simultaneously
  3. Consistent position ordering
    Modified aggregation to always show main DEX (crypto perps) first, then HIP-3 positions

Error handling:

  1. Failed DEX subscriptions are removed from expectedDexs so they don't block notifications for other DEXs
  2. Both ensureClearinghouseStateSubscription and ensureOpenOrdersSubscription mark DEXs as initialize

Changes to HyperLiquidSubscriptionService.ts:

  • Added DEX discovery synchronization promise mechanism
  • Added expectedDexs/initializedDexs tracking for synchronized notifications
  • Added wait logic in createUserDataSubscription() for HIP-3 DEX discovery
  • Modified aggregateAndNotifySubscribers() to wait for all DEXs before notifying
  • Modified aggregation ordering to put main DEX first
  • Added initializedDexs.add() to both subscription callbacks
  • Added expectedDexs.delete() in catch blocks for failed subscriptions
  • Added cleanup for tracking state in cleanupSharedWebData3Subscription()
  • Updated tests to call updateFeatureFlags() to simulate DEX discovery before subscribing in HyperLiquidSubscriptionService.test.ts

Changelog

CHANGELOG entry: Fixes bug where hip3 positions were not loaded on initial PerpsContext load

Related issues

Fixes:

Manual testing steps

Verified crypto and HIP-3 positions appear simultaneously on initial load
Verified position ordering (crypto first, HIP-3 second)
Verified account switching still works correctly
Verified that TP/SL still works as intended

Screenshots/Recordings

Screen.Recording.2026-01-07.at.11.26.25.AM.mov

Pre-merge author checklist

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.

Note

Improves HIP-3 multi-DEX handling and subscription lifecycle to deliver consistent, aggregated user data.

  • Introduces DEX discovery synchronization (waitForDexDiscovery) and resolves pending waits in updateFeatureFlags
  • Tracks expectedDexs/initializedDexs to delay notifications until all DEXs send initial data; orders aggregation preserves main DEX first
  • When HIP-3 is enabled, establishes per-DEX clearinghouseState and openOrders subscriptions upon feature-flag updates if user-data subscribers exist
  • subscribeTo... waits for DEX discovery before creating HIP-3 subscriptions; error paths avoid blocking other DEX updates
  • Aggregation and caches updated to merge per-DEX positions/orders/account; clearing clearAll resets DEX tracking
  • Tests adjusted to simulate DEX discovery and verify restoration and TP/SL inclusion in orders

Written by Cursor Bugbot for commit 67f8a9a. This will update automatically on new commits. Configure here.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 7, 2026

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-perps Perps team label Jan 7, 2026
@github-actions github-actions bot added the size-S label Jan 7, 2026
michalconsensys
michalconsensys previously approved these changes Jan 7, 2026
michalconsensys
michalconsensys previously approved these changes Jan 7, 2026
@gambinish gambinish marked this pull request as ready for review January 7, 2026 19:15
@gambinish gambinish requested a review from a team as a code owner January 7, 2026 19:15
@gambinish gambinish changed the title fix: include hip3 dexes when building position map on init fix: include hip3 dexes when building position map on init cp-7.61.6 Jan 7, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 7, 2026

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokePerps
  • Risk Level: low
  • AI Confidence: 92%
click to see 🤖 AI reasoning details

The changes are isolated to the HyperLiquidSubscriptionService within the Perps (Perpetuals trading) module. The modifications add DEX discovery synchronization for HIP-3 support, ensuring that subscriptions wait for DEX discovery before creating per-DEX subscriptions, and that all DEXs send initial data before notifying subscribers.

Key observations:

  1. All changes are within app/components/UI/Perps/services/ - a feature-specific directory
  2. The service is only imported by HyperLiquidProvider within the same Perps module
  3. No changes to core wallet functionality, Engine, or controllers outside Perps
  4. The test file updates properly accommodate the new synchronization behavior
  5. The changes are additive improvements to existing functionality (better synchronization) rather than breaking changes

This is a well-scoped change to the Perpetuals trading feature that should only require SmokePerps tests to validate.

View GitHub Actions results

this.dexAccountCache.set(cacheKey, accountState);

// Mark this DEX as initialized (has sent first data)
this.initializedDexs.add(cacheKey);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial positions may briefly lack TP/SL data

Low Severity

Both clearinghouseState and openOrders callbacks add the same DEX to initializedDexs, but only one callback needs to fire for a DEX to be considered "initialized." If clearinghouseState fires before openOrders, the synchronization check passes and subscribers receive positions without TP/SL data (since orders haven't been cached yet at line 1269). A subsequent openOrders callback will update the data, causing a brief flicker where positions appear without their take-profit/stop-loss values on initial load.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link
Copy Markdown
Member Author

@gambinish gambinish Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is acceptable, I haven't been able to reproduce this, and we don't show TP/SL data on the main PerpsHome page anyway. We can circle back on this after if it becomes an issue but I don't think it should block this hotifx

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The edge cases are there likely due to the complexity of this service. It may be worth splitting it into multiple services or simplifying it sometime later

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Jan 7, 2026

@gambinish gambinish enabled auto-merge January 7, 2026 19:50
@gambinish gambinish added this pull request to the merge queue Jan 7, 2026
Merged via the queue into main with commit be25b63 Jan 7, 2026
126 of 131 checks passed
@gambinish gambinish deleted the fix/hip-3-market-ld-race-condition branch January 7, 2026 20:18
@github-actions github-actions bot locked and limited conversation to collaborators Jan 7, 2026
@metamaskbot metamaskbot added the release-7.62.0 Issue or pull request that will be included in release 7.62.0 label Jan 7, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.62.0 Issue or pull request that will be included in release 7.62.0 size-M team-perps Perps team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants