feat: support multiple REST URIs#64
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
WalkthroughAdds support for single or multiple REST/RPC URIs across config, env loading, and runtime. Introduces URI normalization, a RESTClient that accepts multiple endpoints with failover/retry/backoff, updates tests and examples, and adapts test and worker wiring to use the first URI for mocks. ChangesMulti-Endpoint REST & RPC (single coherent DAG)
Sequence DiagramsequenceDiagram
participant Worker as Worker
participant Client as RESTClient
participant EP1 as Endpoint 1
participant EP2 as Endpoint 2
participant Logger as Logger
Worker->>Client: instantiate with [EP1, EP2]
Worker->>Client: request /ibc/...
Client->>EP1: GET /ibc/...
EP1-->>Client: 500 Error
Client->>Logger: log endpoint failure
Client->>Client: backoff / increment retry
Client->>EP2: GET /ibc/...
EP2-->>Client: 200 OK + payload
Client-->>Worker: return payload
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/lib/config.ts`:
- Around line 34-42: parseUriConfig currently returns whatever safeJsonParse
yields (including malformed bracketed strings or empty arrays) which defers
errors to runtime; update parseUriConfig so that after calling safeJsonParse for
bracketed input you validate the result is an array of non-empty strings and has
at least one element, and if not throw a descriptive error immediately.
Specifically, in the parseUriConfig function (and around the safeJsonParse call)
check Array.isArray(parsed), ensure every item is typeof string and item.trim()
!== '', and throw (not return) for invalid or empty arrays; leave the
non-bracketed trimmedUri path returning the single string as before.
In `@src/lib/restClient.ts`:
- Around line 19-23: The shared currentIndex on RESTRequestState makes endpoint
selection global across concurrent requests; change logic so currentIndex is not
mutated on the shared state during retries: make the retry cursor a local
variable inside the request() function (use a local index/attempt counter) and
only update/publish RESTRequestState.currentIndex or a preferred index after a
successful response; update code that reads currentIndex (e.g., any loops in
request(), getNextUri logic, and the logic around restUris and requesterConfig)
to use the local cursor for attempts and preserve thread-safety for concurrent
calls.
- Around line 141-159: The catch block in the REST client currently retries on
every thrown error; change it to rethrow immediately for deterministic client
errors (HTTP 4xx) so they don't trigger failover/backoff loops. Inside the catch
for the request in restClient.ts (the block that sets errorContext,
logger.error, state.currentIndex, and uses retryCount / MAX_RETRY), inspect the
error object for an HTTP response status (e.g., error.response?.status or
equivalent from your HTTP library) and if the status is in the 400–499 range,
log the errorContext and rethrow the error without advancing state.currentIndex
or initiating backoff; only proceed with the existing failover logic for
network/timeout errors or retryable 5xx responses. Ensure you reference the same
variables used there: state.currentIndex, retryCount, MAX_RETRY, logger, and
errorContext.
In `@src/test/testSetup.ts`:
- Around line 13-15: The helper firstUri currently returns undefined when given
an empty array; update firstUri(uri: string | string[]) to explicitly check
Array.isArray(uri) and if so verify uri.length > 0, otherwise throw a clear
configuration error (e.g., "restUri must contain at least one entry") so callers
that build URLs get an actionable message; ensure the thrown error is used
instead of returning undefined and reference the firstUri function when making
the change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 6a2b824b-08b4-48cd-addb-39f4ea66ab21
📒 Files selected for processing (9)
README.mdconfig.example.jsonconfig.schema.jsonsrc/lib/config.spec.tssrc/lib/config.tssrc/lib/restClient.spec.tssrc/lib/restClient.tssrc/test/testSetup.tssrc/workers/index.ts
Summary
new RESTClient(chainConfig.restUri, ...).Why
Some public REST/RPC providers periodically state-sync or reset nodes when they have node issues. When that happens, historical state around the last height used for
MsgUpdateClientproof generation can be pruned or unavailable from that endpoint. Even if another provider still has the required state, the relayer previously had no REST fallback path, so update-client generation could fail or keep retrying against an endpoint that can no longer serve the needed height.Allowing multiple REST URIs lets the relayer fail over to another endpoint that may still retain the required historical state, reducing client update failures caused by provider pruning, state-sync resets, or transient REST node issues.
Validation
./node_modules/.bin/tsc --noEmit --incremental false./node_modules/.bin/jest src/lib/config.spec.ts src/lib/restClient.spec.ts --runInBand --config '{"preset":"ts-jest","testEnvironment":"node","moduleNameMapper":{"^src/(.*)$":"<rootDir>/src/$1"}}'Summary by CodeRabbit
New Features
Documentation