Skip to content

feat(rebalancer): use MultiProtocolCore for message delivery checks#7991

Merged
Mo-Hussain merged 4 commits intomainfrom
feat/rebalancer-multiprotocol-core
Feb 3, 2026
Merged

feat(rebalancer): use MultiProtocolCore for message delivery checks#7991
Mo-Hussain merged 4 commits intomainfrom
feat/rebalancer-multiprotocol-core

Conversation

@Mo-Hussain
Copy link
Collaborator

@Mo-Hussain Mo-Hussain commented Feb 2, 2026

Summary

  • Switches ActionTracker from HyperlaneCore (EVM-only) to MultiProtocolCore to support delivery checks across all VM types
  • Validates mailbox exists in registry addresses at startup (throws exception if missing)
  • Uses adapter.isDelivered() pattern instead of direct mailbox.delivered() call

Test plan

  • pnpm -C typescript/rebalancer build passes
  • pnpm -C typescript/rebalancer test passes (172 tests)
  • Manual test with multi-VM warp route

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Rebalancer now uses a multi-protocol core to support all VM types and performs adapter-based per-destination delivery checks.
    • Adds reorg-safe blockTag computation for more reliable delivery verification.
  • Bug Fixes

    • Registry/mailbox addresses are validated at startup to prevent runtime misconfiguration.
  • Tests

    • Expanded delivery-check tests for per-destination checks, blockTag handling, and multi-destination scenarios.

Switched ActionTracker from HyperlaneCore (EVM-only) to MultiProtocolCore
to support delivery checks across all VM types.

- RebalancerContextFactory validates mailbox exists in registry addresses
- ActionTracker uses adapter.isDelivered() instead of mailbox.delivered()
- Updated tests to use adapter pattern

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@Mo-Hussain Mo-Hussain marked this pull request as ready for review February 2, 2026 10:32
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 2, 2026

📝 Walkthrough

Walkthrough

The rebalancer now uses MultiProtocolCore (via a MultiProtocolProvider) instead of HyperlaneCore for delivery checks, validates mailbox registry addresses at startup, and centralizes per-destination blockTag resolution via a new getConfirmedBlockTag helper.

Changes

Cohort / File(s) Summary
Changeset Entry
.changeset/multiprotocol-core-rebalancer.md
Patch release note documenting switch to MultiProtocolCore and mailbox registry validation.
Rebalancer Context Factory
typescript/rebalancer/src/factories/RebalancerContextFactory.ts
Accepts multiProtocolProvider; validates mailbox registry addresses; builds CoreAddresses map and instantiates MultiProtocolCore; threads extended provider into WarpCore and ActionTracker.
ActionTracker Core Logic
typescript/rebalancer/src/tracking/ActionTracker.ts
Core type changed from HyperlaneCore to MultiProtocolCore; delivery checks use core.adapter(chain).isDelivered(messageId, blockTag); per-destination blockTag resolution via getConfirmedBlockTag; signatures adjusted.
ActionTracker Tests
typescript/rebalancer/src/tracking/ActionTracker.test.ts
Mocks switched to adapter-based isDelivered stubs; expectations and scenarios updated for multi-destination delivery checks and blockTag passing; removed direct mailbox.delivered usage.
Monitor
typescript/rebalancer/src/monitor/Monitor.ts
Removed in-file blockTag helper; computeConfirmedBlockTags delegates to new getConfirmedBlockTag utility.
BlockTag Utility
typescript/rebalancer/src/utils/blockTag.ts
New getConfirmedBlockTag utility: resolves reorg-safe block tag (numeric or named) using MultiProtocolProvider, with logging on errors.
Utils Index Export
typescript/rebalancer/src/utils/index.ts
Re-exported blockTag helper (export * from './blockTag.js').

Sequence Diagram(s)

sequenceDiagram
  participant Factory as RebalancerContextFactory
  participant Provider as MultiProtocolProvider
  participant Core as MultiProtocolCore
  participant Adapter as CoreAdapter/Mailbox
  participant Tracker as ActionTracker

  Factory->>Provider: request extendedMultiProtocolProvider / addresses map
  Provider-->>Factory: extendedMultiProtocolProvider, chain names
  Factory->>Factory: validate mailbox registry addresses (startup)
  Factory->>Core: MultiProtocolCore.fromAddressesMap(addresses, provider)
  Factory-->>Tracker: construct with multiProtocolCore
  Tracker->>Core: adapter(chainName).isDelivered(messageId, blockTag)
  Core->>Adapter: mailbox.isDelivered(messageId, blockTag)
  Adapter-->>Core: boolean delivered
  Core-->>Tracker: delivered status
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • paulbalaji
  • yorhodes
  • ltyu
  • antigremlin
  • Xaroz
  • xeno097

Poem

In swampy code where old cores slept,
New adapters wake and softly pept,
Mailboxes checked, tags mapped just so,
Messages know where they must go,
A wee refactor, steady and deft.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: switching to MultiProtocolCore for message delivery checks, which is the primary architectural shift in this PR.
Description check ✅ Passed The description covers all key aspects: summary of changes, test plan with results, and backward compatibility context. It follows the template structure with meaningful content in each section.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/rebalancer-multiprotocol-core

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@typescript/rebalancer/src/factories/RebalancerContextFactory.ts`:
- Around line 232-250: The code extends MultiProtocolProvider in create() but
only stores the base this.multiProvider, causing rebuilds (e.g., in
createActionTracker()) to lose extended mailbox metadata; modify the class to
store the extended provider (e.g., this.extendedMultiProvider) when you call
MultiProtocolProvider.fromMultiProvider and use that stored extended provider
everywhere you currently call MultiProtocolProvider.fromMultiProvider or rebuild
the provider (notably in createActionTracker()), ensuring
MultiProtocolCore.fromAddressesMap and other consumers use the preserved
extended instance rather than reconstructing from this.multiProvider.

@codecov
Copy link

codecov bot commented Feb 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.02%. Comparing base (cf80e8f) to head (c7bcc0e).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7991   +/-   ##
=======================================
  Coverage   77.02%   77.02%           
=======================================
  Files         117      117           
  Lines        2651     2651           
  Branches      244      244           
=======================================
  Hits         2042     2042           
  Misses        593      593           
  Partials       16       16           
Components Coverage Δ
core 87.80% <ø> (ø)
hooks 71.86% <ø> (ø)
isms 81.10% <ø> (ø)
token 86.67% <ø> (ø)
middlewares 84.98% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

… metadata

The extended MultiProtocolProvider (with mailbox metadata for Sealevel warp adapters) was being lost when createActionTracker() rebuilt it from scratch. Now stored in constructor and reused.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@paulbalaji
Copy link
Collaborator

Review Summary

Nice architectural improvement - switching to MultiProtocolCore with adapters is the right pattern for multi-VM support. A few concerns to address:

1. Startup Reorg Safety Regression (Medium)

initialize() calls syncTransfers()/syncRebalanceActions() without confirmedBlockTags, so delivery checks run at "latest" instead of a safe confirmed block.

Old behavior had a fallback:

const blockTag = providedBlockTag ?? (await this.getConfirmedBlockTag(chainName));

New behavior just passes undefined through, risking false "delivered" status if a recent block reorgs.

Suggestion: Either pass computed tags into initialize(), or restore a fallback for EVM chains when no tag is provided.

2. Registry Scope Over-Validation (Medium)

createActionTracker() validates mailbox presence for all registry chains, not just the warp route chains:

const registryAddresses = await this.registry.getAddresses(); // ALL chains
objMap(registryAddresses, (chain, addrs) => {
  if (!addrs.mailbox) throw new Error(...); // Fails on unrelated chains
});

Suggestion: Filter to this.warpCore.tokens.map(t => t.chainName) before validation.

3. Minor: Manual Test Incomplete

PR checklist shows manual multi-VM test not done. Given this enables Sealevel/Cosmos support, would be good to validate before merge.


Overall the implementation is solid - these are refinements rather than blockers. The third commit correctly preserves the extended MultiProtocolProvider which was the critical fix.

…stry scope

- Created shared getConfirmedBlockTag utility for computing reorg-safe block tags
- ActionTracker.getConfirmedBlockTag now computes on-demand during initialize()
  when no Monitor event has provided cached tags yet, fixing startup reorg safety
- Monitor uses shared utility, removing duplicate code
- RebalancerContextFactory.createActionTracker now only fetches/validates
  registry addresses for warp route chains instead of all registry chains

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@hyper-gonk
Copy link
Contributor

hyper-gonk bot commented Feb 2, 2026

⚙️ Node Service Docker Images Built Successfully

Service Tag
🔑 key-funder c7bcc0e-20260202-155951
🔍 offchain-lookup-server c7bcc0e-20260202-155951
♻️ rebalancer c7bcc0e-20260202-155951
🚀 ts-relayer c7bcc0e-20260202-155951
🕵️ warp-monitor c7bcc0e-20260202-155951
Full image paths
gcr.io/abacus-labs-dev/hyperlane-key-funder:c7bcc0e-20260202-155951
gcr.io/abacus-labs-dev/hyperlane-offchain-lookup-server:c7bcc0e-20260202-155951
gcr.io/abacus-labs-dev/hyperlane-rebalancer:c7bcc0e-20260202-155951
gcr.io/abacus-labs-dev/hyperlane-ts-relayer:c7bcc0e-20260202-155951
gcr.io/abacus-labs-dev/hyperlane-warp-monitor:c7bcc0e-20260202-155951

@Mo-Hussain Mo-Hussain added this pull request to the merge queue Feb 3, 2026
Merged via the queue into main with commit 8c80288 Feb 3, 2026
215 of 217 checks passed
@Mo-Hussain Mo-Hussain deleted the feat/rebalancer-multiprotocol-core branch February 3, 2026 08:36
@github-project-automation github-project-automation bot moved this from In Review to Done in Hyperlane Tasks Feb 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants