Skip to content

Conversation

@DZakh
Copy link
Member

@DZakh DZakh commented Sep 4, 2025

  • Better error for missing transaction in HyperSync (Hyperliquid issue)
  • Remember the max block interval of the RPC provider and don't try to increase after the range

Summary by CodeRabbit

  • New Features

    • Introduced a global max block-interval backoff to improve RPC syncing under provider limits.
  • Bug Fixes

    • More robust handling when log responses are not objects, reducing noisy missing-field reports.
    • Improved parsing of provider “range too large” errors to adjust sync intervals appropriately.
  • Configuration

    • Sync settings consolidated into a single source sync type; generated config templates updated. Existing defaults unchanged.
  • Tests

    • Added a skipped HyperSync scenario for broken transaction responses.
    • Updated tests to reflect the new interval suggestion API with an additional flag.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 4, 2025

Walkthrough

Adds a new InternalConfig.sourceSync type and migrates syncConfig references to it across templates and RPC code. Refactors RpcSource backoff to support a global “max” interval signal, updating function signatures and event construction. Adjusts HyperSync field-missing logic control flow. Updates/introduces tests to reflect new return types and add a skipped HyperSync scenario.

Changes

Cohort / File(s) Summary
SyncConfig type migration
codegenerator/cli/npm/envio/src/InternalConfig.res, codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs, codegenerator/cli/templates/static/codegen/src/Config.res
Introduces public type sourceSync; replaces prior syncConfig usages in templates and function return types; removes the old public syncConfig alias; getSyncConfig now returns InternalConfig.sourceSync.
RpcSource backoff and event mapping
codegenerator/cli/npm/envio/src/sources/RpcSource.res
Changes backoff suggestion contract to option<(int, bool)> with a global “max” key; getNextPage now takes ~mutSuggestedBlockIntervals and InternalConfig.sourceSync; updates how events read blockNumber/timestamp and cast block to Internal.eventBlock; minor signature/formatting tweaks.
HyperSync missing-field iteration
codegenerator/cli/npm/envio/src/sources/HyperSync.res
Adds @inline to addMissingParams; replaces forEach with guarded index loop; if returned value isn’t an object, pushes the prefix once; object case keeps prior missing-field detection.
Tests
scenarios/test_codegen/test/RpcSource_test.res, scenarios/test_codegen/test/HyperSync_test.res
Updates tests for new option<(int, bool)> return shape and flags; adds a skipped HyperSync GetLogs test scenario exercising log selections and field requirements.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Caller
  participant RpcSource
  participant Node as RPC Node
  participant Dict as mutSuggestedBlockIntervals
  participant Loader as Block Loader

  Caller->>RpcSource: getNextPage(~mutSuggestedBlockIntervals, ~syncConfig: sourceSync, ~partitionId)
  RpcSource->>Node: eth_getLogs(from..to)
  alt Success
    Node-->>RpcSource: logs[]
    RpcSource->>Loader: getBlock(log.blockNumber)
    Loader-->>RpcSource: block{ number, timestamp, ... }
    RpcSource-->>Caller: page{ events with block cast to Internal.eventBlock }
  else Error
    Node-->>RpcSource: error exn
    RpcSource->>RpcSource: getSuggestedBlockIntervalFromExn(exn) -> Some((range, isMax))?
    alt Some((range, true)) [max suggested]
      RpcSource->>Dict: set("max", range)
    else Some((range, false)) [partition suggested]
      RpcSource->>Dict: set(partitionId, range)
    else None
      RpcSource-->>Caller: propagate/handle without interval update
    end
    RpcSource-->>Caller: next action/result (per existing control flow)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • JonoPrest
  • JasoonS

Poem

In burrows of code, I twitch and sync,
New intervals thump with a global wink.
Blocks hop by with number and time,
Logs trail carrots of structured rhyme.
I stash “max” in my pocket, neat—
Then bound to the next review treat. 🥕

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dz/improve-sources

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@DZakh DZakh requested a review from JonoPrest September 4, 2025 09:56
Base automatically changed from dz/progress-block to main September 4, 2025 13:40
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: 4

🧹 Nitpick comments (5)
codegenerator/cli/npm/envio/src/InternalConfig.res (1)

22-30: Clarify units and bounds; consider naming consistency.

  • Add brief field docs (blocks vs milliseconds; expected ranges).
  • Optional: rename fallbackStallTimeout -> fallbackStallTimeoutMillis for consistency with other "*Millis" fields.

Apply doc comments:

 type sourceSync = {
-  initialBlockInterval: int,
-  backoffMultiplicative: float,
-  accelerationAdditive: int,
-  intervalCeiling: int,
-  backoffMillis: int,
-  queryTimeoutMillis: int,
-  fallbackStallTimeout: int,
+  /* initial page size in blocks */
+  initialBlockInterval: int,
+  /* multiplicative backoff factor (> 1.0) */
+  backoffMultiplicative: float,
+  /* additive acceleration on success (blocks) */
+  accelerationAdditive: int,
+  /* upper bound for block interval (blocks) */
+  intervalCeiling: int,
+  /* delay between retries (ms) */
+  backoffMillis: int,
+  /* per-query timeout (ms) */
+  queryTimeoutMillis: int,
+  /* stall timeout when no progress observed (ms) */
+  fallbackStallTimeout: int,
 }
codegenerator/cli/npm/envio/src/sources/HyperSync.res (1)

79-95: Add a regression test for “missing transaction with empty required fields”.

Ensure we still surface "transaction" in missingParams when nonOptionalTransactionFieldNames is []. This guards the Hyperliquid-specific case.

I can add a targeted test in scenarios/test_codegen/test/HyperSync_test.res to cover this path—want me to open a follow-up PR?

codegenerator/cli/npm/envio/src/sources/RpcSource.res (3)

19-26: Backoff recursion: consider a cap and jitter.

Unbounded doubling can lead to long stalls or lock-step retries. Consider a ceiling (e.g., <= 60s) and small jitter to reduce thundering herds.


210-218: Timeout promise may cause unhandled rejections after race settles.

If logsPromise resolves first, queryTimoutPromise can still reject later without a consumer. Attach a no-op catch to the timeout or use an abortable pattern.

Example (minimal swallow):

- let queryTimoutPromise =
+ let queryTimoutPromise =
     Time.resolvePromiseAfterDelay(~delayMilliseconds=sc.queryTimeoutMillis)->Promise.then(() =>
       Promise.reject(
         QueryTimout(
           `Query took longer than ${Belt.Int.toString(sc.queryTimeoutMillis / 1000)} seconds`,
         ),
       )
     )
+  |> Promise.catch(_ => Promise.resolve())

Also applies to: 237-246


4-4: Typo: QueryTimout → QueryTimeout (exception and usages).

Minor naming polish for clarity.

Apply:

- exception QueryTimout(string)
+ exception QueryTimeout(string)

-         QueryTimout(
+         QueryTimeout(

Also applies to: 214-214

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f5856bb and 7770d60.

📒 Files selected for processing (7)
  • codegenerator/cli/npm/envio/src/InternalConfig.res (1 hunks)
  • codegenerator/cli/npm/envio/src/sources/HyperSync.res (1 hunks)
  • codegenerator/cli/npm/envio/src/sources/RpcSource.res (13 hunks)
  • codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs (1 hunks)
  • codegenerator/cli/templates/static/codegen/src/Config.res (1 hunks)
  • scenarios/test_codegen/test/HyperSync_test.res (1 hunks)
  • scenarios/test_codegen/test/RpcSource_test.res (4 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{res,resi}

📄 CodeRabbit inference engine (.cursor/rules/rescript.mdc)

**/*.{res,resi}: Never use [| item |] to create an array. Use [ item ] instead.
Must always use = for setting value to a field. Use := only for ref values created using ref function.
ReScript has record types which require a type definition before hand. You can access record fields by dot like foo.myField.
It's also possible to define an inline object, it'll have quoted fields in this case.
Use records when working with structured data, and objects to conveniently pass payload data between functions.
Never use %raw to access object fields if you know the type.

Files:

  • scenarios/test_codegen/test/HyperSync_test.res
  • codegenerator/cli/npm/envio/src/InternalConfig.res
  • codegenerator/cli/npm/envio/src/sources/HyperSync.res
  • scenarios/test_codegen/test/RpcSource_test.res
  • codegenerator/cli/templates/static/codegen/src/Config.res
  • codegenerator/cli/npm/envio/src/sources/RpcSource.res
**/*.res

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Prefer reading ReScript .res modules directly; compiled .js artifacts can be ignored

Files:

  • scenarios/test_codegen/test/HyperSync_test.res
  • codegenerator/cli/npm/envio/src/InternalConfig.res
  • codegenerator/cli/npm/envio/src/sources/HyperSync.res
  • scenarios/test_codegen/test/RpcSource_test.res
  • codegenerator/cli/templates/static/codegen/src/Config.res
  • codegenerator/cli/npm/envio/src/sources/RpcSource.res
codegenerator/cli/templates/{static,dynamic}/codegen/src/**/*

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Edit template versions under codegenerator/cli/templates/static/codegen/src or codegenerator/cli/templates/dynamic/codegen/src instead of editing generated/src

Files:

  • codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs
  • codegenerator/cli/templates/static/codegen/src/Config.res
🧠 Learnings (1)
📚 Learning: 2025-08-11T08:49:57.399Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: scenarios/test_codegen/.cursor/rules/hyperindex.mdc:0-0
Timestamp: 2025-08-11T08:49:57.399Z
Learning: Applies to scenarios/test_codegen/**/*.ts : Always cast timestamps from events to BigInt (e.g., BigInt(event.block.timestamp))

Applied to files:

  • codegenerator/cli/npm/envio/src/sources/RpcSource.res
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
🔇 Additional comments (7)
codegenerator/cli/npm/envio/src/InternalConfig.res (1)

22-30: Good addition: centralized sync config type looks solid.

Seven-field record is clear and aligns with the PR goals.

codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs (1)

7-7: No lingering Config.syncConfig usages – templates now use only syncConfigOptions and reference InternalConfig.sourceSync. Confirm InternalConfig is included in bs-dependencies so generated projects compile.

scenarios/test_codegen/test/RpcSource_test.res (1)

423-423: Tests updated for option<(int, bool)> shape — LGTM.

Assertions now check Some((n, isMaxRange)) as per the new API. Good coverage of both suggested ranges and max-range cases.

Also applies to: 463-463, 528-528, 558-558

codegenerator/cli/npm/envio/src/sources/RpcSource.res (4)

597-604: Additive increase guard when a global max exists — LGTM.

Skipping additive growth when the global max key is set prevents overshooting provider constraints. Nice.


371-373: Block fetch path simplification — LGTM.

Fetching the block by number via the loader/backoff path is clearer and avoids stale field casts.

Also applies to: 493-501


666-678: Type assumptions on Ethers block fields — add verification/asserts.

You’re casting Ethers block to Internal.eventBlock via Utils.magic and assuming number/timestamp shapes; mismatches across providers or Ethers versions will surface here. Consider a constructor that validates and maps fields explicitly (or asserts once and logs provider/version).

Would you like a typed adapter for Ethers.JsonRpcProvider.block -> Internal.eventBlock?


241-246: Persist suggested interval under max or partition key — LGTM
Confirmed partitionId is consistently declared as a string in RPC source, SourceManager, and FetchState (and only numeric strings appear in tests); since it’s sourced from user config, its stability is a configuration concern and no in-code normalization is required.

Comment on lines +79 to +95
@inline
let addMissingParams = (acc, fieldNames, returnedObj, ~prefix) => {
fieldNames->Array.forEach(fieldName => {
switch returnedObj
->(Utils.magic: 'a => Js.Dict.t<unknown>)
->Utils.Dict.dangerouslyGetNonOption(fieldName) {
| Some(_) => ()
| None => acc->Array.push(prefix ++ "." ++ fieldName)->ignore
if fieldNames->Utils.Array.notEmpty {
if !(returnedObj->Obj.magic) {
acc->Array.push(prefix)->ignore
} else {
for idx in 0 to fieldNames->Array.length - 1 {
let fieldName = fieldNames->Array.getUnsafe(idx)
switch returnedObj
->(Utils.magic: 'a => Js.Dict.t<unknown>)
->Utils.Dict.dangerouslyGetNonOption(fieldName) {
| Some(_) => ()
| None => acc->Array.push(prefix ++ "." ++ fieldName)->ignore
}
}
}
})
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Always report missing object; avoid truthiness + magic casts.

The non-object detection is gated by fieldNames->notEmpty. If nonOptionalTransactionFieldNames is empty, a missing transaction object won’t be reported—contrary to the PR objective. Also, relying on JS truthiness via Obj.magic is brittle. Replace with explicit JSON classification and hoist the dict cast.

Apply this refactor:

-@inline
-let addMissingParams = (acc, fieldNames, returnedObj, ~prefix) => {
-  if fieldNames->Utils.Array.notEmpty {
-    if !(returnedObj->Obj.magic) {
-      acc->Array.push(prefix)->ignore
-    } else {
-      for idx in 0 to fieldNames->Array.length - 1 {
-        let fieldName = fieldNames->Array.getUnsafe(idx)
-        switch returnedObj
-        ->(Utils.magic: 'a => Js.Dict.t<unknown>)
-        ->Utils.Dict.dangerouslyGetNonOption(fieldName) {
-        | Some(_) => ()
-        | None => acc->Array.push(prefix ++ "." ++ fieldName)->ignore
-        }
-      }
-    }
-  }
-}
+@inline
+let addMissingParams = (acc, fieldNames, returnedObj: Js.Json.t, ~prefix) => {
+  switch Js.Json.classify(returnedObj) {
+  | Js.Json.JSONObject(obj) => {
+      if fieldNames->Utils.Array.notEmpty {
+        let dict = obj
+        for idx in 0 to fieldNames->Array.length - 1 {
+          let fieldName = fieldNames->Array.getUnsafe(idx)
+          switch Js.Dict.get(dict, fieldName) {
+          | Some(_) => ()
+          | None => acc->Array.push(prefix ++ "." ++ fieldName)->ignore
+          }
+        }
+      }
+    }
+  | _ =>
+    /* Missing or non-object => record the whole prefix */
+    acc->Array.push(prefix)->ignore
+  }
+}

Update call sites accordingly (outside the changed hunk):

/* in convertEvent */
missingParams->addMissingParams(Log.fieldNames, (event.log: Js.Json.t), ~prefix="log")
missingParams->addMissingParams(nonOptionalBlockFieldNames, (event.block: Js.Json.t), ~prefix="block")
missingParams->addMissingParams(nonOptionalTransactionFieldNames, (event.transaction: Js.Json.t), ~prefix="transaction")
🤖 Prompt for AI Agents
In codegenerator/cli/npm/envio/src/sources/HyperSync.res around lines 79–95, the
non-object detection is currently gated by fieldNames->Utils.Array.notEmpty and
uses Obj.magic truthiness; change it to always detect non-object by classifying
returnedObj with Js.Json.classify, and if it's not an object push the prefix
once (so missing object is always reported regardless of fieldNames) and return;
if it is an object hoist a single Js.Dict.t<unknown> cast for reuse then, only
if fieldNames is non-empty, iterate fieldNames and use
Utils.Dict.dangerouslyGetNonOption against the hoisted dict to push missing
field names as prefix ++ "." ++ fieldName; also update the convertEvent call
sites as suggested to pass Js.Json.t for event.log/event.block/event.transaction
with ~prefix values.

Comment on lines +110 to 116
let extractBlockRange = (execResult, ~isMaxRange) =>
switch execResult->Js.Re.captures {
| [_, Js.Nullable.Value(blockRangeLimit)] =>
switch blockRangeLimit->Int.fromString {
| Some(blockRangeLimit) if blockRangeLimit > 0 => Some(blockRangeLimit)
| Some(blockRangeLimit) if blockRangeLimit > 0 => Some(blockRangeLimit, isMaxRange)
| _ => None
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Bug: incorrect Option tuple construction (Some needs a single tuple argument).

In ReScript, option<(int, bool)> must be constructed as Some((x, y)), not Some(x, y). Current code won’t type-check and will fail at build time.

Apply:

- | Some(blockRangeLimit) if blockRangeLimit > 0 => Some(blockRangeLimit, isMaxRange)
+ | Some(blockRangeLimit) if blockRangeLimit > 0 => Some((blockRangeLimit, isMaxRange))

-             | (Some(fromBlock), Some(toBlock)) if toBlock >= fromBlock =>
-              Some(toBlock - fromBlock + 1, false)
+             | (Some(fromBlock), Some(toBlock)) if toBlock >= fromBlock =>
+              Some((toBlock - fromBlock + 1, false))

-                      | Some(_) => Some(2000, true)
+                      | Some(_) => Some((2000, true))

-                          | Some(_) => Some(10000, true)
+                          | Some(_) => Some((10000, true))

Also applies to: 127-128, 153-154, 159-160

🤖 Prompt for AI Agents
In codegenerator/cli/npm/envio/src/sources/RpcSource.res around lines 110-116,
the code constructs options incorrectly using multiple arguments for Some;
change those to pass a single tuple value (e.g., Some((blockRangeLimit,
isMaxRange))) so option<(int,bool)> is built correctly; apply the same fix at
the other occurrences reported (lines 127-128, 153-154, 159-160) replacing
Some(x, y) with Some((x, y)).

?fallbackStallTimeout,
}: syncConfigOptions,
): syncConfig => {
): InternalConfig.sourceSync => {
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Return type switch to InternalConfig.sourceSync looks good; verify template/call-site alignment.

This aligns the template with the new public type. Please double-check that all consumers (templates and runtime) now expect InternalConfig.sourceSync and that no references to Config.syncConfig remain.

Run to confirm no stale references:


🏁 Script executed:

#!/bin/bash
rg -nP 'Config\.syncConfig\b|:?\s*syncConfig\b'
rg -nP 'InternalConfig\.sourceSync\b'

Length of output: 6790


Stale Config.syncConfig references found—update to InternalConfig.sourceSync

  • scenarios/test_codegen/test/**/* and mocks still use Config.getSyncConfig
  • static template at codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res
  • dynamic template codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs
  • HBS code in codegenerator/cli/src/hbs_templating/codegen_templates.rs
  • runtime sources in codegenerator/cli/npm/envio/src/sources/RpcSource.res

Ensure every call-site uses InternalConfig.sourceSync and remove all Config.syncConfig/getSyncConfig occurrences.

🤖 Prompt for AI Agents
In codegenerator/cli/templates/static/codegen/src/Config.res around line 29,
there are stale references to Config.syncConfig/getSyncConfig; replace all
call-sites to use InternalConfig.sourceSync instead, update the return/type
usage to match InternalConfig.sourceSync, and remove any remaining
Config.syncConfig/getSyncConfig occurrences; repeat this replacement in the
listed templates and files (scenarios/test_codegen/test/**/*, mocks,
codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res,
codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs,
codegenerator/cli/src/hbs_templating/codegen_templates.rs, and
codegenerator/cli/npm/envio/src/sources/RpcSource.res), ensuring imports/aliases
are adjusted and any type mismatches are fixed so callers compile against
InternalConfig.sourceSync.

@@ -0,0 +1,41 @@
open RescriptMocha

let testApiToken = "3dc856dd-b0ea-494f-b27e-017b8b6b7e07"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Hardcoded API token committed — remove and rotate immediately.

Never commit secrets, even in skipped tests. Replace with an env-driven value and rotate the exposed token.

Apply:

- let testApiToken = "3dc856dd-b0ea-494f-b27e-017b8b6b7e07"
+ // Read from your CI/test runner env and document the requirement.
+ let testApiToken = "<SET_HYPERSYNC_API_TOKEN_IN_ENV>"

Optionally, gate the test at runtime when the token is missing.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let testApiToken = "3dc856dd-b0ea-494f-b27e-017b8b6b7e07"
// Read from your CI/test runner env and document the requirement.
let testApiToken = "<SET_HYPERSYNC_API_TOKEN_IN_ENV>"
🤖 Prompt for AI Agents
In scenarios/test_codegen/test/HyperSync_test.res around line 3, a hardcoded API
token was committed; remove the literal string and replace it with an
environment-driven value (e.g., read from process.env or a test-specific config)
so the test reads the token at runtime, rotate the exposed token immediately,
and add a runtime guard in the test to skip/fail with a clear message if the env
var is missing to avoid accidental failures.

@DZakh DZakh changed the title Sources improvements 2x faster historical sync with RPC source Sep 4, 2025
@DZakh DZakh merged commit 75a502f into main Sep 4, 2025
2 checks passed
@DZakh DZakh deleted the dz/improve-sources branch September 4, 2025 14:31
This was referenced Sep 5, 2025
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.

Do not reattempt block ranges that are too high for particular JSON-RPC servers

3 participants