bug(operator): MegaETH/LCD rate-limit gaps stall getDeposit and Terra writer approval #164

Open
opened 2026-09-04 03:53:09 +00:00 by PlasticDigits · 1 comment

Reporter observed a stuck bridge transfer for xchain hash 0xd2350e21e090a91260457cfd6e697a5acfde2b2d1d32d958a8d3f9ba323f1951. Likely cause: LCD/RPC throttling while verifying source deposits and polling Terra withdrawals, especially under MegaETH public RPC quality pressure. On-chain withdraw rate limits must stay.

Formatted engineering report (current codebase, constraints, direction, acceptance, and test plans) is in the comment below.

Reporter observed a stuck bridge transfer for xchain hash `0xd2350e21e090a91260457cfd6e697a5acfde2b2d1d32d958a8d3f9ba323f1951`. Likely cause: LCD/RPC throttling while verifying source deposits and polling Terra withdrawals, especially under MegaETH public RPC quality pressure. On-chain withdraw rate limits must stay. Formatted engineering report (current codebase, constraints, direction, acceptance, and test plans) is in the comment below.
Author
Owner

Summary

A reporter observed a stuck bridge transfer for xchain hash 0xd2350e21e090a91260457cfd6e697a5acfde2b2d1d32d958a8d3f9ba323f1951 (valid V2 32-byte id; Terra encoding 0jUOIeCQqRJgRXz9bml6Ws/eKy0dMtlYqNP5ujI/GVE=). Operator triage points at LCD/RPC throttling while verifying source deposits and polling Terra withdrawals, especially on MegaETH, whose public RPC quality is known-poor.

This is a client/operator resilience gap, not a request to weaken on-chain withdraw rate limits. EVM eth_getLogs already has method-level fallback and retry classification for HTTP 429. Source getDeposit verification and the Terra writer poll path do not: they use a single RPC/LCD URL, and Terra writer does not apply the EVM negative-verify backoff. Frontend LCD_CONFIG throttle knobs exist but are unused, while Transfer Status polls every chain in parallel.

Treat the reported hash as a diagnostic example (confirm its current stage if still pending). The implementation is the systemic rate-limit-aware fallback/backoff for source verification and Terra LCD polling.


Current codebase

Transfer and approval flow

  1. User deposits on source; on-chain deposit is keyed by xchain_hash_id.
  2. User (or frontend auto-submit) calls WithdrawSubmit on dest; pending withdraw uses the same hash.
  3. Operator discovers unapproved withdraws (EVM: getPendingWithdrawHashes + events; Terra: LCD active_withdrawals / legacy pending_withdrawals).
  4. Operator verifies the source deposit (getDeposit / Terra deposit query / Solana PDA). Fail closed: never approve without a verified deposit.
  5. On success: WithdrawApprove; after the cancel window, execute (unlock/mint).
  6. Frontend Transfer Status re-queries all chains every POLLING_INTERVAL (default 10s).

Two different “rate limits” must not be conflated:

  1. On-chain withdraw caps (security): Terra RATE_LIMITS, EVM TokenRateLimit, Solana WithdrawRateLimit. These must stay.
  2. HTTP/RPC provider throttling: 429 / “too many requests” / MegaETH public RPC flakiness. Operator and frontend must slow down and failover without removing (1).

What is already resilient

  • EVM eth_getLogs: method-level URL fallback + chain-id confirm (rpc_fallback.rs, INV-OP-W1–W3 / issue #138).
  • Retry classifier treats 429 / rate-limit / provider log-limit messages as transient (multichain_rs::is_retryable_evm_rpc_error_message).
  • EVM writer: poll interval, jittered RPC backoff, bounded NegativeVerifySchedule (INV-OP-W4).
  • Terra watcher: 429/503/timeout classified as transient.
  • Active-withdrawals index (issue #139) reduces LCD load from full historical maps.

Gaps that match this stuck-transfer class

  • source_chain_endpoints stores one RPC URL per chain (writers/mod.rs). Comma-separated EVM_RPC_URL / EVM_CHAIN_N_RPC_URL fallbacks are not used for getDeposit.
  • verify_evm_deposit_on_chain in writers/evm.rs and writers/terra.rs calls getDeposit on that single URL.
  • TerraWriter::poll_and_approve uses a single TERRA_LCD_URL. On LCD failure it logs and skips the cycle (Ok); there is no LCD URL fallback and no NegativeVerifySchedule.
  • Frontend fetchLcd / queryContract try sequential URL fallbacks but ignore LCD_CONFIG.minRequestInterval and endpointCooldown. Transfer Status (useMultiChainLookup) fans out parallel EVM + Terra + Solana queries every 10s.
  • There is no dedicated stuck-transfer detector. Symptoms appear as operator no_evm_deposit / evm_errors, EVM negative-retry suppression, or Transfer Status stalling after cancel-window expiry.

Why a new implementation is needed

MegaETH public RPC is intentionally treated as poor-quality. Client-side throttling and failover are required, not optional debt. Today a 429 or flaky getDeposit on the primary MegaETH URL can leave a real deposit unverified every Terra poll cycle, so dest WithdrawSubmit sits unapproved and the transfer looks stuck.

Changing only the frontend poll interval cannot fix operator source verification. Relaxing on-chain withdraw caps would increase drain on key compromise and does not address HTTP 429. The missing work is to reuse the existing EVM log-fallback and negative-retry designs for getDeposit and Terra LCD list/verify polls, and to actually apply the frontend LCD throttle constants.


Constraints and guardrails

  1. Do not relax on-chain withdraw rate limits (Terra OPERATIONAL_NOTES; EVM TokenRateLimit; Solana INV-W4). Fix UX/ops if a transfer is delayed by those caps (INV-UX2).
  2. Fail-closed source verification (INV-OP-W1): never approve without a verified deposit, including when every RPC/LCD fallback fails.
  3. Keep contiguous log cursor (INV-OP-W2) and chain-id confirm on fallbacks (INV-OP-W3).
  4. Bounded negative-retry cache (INV-OP-W4): attacker hashes must not grow memory without bound. Apply the same bound to Terra writer.
  5. Validated poll/backoff env bounds (INV-OP-W8). Do not remove them to “unstick” faster.
  6. No secret RPC URLs in logs (INV-OP-W9).
  7. Keep the active-withdrawals index (#139); do not return to full historical LCD walks.
  8. MegaETH dedicated/reliable RPC plus comma-separated fallbacks is the ops preference; code must still behave when the public endpoint is the only one configured.
  9. Do not log user-identifying data. Hash hex (truncated if needed) and error class are enough.

Relevant files

Area Files
Terra writer LCD poll + getDeposit packages/operator/src/writers/terra.rs, terra_list.rs
EVM writer + negative retry packages/operator/src/writers/evm.rs, negative_retry.rs, poll_cursor.rs, retry.rs
Single-URL source map packages/operator/src/writers/mod.rs
Poll/backoff bounds packages/operator/src/poll_config.rs
EVM method fallback packages/operator/src/rpc_fallback.rs
Terra watcher 429 handling packages/operator/src/watchers/terra.rs
Config (comma-separated EVM RPC; single Terra LCD) packages/operator/src/config.rs
Shared 429 classifier packages/multichain-rs/src/evm/rpc_fallback.rs
Frontend LCD client (unused throttle knobs) packages/frontend/src/services/lcdClient.ts, src/utils/constants.ts
Transfer Status poll packages/frontend/src/hooks/useMultiChainLookup.ts, src/pages/TransferStatusPage.tsx
Hash queries packages/frontend/src/services/terraBridgeQueries.ts, hashMonitor.ts, hashVerification.ts
MegaETH chain config packages/frontend/src/utils/bridgeChains.ts, src/lib/megaethMainnet.ts
Invariants / ops notes docs/OPERATOR_WRITER_INVARIANTS.md, docs/FRONTEND_BRIDGE_INVARIANTS.md, docs/deployment-megaeth.md
Companion issues #138 (operator RPC livelock), #139 (active withdrawals), #131 (Transfer Status UX)

  1. Confirm the reported hash’s stage (deposit present? withdraw submitted? approved? dest rate-limit blocked? execute failed?) via Transfer Status / operator logs. If it is already terminal, keep it as a regression fixture description only.
  2. Extend method-level RPC fallback to getDeposit (and other eth_call verifies) using the full comma-separated URL lists from config, not primary-only source_chain_endpoints. Confirm chain id on each fallback (INV-OP-W3).
  3. Apply NegativeVerifySchedule (or a shared cycle verify budget) to TerraWriter so MegaETH/getDeposit failures do not re-hit every unapproved row every poll interval.
  4. Terra LCD resilience: optional fallback LCD URLs; honor 429 with backoff; skip-cycle remains fail-closed for approval.
  5. Wire frontend LCD_CONFIG.minRequestInterval / endpointCooldown; avoid parallel multi-chain blasts on Transfer Status when a lookup is already in flight.
  6. Observability: distinguish rpc_throttled vs no_deposit vs lcd_failure in logs/metrics (no secrets, no user ids). Surface “source RPC throttled — retrying” in Transfer Status rather than an indefinite unknown stall.
  7. Ops: prefer a dedicated MegaETH RPC with fallbacks; keep poll/backoff bounds.

Acceptance criteria

  • getDeposit / source verify uses the same fallback URL list as eth_getLogs and confirms chain id on each URL.
  • HTTP 429 / timeout / provider rate-limit on MegaETH (and any EVM source) does not permanently skip a real deposit; it retries on a bounded schedule.
  • Terra writer does not re-verify every unapproved hash on every cycle after a negative/throttled result; cache is bounded (INV-OP-W4).
  • Terra LCD 429/failure skips the cycle without approving; when a fallback LCD is configured, it is tried.
  • Frontend LCD client respects minRequestInterval / endpointCooldown; Transfer Status does not amplify 429s via unbounded parallel polls.
  • On-chain withdraw rate limits are unchanged; INV-UX2 banner still explains dest-cap delays.
  • Fail-closed: all RPCs down ⇒ no approve. A later healthy RPC can still approve a real deposit.
  • Logs/metrics classify throttle vs missing deposit vs LCD failure without secret URLs or user identifiers.
  • Documented lookup procedure for a hex xchain_hash_id (Transfer Status + operator log grep) without requiring a new public hash-oracle API.

Test plan: all paths

  1. Happy path: deposit on MegaETH (or any EVM), dest withdraw submit, source getDeposit succeeds on primary RPC, approve + execute.
  2. Primary RPC 429, fallback healthy: getDeposit fails on URL[0] with 429; URL[1] returns the deposit; approve proceeds; chain-id mismatch on a fallback is rejected.
  3. All RPCs 429: no approve; bounded backoff; later success when a URL recovers.
  4. True missing deposit: fake/unrelated hash; negative cache suppresses repeat getDeposit; never approve.
  5. Terra LCD 429: writer skips cycle; no approve; next cycle retries; with two LCD URLs, second is used after first 429.
  6. Terra active list pagination: page cap / cursor (#139) unchanged under backoff.
  7. Frontend Transfer Status: lookup of a known hash while LCD/RPC returns 429 shows retry/throttled state, then resolves; unused LCD_CONFIG knobs are actually enforced (unit + integration).
  8. Dest on-chain rate limit: transfer delayed by cap is not treated as LCD stuck; INV-UX2 copy remains.
  9. Solana/Terra sources: fallback/backoff changes do not break non-EVM verify paths.
  10. Config bounds: poll/backoff env still rejected outside INV-OP-W8 ranges.
  11. Reported hash: if still non-terminal in ops, confirm it unsticks after fallback/backoff; if already terminal, replay an equivalent MegaETH 429 fixture.

Test plan: attack, hack, and abuse vectors

Vector Expected result
Spam WithdrawSubmit with random hashes Bounded negative-retry / verify budget; memory does not grow unbounded; legitimate hashes still make progress
Exhaust public MegaETH RPC / Terra LCD Operator slows down and failovers; does not approve unverified deposits; does not disable on-chain caps
Frontend poll amplification (many tabs) Interval + LCD throttle keep request rate bounded
Chain-id lying fallback RPC Fallback rejected (INV-OP-W3); no approve from the lying node
Secret RPC URL in error logs Redacted (INV-OP-W9)
Lowering on-chain rate limits “to unstick” Out of scope / must not ship in this change
Operator API scrape of /pending Existing bearer token + governor rate limit unchanged
Hash oracle probing via public LCD Public by design; prefer single-hash queries; do not add a new unauthenticated bulk dump

Verification criteria

  • Unit tests cover getDeposit fallback order, 429 classification, chain-id confirm, and Terra NegativeVerifySchedule (or equivalent) bounds.
  • Operator tests prove: 429-then-success approves; all-down never approves; missing deposit never approves.
  • Frontend tests prove fetchLcd honors minRequestInterval / endpointCooldown and Transfer Status does not issue overlapping multi-chain lookups.
  • Existing operator writer invariants (#138), active-withdrawals tests (#139), hash parity, and Terra cross-chain E2E still pass.
  • A staging or mainnet rehearsal with a MegaETH source (or recorded 429 fixture) shows a previously retry-starved hash reach getDeposit success without raising on-chain caps.
  • Docs (OPERATOR_WRITER_INVARIANTS.md, MegaETH deployment notes) mention source-verify fallback and Terra writer backoff.
## Summary A reporter observed a stuck bridge transfer for xchain hash `0xd2350e21e090a91260457cfd6e697a5acfde2b2d1d32d958a8d3f9ba323f1951` (valid V2 32-byte id; Terra encoding `0jUOIeCQqRJgRXz9bml6Ws/eKy0dMtlYqNP5ujI/GVE=`). Operator triage points at LCD/RPC throttling while verifying source deposits and polling Terra withdrawals, especially on MegaETH, whose public RPC quality is known-poor. This is a client/operator resilience gap, not a request to weaken on-chain withdraw rate limits. EVM `eth_getLogs` already has method-level fallback and retry classification for HTTP 429. Source `getDeposit` verification and the Terra writer poll path do not: they use a single RPC/LCD URL, and Terra writer does not apply the EVM negative-verify backoff. Frontend `LCD_CONFIG` throttle knobs exist but are unused, while Transfer Status polls every chain in parallel. Treat the reported hash as a diagnostic example (confirm its current stage if still pending). The implementation is the systemic rate-limit-aware fallback/backoff for source verification and Terra LCD polling. --- ## Current codebase ### Transfer and approval flow 1. User deposits on source; on-chain deposit is keyed by `xchain_hash_id`. 2. User (or frontend auto-submit) calls `WithdrawSubmit` on dest; pending withdraw uses the same hash. 3. Operator discovers unapproved withdraws (EVM: `getPendingWithdrawHashes` + events; Terra: LCD `active_withdrawals` / legacy `pending_withdrawals`). 4. Operator verifies the source deposit (`getDeposit` / Terra deposit query / Solana PDA). Fail closed: never approve without a verified deposit. 5. On success: `WithdrawApprove`; after the cancel window, execute (unlock/mint). 6. Frontend Transfer Status re-queries all chains every `POLLING_INTERVAL` (default 10s). Two different “rate limits” must not be conflated: 1. **On-chain withdraw caps** (security): Terra `RATE_LIMITS`, EVM `TokenRateLimit`, Solana `WithdrawRateLimit`. These must stay. 2. **HTTP/RPC provider throttling**: 429 / “too many requests” / MegaETH public RPC flakiness. Operator and frontend must slow down and failover without removing (1). ### What is already resilient - EVM `eth_getLogs`: method-level URL fallback + chain-id confirm (`rpc_fallback.rs`, INV-OP-W1–W3 / issue #138). - Retry classifier treats 429 / rate-limit / provider log-limit messages as transient (`multichain_rs::is_retryable_evm_rpc_error_message`). - EVM writer: poll interval, jittered RPC backoff, bounded `NegativeVerifySchedule` (INV-OP-W4). - Terra watcher: 429/503/timeout classified as transient. - Active-withdrawals index (issue #139) reduces LCD load from full historical maps. ### Gaps that match this stuck-transfer class - `source_chain_endpoints` stores **one** RPC URL per chain (`writers/mod.rs`). Comma-separated `EVM_RPC_URL` / `EVM_CHAIN_N_RPC_URL` fallbacks are **not** used for `getDeposit`. - `verify_evm_deposit_on_chain` in `writers/evm.rs` and `writers/terra.rs` calls `getDeposit` on that single URL. - `TerraWriter::poll_and_approve` uses a single `TERRA_LCD_URL`. On LCD failure it logs and skips the cycle (`Ok`); there is no LCD URL fallback and no `NegativeVerifySchedule`. - Frontend `fetchLcd` / `queryContract` try sequential URL fallbacks but ignore `LCD_CONFIG.minRequestInterval` and `endpointCooldown`. Transfer Status (`useMultiChainLookup`) fans out parallel EVM + Terra + Solana queries every 10s. - There is no dedicated stuck-transfer detector. Symptoms appear as operator `no_evm_deposit` / `evm_errors`, EVM negative-retry suppression, or Transfer Status stalling after cancel-window expiry. --- ## Why a new implementation is needed MegaETH public RPC is intentionally treated as poor-quality. Client-side throttling and failover are required, not optional debt. Today a 429 or flaky `getDeposit` on the primary MegaETH URL can leave a real deposit unverified every Terra poll cycle, so dest `WithdrawSubmit` sits unapproved and the transfer looks stuck. Changing only the frontend poll interval cannot fix operator source verification. Relaxing on-chain withdraw caps would increase drain on key compromise and does not address HTTP 429. The missing work is to reuse the existing EVM log-fallback and negative-retry designs for `getDeposit` and Terra LCD list/verify polls, and to actually apply the frontend LCD throttle constants. --- ## Constraints and guardrails 1. **Do not relax on-chain withdraw rate limits** (Terra OPERATIONAL_NOTES; EVM `TokenRateLimit`; Solana INV-W4). Fix UX/ops if a transfer is delayed by those caps (INV-UX2). 2. **Fail-closed source verification** (INV-OP-W1): never approve without a verified deposit, including when every RPC/LCD fallback fails. 3. Keep contiguous log cursor (INV-OP-W2) and chain-id confirm on fallbacks (INV-OP-W3). 4. Bounded negative-retry cache (INV-OP-W4): attacker hashes must not grow memory without bound. Apply the same bound to Terra writer. 5. Validated poll/backoff env bounds (INV-OP-W8). Do not remove them to “unstick” faster. 6. No secret RPC URLs in logs (INV-OP-W9). 7. Keep the active-withdrawals index (#139); do not return to full historical LCD walks. 8. MegaETH dedicated/reliable RPC plus comma-separated fallbacks is the ops preference; code must still behave when the public endpoint is the only one configured. 9. Do not log user-identifying data. Hash hex (truncated if needed) and error class are enough. --- ## Relevant files | Area | Files | |---|---| | Terra writer LCD poll + `getDeposit` | `packages/operator/src/writers/terra.rs`, `terra_list.rs` | | EVM writer + negative retry | `packages/operator/src/writers/evm.rs`, `negative_retry.rs`, `poll_cursor.rs`, `retry.rs` | | Single-URL source map | `packages/operator/src/writers/mod.rs` | | Poll/backoff bounds | `packages/operator/src/poll_config.rs` | | EVM method fallback | `packages/operator/src/rpc_fallback.rs` | | Terra watcher 429 handling | `packages/operator/src/watchers/terra.rs` | | Config (comma-separated EVM RPC; single Terra LCD) | `packages/operator/src/config.rs` | | Shared 429 classifier | `packages/multichain-rs/src/evm/rpc_fallback.rs` | | Frontend LCD client (unused throttle knobs) | `packages/frontend/src/services/lcdClient.ts`, `src/utils/constants.ts` | | Transfer Status poll | `packages/frontend/src/hooks/useMultiChainLookup.ts`, `src/pages/TransferStatusPage.tsx` | | Hash queries | `packages/frontend/src/services/terraBridgeQueries.ts`, `hashMonitor.ts`, `hashVerification.ts` | | MegaETH chain config | `packages/frontend/src/utils/bridgeChains.ts`, `src/lib/megaethMainnet.ts` | | Invariants / ops notes | `docs/OPERATOR_WRITER_INVARIANTS.md`, `docs/FRONTEND_BRIDGE_INVARIANTS.md`, `docs/deployment-megaeth.md` | | Companion issues | #138 (operator RPC livelock), #139 (active withdrawals), #131 (Transfer Status UX) | --- ## Recommended direction 1. Confirm the reported hash’s stage (deposit present? withdraw submitted? approved? dest rate-limit blocked? execute failed?) via Transfer Status / operator logs. If it is already terminal, keep it as a regression fixture description only. 2. Extend method-level RPC fallback to `getDeposit` (and other `eth_call` verifies) using the full comma-separated URL lists from config, not primary-only `source_chain_endpoints`. Confirm chain id on each fallback (INV-OP-W3). 3. Apply `NegativeVerifySchedule` (or a shared cycle verify budget) to `TerraWriter` so MegaETH/`getDeposit` failures do not re-hit every unapproved row every poll interval. 4. Terra LCD resilience: optional fallback LCD URLs; honor 429 with backoff; skip-cycle remains fail-closed for approval. 5. Wire frontend `LCD_CONFIG.minRequestInterval` / `endpointCooldown`; avoid parallel multi-chain blasts on Transfer Status when a lookup is already in flight. 6. Observability: distinguish `rpc_throttled` vs `no_deposit` vs `lcd_failure` in logs/metrics (no secrets, no user ids). Surface “source RPC throttled — retrying” in Transfer Status rather than an indefinite unknown stall. 7. Ops: prefer a dedicated MegaETH RPC with fallbacks; keep poll/backoff bounds. --- ## Acceptance criteria - [ ] `getDeposit` / source verify uses the same fallback URL list as `eth_getLogs` and confirms chain id on each URL. - [ ] HTTP 429 / timeout / provider rate-limit on MegaETH (and any EVM source) does not permanently skip a real deposit; it retries on a bounded schedule. - [ ] Terra writer does not re-verify every unapproved hash on every cycle after a negative/throttled result; cache is bounded (INV-OP-W4). - [ ] Terra LCD 429/failure skips the cycle without approving; when a fallback LCD is configured, it is tried. - [ ] Frontend LCD client respects `minRequestInterval` / `endpointCooldown`; Transfer Status does not amplify 429s via unbounded parallel polls. - [ ] On-chain withdraw rate limits are unchanged; INV-UX2 banner still explains dest-cap delays. - [ ] Fail-closed: all RPCs down ⇒ no approve. A later healthy RPC can still approve a real deposit. - [ ] Logs/metrics classify throttle vs missing deposit vs LCD failure without secret URLs or user identifiers. - [ ] Documented lookup procedure for a hex `xchain_hash_id` (Transfer Status + operator log grep) without requiring a new public hash-oracle API. --- ## Test plan: all paths 1. **Happy path:** deposit on MegaETH (or any EVM), dest withdraw submit, source `getDeposit` succeeds on primary RPC, approve + execute. 2. **Primary RPC 429, fallback healthy:** `getDeposit` fails on URL[0] with 429; URL[1] returns the deposit; approve proceeds; chain-id mismatch on a fallback is rejected. 3. **All RPCs 429:** no approve; bounded backoff; later success when a URL recovers. 4. **True missing deposit:** fake/unrelated hash; negative cache suppresses repeat `getDeposit`; never approve. 5. **Terra LCD 429:** writer skips cycle; no approve; next cycle retries; with two LCD URLs, second is used after first 429. 6. **Terra active list pagination:** page cap / cursor (#139) unchanged under backoff. 7. **Frontend Transfer Status:** lookup of a known hash while LCD/RPC returns 429 shows retry/throttled state, then resolves; unused `LCD_CONFIG` knobs are actually enforced (unit + integration). 8. **Dest on-chain rate limit:** transfer delayed by cap is **not** treated as LCD stuck; INV-UX2 copy remains. 9. **Solana/Terra sources:** fallback/backoff changes do not break non-EVM verify paths. 10. **Config bounds:** poll/backoff env still rejected outside INV-OP-W8 ranges. 11. **Reported hash:** if still non-terminal in ops, confirm it unsticks after fallback/backoff; if already terminal, replay an equivalent MegaETH 429 fixture. --- ## Test plan: attack, hack, and abuse vectors | Vector | Expected result | |---|---| | Spam `WithdrawSubmit` with random hashes | Bounded negative-retry / verify budget; memory does not grow unbounded; legitimate hashes still make progress | | Exhaust public MegaETH RPC / Terra LCD | Operator slows down and failovers; does not approve unverified deposits; does not disable on-chain caps | | Frontend poll amplification (many tabs) | Interval + LCD throttle keep request rate bounded | | Chain-id lying fallback RPC | Fallback rejected (INV-OP-W3); no approve from the lying node | | Secret RPC URL in error logs | Redacted (INV-OP-W9) | | Lowering on-chain rate limits “to unstick” | Out of scope / must not ship in this change | | Operator API scrape of `/pending` | Existing bearer token + governor rate limit unchanged | | Hash oracle probing via public LCD | Public by design; prefer single-hash queries; do not add a new unauthenticated bulk dump | --- ## Verification criteria - Unit tests cover `getDeposit` fallback order, 429 classification, chain-id confirm, and Terra `NegativeVerifySchedule` (or equivalent) bounds. - Operator tests prove: 429-then-success approves; all-down never approves; missing deposit never approves. - Frontend tests prove `fetchLcd` honors `minRequestInterval` / `endpointCooldown` and Transfer Status does not issue overlapping multi-chain lookups. - Existing operator writer invariants (#138), active-withdrawals tests (#139), hash parity, and Terra cross-chain E2E still pass. - A staging or mainnet rehearsal with a MegaETH source (or recorded 429 fixture) shows a previously retry-starved hash reach `getDeposit` success without raising on-chain caps. - Docs (`OPERATOR_WRITER_INVARIANTS.md`, MegaETH deployment notes) mention source-verify fallback and Terra writer backoff.
PlasticDigits changed title from Check bridge monorepo, lcd call, likely its rate limiting (which we need due to to bug(operator): MegaETH/LCD rate-limit gaps stall getDeposit and Terra writer approval 2026-09-04 04:03:50 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-bridge-monorepo#164
No description provided.