Skip to content

fix(fx-tunnel-relayer): relay all MessageSent events in a transaction - #4963

Open
droplet-rl wants to merge 1 commit into
masterfrom
droplet/T90K0AL22-C0ADKTEEETA-1785071332-160749
Open

fix(fx-tunnel-relayer): relay all MessageSent events in a transaction#4963
droplet-rl wants to merge 1 commit into
masterfrom
droplet/T90K0AL22-C0ADKTEEETA-1785071332-160749

Conversation

@droplet-rl

Copy link
Copy Markdown
Contributor

Motivation

When a single Polygon transaction emits multiple MessageSent events from the OracleChildTunnel (e.g. two OO disputes bridged atomically in one transaction), the relayer only ever relays the first message. matic.js buildPayloadForExit(burnTxHash, logEventSig, isFast, index = 0) proves the index-th log matching the event signature within the transaction, and the relayer never passes an index — so every event in the same transaction produces an identical proof for message #1. The first submission succeeds and the rest revert with FxRootTunnel: EXIT_ALREADY_PROCESSED, which is swallowed silently. The unrelayed price requests never reach the DVM and the corresponding OO requests stay stuck in Disputed with bonds locked.

This happened in production on 2026-07-22/23: 0x0874d7b0… and 0xc6d74727… each bridged two disputes; in both cases the second dispute never reached the DVM. Both stuck messages have since been relayed manually with proofs built at tokenIndex=1 (0x37ba42b6…, 0xeaf7b45c…).

Summary

  • For each MessageSent event, compute its position among all logs matching the MessageSent signature in its transaction receipt (fetched once per transaction) and pass that index to buildPayloadForExit, so every message in a multi-message transaction is proven and relayed.
  • Log at debug level instead of returning silently when a relay reverts with EXIT_ALREADY_PROCESSED, so legitimate skips remain visible.

Details

The index is computed against all logs in the receipt with the MessageSent topic (matching matic.js getAllLogIndices semantics, which filters by topic only, not emitter) rather than just this contract's events, so the proof index stays correct even if another fx-tunnel contract emitted MessageSent in the same transaction.

Testing

  • New unit tests created
  • All existing tests pass

New test bundles two requestPrice calls into one transaction via Multicall3 and asserts both messages are proven at indices 0 and 1 and both relays are submitted. yarn workspace @uma/fx-tunnel-relayer test passes locally.

Issue(s)

Fixes #4962

🤖 Generated with Claude Code

@droplet-rl
droplet-rl requested a review from mrice32 as a code owner July 26, 2026 15:14
@droplet-rl
droplet-rl requested a review from Reinis-FRP July 26, 2026 15:14
@droplet-rl
droplet-rl requested a review from chrismaree as a code owner July 26, 2026 15:14
@droplet-rl
droplet-rl requested a review from md0x July 26, 2026 15:14
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

A Polygon transaction bridging multiple price requests emits multiple
MessageSent events, but the exit proof was always built for the first
matching log (matic.js buildPayloadForExit defaults to index 0). Every
event in such a transaction produced a proof for message #1; the first
relay succeeded and the rest reverted with EXIT_ALREADY_PROCESSED, which
was swallowed silently, so the remaining messages never reached the DVM.

Compute each event's position among the MessageSent logs in its
transaction receipt and prove exactly that log, and log skips caused by
EXIT_ALREADY_PROCESSED at debug level instead of returning silently.

Fixes #4962

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: droplet-rl <284132418+droplet-rl@users.noreply.github.com>
@droplet-rl
droplet-rl force-pushed the droplet/T90K0AL22-C0ADKTEEETA-1785071332-160749 branch from 85cc3fe to 480f744 Compare July 26, 2026 15:15
@droplet-rl

Copy link
Copy Markdown
Contributor Author

Noting for reviewers: the Codex automated review was skipped on this PR because the Codex account hit its usage limit — no review feedback was produced. No code changes needed in response. Once the quota resets, a re-review can be requested by commenting @codex review; in the meantime this PR still needs a human review.

@droplet-rl

Copy link
Copy Markdown
Contributor Author

🔎 View trace

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits. You can see your limits in the Codex usage dashboard.

@droplet-rl

Copy link
Copy Markdown
Contributor Author

Duplicate quota notification — my previous comment inadvertently re-triggered Codex by spelling out the re-review command, and it failed on the same usage limit. Nothing actionable here; ignore both bot messages. Once the Codex quota resets, a re-review can be requested with the usual mention command (not spelled out here to avoid re-triggering it). Human review of this PR can proceed in the meantime.

@droplet-rl

Copy link
Copy Markdown
Contributor Author

🔎 View trace

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fx-tunnel-relayer: only the first MessageSent event per Polygon transaction is relayed

1 participant