Skip to content

Chore/deploy#437

Merged
mani99brar merged 50 commits intodevfrom
chore/deploy
Jan 20, 2026
Merged

Chore/deploy#437
mani99brar merged 50 commits intodevfrom
chore/deploy

Conversation

@mani99brar
Copy link
Copy Markdown
Contributor

@mani99brar mani99brar commented Dec 30, 2025

PR-Codex overview

This PR focuses on updating the codebase for the Vea relayer and validator, including enhancements to state management, error handling, and integration of heartbeat signals for monitoring. It also updates dependencies and Docker configurations.

Detailed summary

  • Added new JSON state files for testnet_42161, testnet_10200, and testnet_11155111.
  • Updated Node version in package.json and Dockerfiles to 24.4.0.
  • Introduced HASHI_NOT_CONFIGURED and other error states in event handling.
  • Modified transaction handlers to accommodate new structure for nonces and state management.
  • Enhanced GraphQL queries and added methods for fetching claims and epochs.
  • Implemented heartbeat functionality for monitoring service in heartbeat.ts.
  • Updated README documentation for relayer and validator usage.
  • Refactored state file handling to manage hashiBlockNumber instead of hashiNonce.
  • Improved logging with pino for better traceability of events.
  • Adjusted Docker configurations for building and running containers.

The following files were skipped due to too many changes: validator-cli/src/helpers/snapshot.test.ts, validator-cli/src/utils/claim.ts, validator-cli/src/utils/arbToEthState.ts, validator-cli/src/utils/logger.ts, relayer-cli/src/utils/hashi.test.ts, yarn.lock, relayer-cli/src/utils/hashi.ts

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Hashi bridge integration for enhanced cross-chain messaging support
    • Introduced Docker containerization for relayer and validator services
    • Added heartbeat monitoring for service health tracking
    • Enhanced GraphQL utilities for improved message querying
  • Improvements

    • Upgraded to Node.js 24.4.0
    • Implemented structured logging throughout services
    • Enhanced finality validation for cross-chain operations
    • Improved state management and error handling

✏️ Tip: You can customize this high-level summary in your review settings.

@netlify
Copy link
Copy Markdown

netlify bot commented Dec 30, 2025

Deploy Preview for veascan ready!

Name Link
🔨 Latest commit d400265
🔍 Latest deploy log https://app.netlify.com/projects/veascan/deploys/6965ffd43f675c0008db48ae
😎 Deploy Preview https://deploy-preview-437--veascan.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Dec 30, 2025

Walkthrough

This PR introduces Hashi cross-chain bridge execution, containerizes relayer and validator services via Docker, refactors contract imports from package to local paths, implements heartbeat monitoring and structured logging, updates state tracking from hashiNonce to hashiBlockNumber, and extends bridge configuration with additional RPC endpoints and contract addresses.

Changes

Cohort / File(s) Summary
Docker Containerization
docker-compose.yml, relayer-cli/Dockerfile, validator-cli/Dockerfile
New multi-stage Dockerfiles for relayer and validator with node:24.4-alpine, Corepack Yarn setup, conditional TypeChain builds, and docker-compose orchestration with shared vea-network.
Node.js Version Bump
package.json
Volta Node version updated from 22.14.0 to 24.4.0.
Contract Import Migration
relayer-cli/src/utils/ethers.ts, validator-cli/src/utils/ethers.ts, relayer-cli/src/consts/bridgeRoutes.ts, validator-cli/src/consts/bridgeRoutes.ts, validator-cli/src/utils/transactionHandlers/arbToEthHandler.ts, validator-cli/src/utils/transactionHandlers/arbToGnosisHandler.ts, validator-cli/src/utils/transactionHandlers/baseTransactionHandler.ts, validator-cli/src/helpers/validator.ts
Switched imports from @kleros/vea-contracts/typechain-types to local relative path ../../../contracts/typechain-types; deployed contract JSONs moved from package to local deployments.
Bridge Configuration Expansion
relayer-cli/src/consts/bridgeRoutes.ts
Added rpcInbox, yahoAddress, yaruAddress, hashiAddress fields to IBridge interface; populated with Sepolia and Chiado contract addresses and environment-based RPC initialization.
Hashi Bridge Executor Implementation
relayer-cli/src/utils/hashi.ts, relayer-cli/src/utils/hashiHelpers/bridgeRoutes.ts, relayer-cli/src/utils/hashiHelpers/hashiTypes.ts
New Hashi execution flow: refactored from nonce-polling to log-driven message dispatch; introduced HashiMessageState, HashiExecutionStatus, DispatchedTxnData types; added getHashiBridgeConfig() and getAllMessageDispatchedLogs() helpers; renamed VeaNonceToHashiMessage to HashiMessageState with richer state tracking.
Relayer Core Refactoring
relayer-cli/src/relayer.ts, relayer-cli/src/utils/relayerHelpers.ts
Integrated heartbeat telemetry; added per-network execution timers; introduced Hashi cycle scheduling (5 minutes); refactored state key from hashiNonce to hashiBlockNumber; added sourceChainId to network config and environment-driven Hashi chain configuration.
State Management Updates
relayer-cli/state/devnet_11155111.json, relayer-cli/state/testnet_11155111.json, relayer-cli/state/testnet_10200.json, relayer-cli/state/testnet_42161.json
Renamed state field from hashiNonce to hashiBlockNumber; updated timestamps and nonces; added new state files for testnet Chiado and Arbitrum chains.
Logging & Monitoring Infrastructure
relayer-cli/src/utils/logger.ts, relayer-cli/src/utils/heartbeat.ts, validator-cli/src/utils/logger.ts, validator-cli/src/utils/heartbeat.ts
Introduced pino-based structured logging with optional Logtail transport; added heartbeat utility for service monitoring; integrated logging across BotEvents with contextual scoping.
GraphQL Query Helpers
relayer-cli/src/utils/graphQueries.ts, relayer-cli/src/utils/proof.ts, validator-cli/src/utils/graphQueries.ts
Added getVeaMsgTrnx(), getCount(), getNonceFrom() for relayer; extended getProofAtCount() with inboxAddress parameter; added getClaimsForEpochs(), refactored getLastMessageSaved() to throw NoMessageSavedError and return structured response.
Validator Claim & Snapshot Logic
validator-cli/src/helpers/claimer.ts, validator-cli/src/helpers/snapshot.ts, validator-cli/src/utils/claim.ts, validator-cli/src/utils/arbToEthState.ts
Added finality checks via getBlocksAndCheckFinality with emitter-based error reporting; refactored claim retrieval with graph fallbacks and verification hashing; extended CheckAndClaimParams and SnapshotCheckParams with new fetchers and provider overrides.
Bot Events & Error Handling
relayer-cli/src/utils/botEvents.ts, validator-cli/src/utils/botEvents.ts, validator-cli/src/utils/errors.ts
Added new BotEvents: HASHI_NOT_CONFIGURED, NO_CLAIM_FETCHED, CLAIM_MISMATCH, FINALITY_ISSUE, FINALITY_ERROR; introduced NoMessageSavedError class.
Watcher & Transaction Handlers
validator-cli/src/watcher.ts, validator-cli/src/utils/transactionHandlers/arbToEthHandler.test.ts
Increased RPC_BLOCK_LIMIT from 100 to 1000; switched from "latest" to "finalized" block references; added heartbeat integration; introduced CYCLE_DELAY_MS (2 minutes); updated getClaim call signature with network and emitter parameters.
Package Dependencies
relayer-cli/package.json, validator-cli/package.json
Removed @kleros/vea-contracts workspace dependency and pm2; added ethers ^6.13.5, graphql ^16.8.1, graphql-request ^6.1.0, pino ^10.1.0, pino-pretty ^13.1.2.
VeaScan Subgraph Updates
veascan-subgraph-inbox/schema.graphql, veascan-subgraph-inbox/src/VeaInbox.ts, veascan-subgraph-inbox/package.json
Added inbox: Inbox! relation field to Message type; refactored handleMessageSent to parse _msgSender from message data and link to Inbox; bumped package version from 0.2.4 to 0.3.4.
Documentation & Configuration
relayer-cli/README.md, validator-cli/README.md, relayer-cli/.env.dist
Updated deployment guides from PM2 to Docker; added environment variables SENDER_ADDRESSES_HASHI, RPC_ARBITRUM_SEPOLIA, RPC_STORY, RPC_ARBITRUM_ONE, TRANSACTION_BATCHER_CONTRACT_SEPOLIA, TRANSACTION_BATCHER_CONTRACT_CHIADO; removed HASHI_EXECUTOR_ENABLED; narrowed VEAOUTBOX_CHAINS to Sepolia only.
Test Updates
relayer-cli/src/utils/hashi.test.ts, relayer-cli/src/utils/relayerHelpers.test.ts, validator-cli/src/helpers/claimer.test.ts, validator-cli/src/helpers/snapshot.test.ts, validator-cli/src/utils/claim.test.ts
Updated test mocks and assertions to reflect new signatures for Hashi executor functions, state key renames, and claim/snapshot fetcher integration; added new test dependencies for fetchBlocksAndCheckFinality, fetchLastClaimedEpoch, and network/emitter parameters.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • Feat/arb sep chaido deploy #359 — Touches same bridge/inbox/outbox deployment and bridging configuration surfaces (RPC/env vars, router/AMB addresses, contract deployment artifacts).
  • Feat/relayer tests #395 — Modifies same relayer-cli modules (BotEvents/logger, relayerHelpers/start/updateStateFile signatures, event emitter integration).
  • Feat/hashi executor #434 — Implements Hashi executor with overlapping changes to hashi state persistence, runHashiExecutor/toExecuteMessage signatures, and botEvents/logger integration.

Suggested labels

Type: Maintenance :construction:, Package: Bots, Package: VeaScan Subgraph

Suggested reviewers

  • alcercu
  • jaybuidl

Poem

🐰 From contracts kept in packages old, to local paths of cleaner fold,
Hashi bridges now shall soar, with heartbeats sent from shore to shore,
Pino logs in colors bright, docker builds with all our might—
State and snapshots verified true, a relay reborn in form anew!

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.83% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Chore/deploy' is vague and generic, using non-descriptive terms that don't convey meaningful information about the changeset's primary purpose. Consider using a more specific title that reflects the main changes, such as 'Add Hashi executor and improve relayer/validator deployment' or 'Refactor to Hashi-based execution and add Docker deployment support'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing touches
  • 📝 Generate docstrings

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

Copy link
Copy Markdown
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: 12

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
validator-cli/src/helpers/snapshot.test.ts (1)

151-174: Test mock return value doesn't match expected interface.

Similar to the previous test, fetchLastSavedMessage returns "message-3" instead of the expected object shape { id, stateRoot }. This will cause the destructuring on line 90 of snapshot.ts to fail or produce unexpected results.

🔎 Proposed fix
-      fetchLastSavedMessage = jest.fn().mockResolvedValue("message-3");
+      fetchLastSavedMessage = jest.fn().mockResolvedValue({ id: "inbox-3", stateRoot: "0xdifferent" });
relayer-cli/src/utils/relay.ts (1)

178-186: Potential NaN return when no messages are relayed.

If lastNonce remains null (no messages relayed for any sender), line 185 returns null + 1 which evaluates to 1 in JavaScript (not NaN as I initially thought, since null coerces to 0). However, returning 1 when nothing was relayed may be misleading.

The return value should indicate that no messages were relayed to avoid confusion for callers.

🔎 Proposed fix
   if (lastNonce != null) {
     const gasLimit = await batcher.batchSend.estimateGas(targets, values, datas);
     const tx = await batcher.batchSend(targets, values, datas, { gasLimit });
     const receipt = await tx.wait();
     emitter.emit(BotEvents.RELAY_ALL_FROM, nonce, msgSenders, receipt.hash);
+    return lastNonce + 1;
   }

-  return lastNonce + 1; // return current nonce
+  return null; // No messages were relayed
 };
relayer-cli/src/utils/relayerHelpers.ts (1)

81-81: Inconsistent path construction may cause issues.

Line 34 uses path.join(stateDir, ...) which handles missing trailing slashes, but line 81 uses string concatenation with process.env.STATE_DIR + network + .... If STATE_DIR lacks a trailing slash, this will produce an incorrect path like /path/to/statenetwork_123.json.

Suggested fix
-    const chain_state_file = process.env.STATE_DIR + network + "_" + chainId + ".json";
+    const chain_state_file = path.join(stateDir, `${network}_${chainId}.json`);
validator-cli/src/utils/graphQueries.ts (1)

23-35: Functions return undefined for unsupported chain IDs.

Both getOutboxSubgraphUrl and getInboxSubgraphUrl lack a default return/throw for unsupported chain IDs. This causes implicit undefined returns while the type signature promises string. Callers like getClaimsForEpochs pass this directly to request(), which will fail with an unclear error.

Suggested fix
 const getOutboxSubgraphUrl = (chainId: number): string => {
   if (chainId === 11155111) {
     return process.env.VEAOUTBOX_SUBGRAPH_SEPOLIA || "";
   } else if (chainId === 10200) {
     return process.env.VEAOUTBOX_SUBGRAPH_CHIADO || "";
   }
+  throw new Error(`Unsupported outbox chain ID: ${chainId}`);
 };
 const getInboxSubgraphUrl = (chainId: number): string => {
   // using destination chainId's for inbox
   if (chainId === 11155111 || chainId === 10200) {
     return process.env.VEAINBOX_SUBGRAPH_ARBSEPOLIA || "";
   }
+  throw new Error(`Unsupported inbox chain ID: ${chainId}`);
 };
♻️ Duplicate comments (5)
contracts/deploy/01-outbox/01-arb-sepolia-to-sepolia-outbox.ts (1)

16-16: Epoch period reduction is consistent.

This change aligns with the epoch period reduction across all deployment configurations. The same verification and testing considerations mentioned for the Chiado-to-ArbSepolia outbox apply here.

contracts/deploy/02-inbox/02-chiado-to-arb-sepolia-inbox.ts (1)

12-12: LGTM - Consistent epoch period update.

This inbox deployment aligns with the coordinated epoch period reduction across the PR.

contracts/deploy/01-outbox/01-arb-sepolia-to-chiado-outbox.ts (1)

15-15: LGTM - Consistent epoch period update.

This change is part of the coordinated epoch period reduction across all deployment configurations.

contracts/deploy/02-inbox/02-arb-sepolia-to-sepolia-inbox.ts (1)

11-11: LGTM - Consistent epoch period update.

This inbox deployment configuration aligns with the epoch period reduction applied across the PR.

contracts/deploy/02-inbox/02-arb-sepolia-to-chiado-inbox.ts (1)

11-11: LGTM - Consistent epoch period update.

This change maintains consistency with the epoch period reduction across all deployment configurations.

🧹 Nitpick comments (26)
relayer-cli/src/utils/proof.ts (1)

23-53: Consider adding explicit return type annotation.

The getMessageDataToRelay function lacks an explicit return type annotation. Adding one would improve type safety and make it clearer that the function returns a 3-element tuple.

🔎 Suggested type annotation
 const getMessageDataToRelay = async (
   chainId: number,
   inbox: string,
   nonce: number,
   requestGraph: typeof request = request
-) => {
+): Promise<[string, string, string] | undefined> => {
   try {
relayer-cli/package.json (1)

28-28: Consider using a caret range for pino-pretty.

The version 13.1.2 is pinned exactly, while other dependencies use caret ranges (e.g., ^6.13.5, ^10.1.0). Based on learnings, floating versions are preferred in this project. Consider changing to ^13.1.2 for consistency.

🔎 Proposed fix
-    "pino-pretty": "13.1.2",
+    "pino-pretty": "^13.1.2",
relayer-subgraph-inbox/src/vea-inbox.ts (2)

28-28: Downgrade debug log from log.error to log.info or log.debug.

This log statement appears to be for debugging purposes rather than an actual error condition. Using log.error for routine message processing can pollute error logs and make it harder to identify real issues.

🔎 Proposed fix
-  log.error("processing {}", [_nonce.toString()]);
+  log.info("processing {}", [_nonce.toString()]);

83-83: Same issue: downgrade debug log from log.error to log.info.

🔎 Proposed fix
-  log.error("processing {}", [entity.nonce.toString()]);
+  log.info("processing {}", [entity.nonce.toString()]);
relayer-cli/src/consts/bridgeRoutes.ts (1)

22-24: Consider improving inline comments for clarity.

The comments for yaruAddress and hashiAddress both say "Hashi (Yaru) contract address", but hashiAddress is the Hashi contract, not Yaru. This appears to be a copy-paste oversight.

🔎 Proposed fix
-  yahoAddress?: string; // Hashi (Yaru) contract address
-  yaruAddress?: string; // Hashi (Yaru) contract address
-  hashiAddress?: string; // Hashi (Yaru) contract address
+  yahoAddress?: string; // Yaho contract address (on source chain)
+  yaruAddress?: string; // Yaru contract address (on destination chain)
+  hashiAddress?: string; // Hashi contract address (on destination chain)
validator-cli/Dockerfile (1)

41-42: TypeChain skip logic may lead to stale artifacts.

The conditional [ -d contracts/typechain-types ] skips the build if the directory exists, but this could result in stale TypeChain types if contracts have changed. Consider removing the condition to always rebuild, or use a more robust cache invalidation strategy.

🔎 Alternative: Always rebuild to ensure fresh artifacts
-RUN [ -d contracts/typechain-types ] && echo "TypeChain present, skipping build" || yarn workspace @kleros/vea-contracts build
+RUN yarn workspace @kleros/vea-contracts build

If build time is a concern, Docker layer caching on the COPY step (line 36) will naturally invalidate when contracts change.

validator-cli/src/helpers/snapshot.test.ts (1)

13-14: Unused mock fetchClaimForEpoch in tests.

The fetchClaimForEpoch mock is defined and passed to test parameters, but based on the isSnapshotNeeded function signature in snapshot.ts (lines 60-69 in relevant code snippets), there is no fetchClaimForEpoch parameter—only fetchLastClaimedEpoch. This mock appears to be dead code.

Either remove the unused mock or verify if this is intended for a future implementation.

🔎 Proposed fix
-  let fetchClaimForEpoch: jest.Mock;
   ...
-    fetchClaimForEpoch = jest.fn().mockResolvedValue({
-      stateRoot: "0xabcde",
-    });

And remove fetchClaimForEpoch from all test params objects.

Also applies to: 33-35, 52-53

docker-compose.yml (1)

1-25: Consider adding health checks and persistent volumes for production readiness.

The compose file is functional but lacks:

  1. Health checks - Useful for orchestration and monitoring
  2. Resource limits - Prevents runaway memory/CPU usage
  3. Persistent volumes - The relayer creates a state directory; without a volume mount, state is lost on container restart
🔎 Example additions
 services:
   validator:
     build:
       context: .
       dockerfile: ./validator-cli/Dockerfile
     command: yarn start --saveSnapshot 
     env_file:
       - path: ./validator-cli/.env
         required: true
     restart: unless-stopped
+    healthcheck:
+      test: ["CMD", "node", "-e", "process.exit(0)"]
+      interval: 30s
+      timeout: 10s
+      retries: 3
     networks:
       - vea-network

   relayer:
     build:
       context: .
       dockerfile: ./relayer-cli/Dockerfile
     env_file:
       - path: ./relayer-cli/.env
         required: true
     restart: unless-stopped
+    volumes:
+      - relayer-state:/home/node/monorepo/relayer-cli/state
     networks:
       - vea-network
+
+volumes:
+  relayer-state:
 networks:
   vea-network:
relayer-cli/src/utils/hashiHelpers/abi.ts (1)

13-342: Consider adding TypeScript type annotation for YaruAbi.

The YaruAbi constant is well-structured. Adding an explicit type annotation would improve IDE support and catch typos at compile time.

🔎 Optional type annotation
+import { InterfaceAbi } from "ethers";
+
-export const YaruAbi = [
+export const YaruAbi: InterfaceAbi = [
relayer-cli/src/utils/graphQueries.ts (2)

4-19: Missing environment variable validation and potential GraphQL injection.

  1. No validation for RELAYER_SUBGRAPH: If undefined, request(undefined, query) will fail with an unclear error.

  2. Potential GraphQL injection (Line 7): The inboxAddress is directly interpolated into the query string. While this comes from internal sources, consider using parameterized queries if supported.

  3. Console.log for errors (Line 16): Should use structured logging consistent with the project's logging utilities.

🔎 Proposed fix for validation
 async function getVeaMsgTrnx(nonce: number, inboxAddress: string) {
   try {
     const subgraph = process.env.RELAYER_SUBGRAPH;
+    if (!subgraph) {
+      throw new Error("RELAYER_SUBGRAPH environment variable is not set");
+    }
     const query = `{messageSents(first: 1, where: {nonce: ${nonce}, inbox: "${inboxAddress}"}) {

Based on learnings, environment variable validation will be handled during dockerization, so this may be deferred.


63-85: Type inconsistency in return value.

Line 84 maps nonce with type annotation { nonce: string | number }, but the MessageSent interface on line 48-50 defines nonce as number. The GraphQL response likely returns strings for numeric values.

Also, consider adding error handling similar to getVeaMsgTrnx for consistency.

🔎 Proposed fix for type consistency
 interface MessageSent {
-  nonce: number;
+  nonce: string;
 }
 
 ...
 
-  return result[`messageSents`].map((a: { nonce: string | number }) => Number(a.nonce));
+  return result.messageSents.map((msg) => Number(msg.nonce));
relayer-cli/.env.dist (1)

27-27: Add trailing newline.

The file should end with a blank line for proper formatting.

🔎 Proposed fix
 # Hashi Executor enabler
 HASHI_EXECUTOR_ENABLED=true
+
relayer-cli/src/utils/heartbeat.ts (3)

6-9: Unused status parameter.

The status parameter is declared but never used in the function. If it's intended for future use, consider documenting this. Otherwise, remove it or incorporate it into the heartbeat request (e.g., as a query parameter or in the User-Agent).


22-43: Consider removing unused response data accumulation.

The response data is accumulated but never used. Since this is a fire-and-forget heartbeat, you can remove the data accumulation for clarity.

🔎 Proposed refactor
     return new Promise((resolve, reject) => {
       const req = https.request(options, (res) => {
-        let data = "";
-        res.on("data", (chunk) => {
-          data += chunk;
-        });
         res.on("end", () => {
           resolve();
         });
       });

44-46: Silent error handling is acceptable for heartbeat telemetry.

The silent failure approach is appropriate for non-critical heartbeat signals. However, for debugging purposes, consider optionally logging errors when a debug flag is enabled.

validator-cli/src/helpers/validator.ts (1)

53-60: Verify finality check flow and unused destructured element.

  1. The destructuring on line 54 skips element at index 1 (appears to be ethBlock based on the function name). Confirm this is intentional and the value is not needed downstream.

  2. The check res === undefined || finalityIssueFlagArb || finalityIssueFlagEth on line 55 could throw if res is actually undefined since the destructuring on line 54 would fail first. Consider reordering:

🔎 Suggested safer pattern
-  const res = await fetchBlocksAndCheckFinality(queryRpc, veaInboxProvider, epoch, epochPeriod, emitter);
-  const [arbitrumBlock, , finalityIssueFlagArb, finalityIssueFlagEth] = res;
-  if (res === undefined || finalityIssueFlagArb || finalityIssueFlagEth) {
+  const res = await fetchBlocksAndCheckFinality(queryRpc, veaInboxProvider, epoch, epochPeriod, emitter);
+  if (!res) {
+    emitter.emit(BotEvents.FINALITY_ISSUE, epoch);
+    return null;
+  }
+  const [arbitrumBlock, , finalityIssueFlagArb, finalityIssueFlagEth] = res;
+  if (finalityIssueFlagArb || finalityIssueFlagEth) {
     emitter.emit(BotEvents.FINALITY_ISSUE, epoch);
     return null;
   }
validator-cli/src/utils/heartbeat.ts (1)

1-47: Code duplication with relayer-cli heartbeat utility.

This file is nearly identical to relayer-cli/src/utils/heartbeat.ts. Consider extracting to a shared package to reduce maintenance burden and ensure consistent behavior.

relayer-cli/src/utils/hashi.test.ts (3)

6-14: MockEmitter duplicated from validator-cli.

This MockEmitter class is identical to the one in validator-cli/src/utils/emitter.ts. Consider importing from a shared location or extracting to a common test utilities module.


118-131: Inconsistent mock return values for hasThresholdMet.

Line 110 uses HashiExecutionStatus.EXECUTABLE while line 126 uses false. For consistency, line 126 should use HashiExecutionStatus.NOT_EXECUTABLE or similar enum value if one exists.


17-17: Use const for mockEmitter.

mockEmitter is never reassigned.

-  let mockEmitter = new MockEmitter();
+  const mockEmitter = new MockEmitter();
validator-cli/src/utils/logger.ts (1)

9-10: Consider making log level configurable.

The log level is hardcoded to "debug". Consider making it configurable via environment variable for production deployments where you may want "info" or higher.

 const loggerOptions = {
-  level: "debug",
+  level: process.env.LOG_LEVEL || "debug",
   base: { service: "Vea" },
relayer-cli/src/utils/hashiHelpers/hashiMsgUtils.ts (3)

11-23: Return type inconsistency: BigInt vs bigint.

The function signature declares BigInt (the constructor/wrapper object type) but hexToBigInt32Bytes returns bigint (the primitive type). While TypeScript allows this assignment, using the primitive bigint is more idiomatic and consistent.

Suggested fix
 export function getHashiMsgId(
   sourceChainId: bigint | number | string,
   dispatcherAddress: string,
   message: HashiMessage
-): BigInt {
+): bigint {

34-41: Unreachable code branch for message.data handling.

Per the HashiMessage interface, data is typed as string. The else branch at line 41 (getBytes(message.data)) is unreachable since the typeof message.data === "string" condition will always be true. Consider removing the dead branch or updating the type if byte arrays are expected.

Simplified version
-  const data =
-    typeof message.data === "string"
-      ? isHexString(message.data)
-        ? message.data
-        : (() => {
-            throw new Error("message.data must be 0x-hex");
-          })()
-      : getBytes(message.data);
+  if (!isHexString(message.data)) {
+    throw new Error("message.data must be 0x-hex");
+  }
+  const data = message.data;

56-63: Consider using ethers' native BigInt conversion.

The manual byte iteration can be replaced with a direct conversion. The BigInt() constructor in JavaScript natively handles hex strings prefixed with 0x.

Simplified version
 function hexToBigInt32Bytes(hex32: string): bigint {
-  const bytes = toBeArray(hex32);
-  // Convert bytes to BigInt (big-endian)
-  let n = BigInt(0);
-  for (const b of Array.from(bytes)) {
-    n = (n << BigInt(8)) + BigInt(b);
-  }
-  return n;
+  return BigInt(hex32);
 }
validator-cli/src/utils/claim.ts (1)

79-126: Duplicated graph fetch and claim population logic.

Lines 81-96 (in catch block) and lines 103-118 (in post-validation) contain nearly identical code for fetching from graph and populating claim fields. Consider extracting to a helper function to reduce duplication and maintenance burden.

Example helper extraction
const populateClaimFromGraph = async (
  claim: ClaimStruct,
  claimFromGraph: ClaimData,
  veaOutboxProvider: JsonRpcProvider
): Promise<void> => {
  claim.stateRoot = claimFromGraph.stateroot;
  claim.claimer = claimFromGraph.bridger;
  claim.timestampClaimed = claimFromGraph.timestamp;
  if (claimFromGraph.verification?.startTimestamp) {
    claim.timestampVerification = claimFromGraph.verification.startTimestamp;
    const txReceipt = await veaOutboxProvider.getTransactionReceipt(claimFromGraph.verification.startTxHash);
    claim.blocknumberVerification = txReceipt.blockNumber;
  }
  if (claimFromGraph.challenge) {
    claim.challenger = claimFromGraph.challenge.challenger;
  }
};
relayer-cli/src/utils/hashi.ts (1)

54-61: No error handling for individual message status checks.

If isMessageExecutable throws for any nonce, the entire executor stops without processing remaining messages or saving progress. Consider wrapping in try/catch to log errors and continue with remaining nonces.

Suggested error handling
   while (nonce < inboxCount) {
     // ToDo: Add cooldown periods for nonces that cannot be executed.
-    const messageState = await isMessageExecutable({ chainId, nonce, veaInboxAddress, rpcInbox });
-    if (messageState != null && !messageState.executed) {
-      executableNonces.push(messageState);
+    try {
+      const messageState = await isMessageExecutable({ chainId, nonce, veaInboxAddress, rpcInbox });
+      if (messageState != null && !messageState.executed) {
+        executableNonces.push(messageState);
+      }
+    } catch (e) {
+      // Log error but continue processing remaining nonces
+      console.error(`Failed to check message status for nonce ${nonce}:`, e);
     }
     nonce++;
   }

# This is the final layer that will be deployed and run

# Node version for all Vea
FROM node:24.4-alpine AS relayer

Check warning

Code scanning / Scorecard

Pinned-Dependencies Medium

score is 7: containerImage not pinned by hash
Click Remediation section below to solve this issue
#

# Node version for Vea
FROM node:24.4-alpine AS validator-build

Check warning

Code scanning / Scorecard

Pinned-Dependencies Medium

score is 7: containerImage not pinned by hash
Click Remediation section below to solve this issue
# This is the final layer that will be deployed and run

# Node version for Vea
FROM node:24.4-alpine AS validator

Check warning

Code scanning / Scorecard

Pinned-Dependencies Medium

score is 7: containerImage not pinned by hash
Click Remediation section below to solve this issue
Copy link
Copy Markdown
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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
relayer-cli/src/utils/logger.ts (1)

100-109: Remove duplicate Hashi event listeners.

These event listeners duplicate the handlers already defined at lines 89-98. Both sets will fire for each event, causing:

  • Duplicate log entries (structured + console)
  • Inconsistent logging output
  • Performance overhead

These lines appear to be leftover code from the console.log-to-pino migration and should be removed.

🔎 Proposed fix
-  // Hashi executor logs
-  emitter.on(BotEvents.EXECUTING_HASHI, (startNonce, endNonce) => {
-    console.log(`Executing Hashi for nonces from ${startNonce} to ${endNonce}`);
-  });
-  emitter.on(BotEvents.HASHI_EXECUTED, (endNonce) => {
-    console.log(`Successfully executed Hashi till ${endNonce}`);
-  });
-  emitter.on(BotEvents.HASHI_BATCH_TXN, (txHash, batchSize) => {
-    console.log(`Hashi batch transaction ${txHash} for ${batchSize} messages`);
-  });
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b73cd89 and 0066b07.

📒 Files selected for processing (1)
  • relayer-cli/src/utils/logger.ts
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: relayer-cli/src/devnetRelayExample.ts:5-6
Timestamp: 2024-11-21T07:44:06.942Z
Learning: The files `contracts/deploy/02-inbox/02-arb-sepolia-to-chiado-inbox.ts` and `contracts/deploy/02-inbox/02-arb-sepolia-to-sepolia-inbox.ts` are not part of the current scope in this PR.
Learnt from: mani99brar
Repo: kleros/vea PR: 427
File: relayer-cli/package.json:17-21
Timestamp: 2025-07-07T12:31:37.880Z
Learning: In the kleros/vea project, floating versions (using caret ranges like ^0.5.5) are preferred for dependencies rather than pinning to exact versions. The team is comfortable with automatic minor and patch version updates.
Learnt from: mani99brar
Repo: kleros/vea PR: 430
File: contracts/src/interfaces/inboxes/IVeaInbox.sol:0-0
Timestamp: 2025-08-27T07:02:45.825Z
Learning: The sendMessage signature simplification in IVeaInbox.sol and related call site updates across relay-cli and test files were fixed in a separate PR by mani99brar.
Learnt from: mani99brar
Repo: kleros/vea PR: 395
File: relayer-cli/src/utils/relayerHelpers.ts:95-97
Timestamp: 2025-01-15T07:41:34.012Z
Learning: The shutdown manager improvements in relayer-cli/src/utils/relayerHelpers.ts, including proper exit code handling, will be addressed in a separate PR to keep the current changes focused.
Learnt from: mani99brar
Repo: kleros/vea PR: 434
File: relayer-cli/src/utils/hashi.ts:206-235
Timestamp: 2025-10-27T13:45:23.420Z
Learning: The Hashi executor in relayer-cli currently only supports routes from Arbitrum Sepolia (chain ID 421614), so the hardcoded SOURCE_CHAIN_ID constant in relayer-cli/src/utils/hashi.ts is acceptable for the current scope. This will be updated when support for other source chains is added.
Learnt from: fcanela
Repo: kleros/vea PR: 377
File: relayer-cli/src/utils/lock.ts:53-54
Timestamp: 2024-12-10T11:50:03.499Z
Learning: The `relayer-cli` project plans to transition away from file-based lock mechanisms (e.g., in `src/utils/lock.ts`) due to deployment in Docker containers within a cloud environment, where file-based implementations are not ideal. They intend to adopt a solution suitable for both local and cloud deployments.
📚 Learning: 2024-11-26T11:30:36.180Z
Learnt from: fcanela
Repo: kleros/vea PR: 344
File: relayer-cli/src/utils/relay.ts:28-40
Timestamp: 2024-11-26T11:30:36.180Z
Learning: In `relayer-cli/src/utils/relay.ts`, avoid suggesting adding try/catch blocks that only log errors and rethrow in the `relay` function.

Applied to files:

  • relayer-cli/src/utils/logger.ts
⏰ 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). (2)
  • GitHub Check: dependency-review
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
relayer-cli/src/utils/logger.ts (2)

1-28: LGTM - Clean pino logger setup with conditional transport.

The structured logging configuration is well implemented with appropriate conditional transport selection based on environment variables.


40-42: LGTM - Clean delegation pattern.

The delegation to configurableInitialize provides good flexibility for future enhancements.

Copy link
Copy Markdown
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: 0

♻️ Duplicate comments (1)
validator-cli/src/utils/claim.test.ts (1)

15-15: Remove describe.only before merging.

This was already flagged in a previous review and acknowledged. The .only modifier restricts test execution to this suite only.

🧹 Nitpick comments (3)
validator-cli/src/helpers/claimer.ts (2)

139-144: Consider explicit array length check for clarity.

Line 140 accesses lastClaimLogs[lastClaimLogs.length - 1].data without checking if the array is empty. If no claims exist yet, this throws and execution moves to the catch block. While functionally correct (the fallback handles it), an explicit length check would make the intent clearer:

try {
  const lastClaimLogs = await veaOutbox.queryFilter(veaOutbox.filters.Claimed());
  if (lastClaimLogs.length > 0) {
    lastClaimedStateroot = lastClaimLogs[lastClaimLogs.length - 1].data;
  } else {
    // Explicitly handle no claims case
    const claimData = await fetchLatestClaimedEpoch(veaOutbox.target, chainId);
    lastClaimedStateroot = claimData ? claimData.stateroot : ethers.ZeroHash;
  }
} catch {
  const claimData = await fetchLatestClaimedEpoch(veaOutbox.target, chainId);
  lastClaimedStateroot = claimData ? claimData.stateroot : ethers.ZeroHash;
}

This distinguishes between "no claims yet" and "query failed," improving debuggability.


145-147: Optional: Potentially unreachable null check.

Since both the try block (line 140) and catch block (line 143) assign a value to lastClaimedStateroot, the null check at lines 145-147 appears unreachable unless the catch block itself throws (in which case the function would throw, not return null).

If you intend this as defensive programming, consider adding a comment. Otherwise, you could remove these lines as the subsequent logic at line 148 will handle all valid cases.

validator-cli/src/utils/graphQueries.ts (1)

112-120: Consider deriving blocknumberVerification from transaction receipt.

Line 117 sets blocknumberVerification: 0 with a comment noting additional data is needed. However, when claim.verification?.startTxHash is available, you could fetch the transaction receipt to get the actual block number (similar to lines 93-94 in getClaim).

🔎 Potential enhancement

This would require making additional provider calls, so it might be a trade-off between accuracy and performance. Alternatively, document that callers should not rely on blocknumberVerification or honest fields from this function.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0066b07 and 6232598.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (7)
  • package.json
  • validator-cli/src/helpers/claimer.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/utils/claim.ts
  • validator-cli/src/utils/graphQueries.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json
🧰 Additional context used
🧠 Learnings (43)
📓 Common learnings
Learnt from: mani99brar
Repo: kleros/vea PR: 395
File: relayer-cli/src/utils/relayerHelpers.ts:95-97
Timestamp: 2025-01-15T07:41:34.012Z
Learning: The shutdown manager improvements in relayer-cli/src/utils/relayerHelpers.ts, including proper exit code handling, will be addressed in a separate PR to keep the current changes focused.
Learnt from: mani99brar
Repo: kleros/vea PR: 427
File: relayer-cli/package.json:17-21
Timestamp: 2025-07-07T12:31:37.880Z
Learning: In the kleros/vea project, floating versions (using caret ranges like ^0.5.5) are preferred for dependencies rather than pinning to exact versions. The team is comfortable with automatic minor and patch version updates.
Learnt from: mani99brar
Repo: kleros/vea PR: 430
File: contracts/src/interfaces/inboxes/IVeaInbox.sol:0-0
Timestamp: 2025-08-27T07:02:45.825Z
Learning: The sendMessage signature simplification in IVeaInbox.sol and related call site updates across relay-cli and test files were fixed in a separate PR by mani99brar.
Learnt from: mani99brar
Repo: kleros/vea PR: 434
File: relayer-cli/src/utils/hashiHelpers/hashiTypes.ts:1-16
Timestamp: 2025-10-27T13:45:22.819Z
Learning: In the Vea relayer-cli project, HashiMessage interface and related types use simple number and string types. Type conversion and normalization (e.g., number to bigint, string to bytes) is handled in encoding utilities like encodeMessageForAbi before on-chain calls, rather than widening the interface types themselves.
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/epochHandler.ts:13-13
Timestamp: 2024-12-11T08:52:17.062Z
Learning: In `bridger-cli/src/utils/epochHandler.ts`, the `veaOutbox` parameter is intentionally typed as `any` because the script is designed to be agnostic for multiple contracts.
Learnt from: mani99brar
Repo: kleros/vea PR: 424
File: validator-cli/src/helpers/claimer.ts:72-76
Timestamp: 2025-06-05T12:17:21.782Z
Learning: In validator-cli/src/helpers/claimer.ts, the outboxStateRoot captured at the beginning of the checkAndClaim function won't change for the epoch being claimed, so there's no race condition concern when reusing it in makeClaim/makeClaimDevnet functions.
📚 Learning: 2024-11-20T11:50:15.304Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: contracts/src/test/ArbToGnosis/VeaInboxArbToGnosisMock.sol:27-38
Timestamp: 2024-11-20T11:50:15.304Z
Learning: In `VeaInboxArbToGnosisMock.sendSnapshot`, `epochPeriod` is guaranteed to be non-zero, so a check for `epochPeriod > 0` is unnecessary.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
📚 Learning: 2025-06-05T12:17:21.782Z
Learnt from: mani99brar
Repo: kleros/vea PR: 424
File: validator-cli/src/helpers/claimer.ts:72-76
Timestamp: 2025-06-05T12:17:21.782Z
Learning: In validator-cli/src/helpers/claimer.ts, the outboxStateRoot captured at the beginning of the checkAndClaim function won't change for the epoch being claimed, so there's no race condition concern when reusing it in makeClaim/makeClaimDevnet functions.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/helpers/claimer.test.ts
  • validator-cli/src/utils/graphQueries.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-12-13T05:16:07.386Z
Learnt from: mani99brar
Repo: kleros/vea PR: 379
File: contracts/package.json:75-75
Timestamp: 2024-12-13T05:16:07.386Z
Learning: In this project, replacing imports from `ethersproject` to `ethers` may require extensive changes and can be out of scope for certain PRs.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
📚 Learning: 2024-12-16T09:24:33.478Z
Learnt from: mani99brar
Repo: kleros/vea PR: 383
File: contracts/test/integration/ArbToGnosis.ts:520-520
Timestamp: 2024-12-16T09:24:33.478Z
Learning: In the TypeScript integration tests (`contracts/test/integration/ArbToGnosis.ts`), adding null checks after retrieving blocks using `await ethers.provider.getBlock` is unnecessary because the test will fail if the block is not found.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/helpers/claimer.test.ts
  • validator-cli/src/utils/graphQueries.ts
📚 Learning: 2024-12-10T08:27:15.815Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/epochHandler.ts:63-68
Timestamp: 2024-12-10T08:27:15.815Z
Learning: In the file `bridger-cli/src/utils/epochHandler.ts`, the calculation within the `checkForNewEpoch` function is correct as implemented and has been tested.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/helpers/claimer.ts
📚 Learning: 2024-12-09T10:18:00.133Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/ethers.ts:20-82
Timestamp: 2024-12-09T10:18:00.133Z
Learning: In `bridger-cli/src/utils/ethers.ts`, prefer to keep the existing `chainId` checks without refactoring to avoid overcomplicating the code with additional conditional logic.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-11-20T11:50:15.304Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: contracts/src/test/ArbToGnosis/VeaInboxArbToGnosisMock.sol:27-38
Timestamp: 2024-11-20T11:50:15.304Z
Learning: Additional validation for `_gasLimit` and `_claim` parameters in `VeaInboxArbToGnosisMock.sendSnapshot` is unnecessary because there's no incentive for manipulation in this context.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/helpers/claimer.test.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2025-08-27T07:02:45.825Z
Learnt from: mani99brar
Repo: kleros/vea PR: 430
File: contracts/src/interfaces/inboxes/IVeaInbox.sol:0-0
Timestamp: 2025-08-27T07:02:45.825Z
Learning: The sendMessage signature simplification in IVeaInbox.sol and related call site updates across relay-cli and test files were fixed in a separate PR by mani99brar.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/utils/graphQueries.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-12-16T09:22:57.434Z
Learnt from: mani99brar
Repo: kleros/vea PR: 383
File: contracts/test/integration/ArbToGnosis.ts:114-114
Timestamp: 2024-12-16T09:22:57.434Z
Learning: In the local Hardhat deployment for testing, `VeaInboxArbToGnosisMock` is deployed with the identifier name `VeaInboxArbToGnosis`, so it's appropriate to retrieve it using `getContract("VeaInboxArbToGnosis")` and cast it to `VeaInboxArbToGnosisMock` in `ArbToGnosis.ts`.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-12-09T09:40:28.400Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/transactionHandler.ts:13-13
Timestamp: 2024-12-09T09:40:28.400Z
Learning: In `bridger-cli/src/utils/transactionHandler.ts`, the `veaOutbox` implementations differ for each chain, but a common interface should be defined for type checks to enhance type safety.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/utils/graphQueries.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-11-21T05:40:34.912Z
Learnt from: mani99brar
Repo: kleros/vea PR: 344
File: validator-cli/src/utils/arbMsgExecutor.ts:52-85
Timestamp: 2024-11-21T05:40:34.912Z
Learning: In the `getMessageStatus` function, returning `undefined` for failed status fetches is acceptable because failures may be due to temporary finality issues.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/utils/graphQueries.ts
📚 Learning: 2025-01-15T07:41:34.012Z
Learnt from: mani99brar
Repo: kleros/vea PR: 395
File: relayer-cli/src/utils/relayerHelpers.ts:95-97
Timestamp: 2025-01-15T07:41:34.012Z
Learning: The shutdown manager improvements in relayer-cli/src/utils/relayerHelpers.ts, including proper exit code handling, will be addressed in a separate PR to keep the current changes focused.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/utils/graphQueries.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-11-21T07:44:06.942Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: relayer-cli/src/devnetRelayExample.ts:5-6
Timestamp: 2024-11-21T07:44:06.942Z
Learning: The files `contracts/deploy/02-inbox/02-arb-sepolia-to-chiado-inbox.ts` and `contracts/deploy/02-inbox/02-arb-sepolia-to-sepolia-inbox.ts` are not part of the current scope in this PR.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-12-02T10:16:56.825Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: validator-cli/src/ArbToEth/watcherArbToGnosis.ts:829-840
Timestamp: 2024-12-02T10:16:56.825Z
Learning: In the `validator-cli/src/ArbToEth/watcherArbToGnosis.ts` file, avoid adding redundant error handling in functions like `reconstructChallengeProgress` when error handling is already adequately managed.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/utils/graphQueries.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-11-20T10:49:25.392Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: contracts/deploy/01-outbox/01-arb-to-gnosis-outbox.ts:93-98
Timestamp: 2024-11-20T10:49:25.392Z
Learning: In `contracts/deploy/01-outbox/01-arb-to-gnosis-outbox.ts`, when resurrecting testnets, it's acceptable to use `getContractAddress()` for contract address prediction.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/utils/claim.test.ts
📚 Learning: 2024-12-11T08:52:17.062Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/epochHandler.ts:13-13
Timestamp: 2024-12-11T08:52:17.062Z
Learning: In `bridger-cli/src/utils/epochHandler.ts`, the `veaOutbox` parameter is intentionally typed as `any` because the script is designed to be agnostic for multiple contracts.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/utils/graphQueries.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-12-11T08:52:23.697Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/epochHandler.ts:38-50
Timestamp: 2024-12-11T08:52:23.697Z
Learning: The `getBlockNumberFromEpoch` function in `bridger-cli/src/utils/epochHandler.ts` is currently unused and will be addressed in a future issue.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/utils/graphQueries.ts
📚 Learning: 2024-12-09T09:03:31.474Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/graphQueries.ts:12-34
Timestamp: 2024-12-09T09:03:31.474Z
Learning: In `bridger-cli/src/utils/graphQueries.ts`, within the `getClaimForEpoch` function, returning `result['claims'][0]` is sufficient because it will be `undefined` if `result['claims']` is an empty array, making additional checks unnecessary.

Applied to files:

  • validator-cli/src/helpers/snapshot.test.ts
  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/helpers/claimer.test.ts
  • validator-cli/src/utils/graphQueries.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-12-10T04:59:10.224Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/claim.ts:23-32
Timestamp: 2024-12-10T04:59:10.224Z
Learning: In `bridger-cli/src/utils/claim.ts`, within the `fetchClaim` function, when `claimData` is undefined, avoid initializing it with default values, as this can result in incorrect claim values and make issues harder to identify.

Applied to files:

  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/helpers/claimer.test.ts
  • validator-cli/src/utils/graphQueries.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-12-09T10:54:09.943Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/claim.ts:42-51
Timestamp: 2024-12-09T10:54:09.943Z
Learning: In the `bridger-cli/src/utils/claim.ts` file, within the `fetchClaim` function, explicit error handling for provider calls and event queries is not required; errors should be allowed to propagate naturally.

Applied to files:

  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/helpers/claimer.test.ts
  • validator-cli/src/utils/graphQueries.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-11-27T10:48:48.433Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: validator-cli/src/ArbToEth/watcherArbToGnosis.ts:24-24
Timestamp: 2024-11-27T10:48:48.433Z
Learning: In the `validator-cli` codebase, both `arbitrumToEth` and `arbitrumToGnosis` modules use the same `ClaimStruct`, so importing `ClaimStruct` from either module is acceptable.

Applied to files:

  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/utils/graphQueries.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-12-09T10:54:57.068Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/claim.ts:56-69
Timestamp: 2024-12-09T10:54:57.068Z
Learning: In the TypeScript file 'bridger-cli/src/utils/claim.ts', the upper layers handle input validation for the 'hashClaim' function. Therefore, explicit input validation within 'hashClaim' is not necessary.

Applied to files:

  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/helpers/claimer.test.ts
  • validator-cli/src/utils/graphQueries.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-12-09T09:04:04.819Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/graphQueries.ts:36-58
Timestamp: 2024-12-09T09:04:04.819Z
Learning: In `bridger-cli/src/utils/graphQueries.ts` (TypeScript), the `getVerificationStatus` function is no longer needed and has been removed.

Applied to files:

  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/utils/graphQueries.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2025-06-05T12:17:17.615Z
Learnt from: mani99brar
Repo: kleros/vea PR: 424
File: validator-cli/src/helpers/validator.ts:71-74
Timestamp: 2025-06-05T12:17:17.615Z
Learning: The challenger functionality in validator-cli/src/helpers/validator.ts is currently only supported for Network.TESTNET. There is no MAINNET support yet, which is why the network is hardcoded to Network.TESTNET when fetching and creating transaction handlers.

Applied to files:

  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/helpers/claimer.test.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-12-06T13:46:45.497Z
Learnt from: fcanela
Repo: kleros/vea PR: 377
File: relayer-cli/src/utils/lock.test.ts:22-50
Timestamp: 2024-12-06T13:46:45.497Z
Learning: In the `relayer-cli` project, when reviewing tests, avoid suggesting tests that check the functionality of Node.js native libraries like `fs`, as it's part of the native library's responsibilities.

Applied to files:

  • validator-cli/src/utils/claim.test.ts
📚 Learning: 2024-11-27T04:18:05.872Z
Learnt from: mani99brar
Repo: kleros/vea PR: 344
File: validator-cli/src/ArbToEth/watcherArbToEth.ts:732-745
Timestamp: 2024-11-27T04:18:05.872Z
Learning: In `validator-cli/src/ArbToEth/watcherArbToEth.ts`, input validation inside the `hashClaim` function is unnecessary because the upper layer ensures valid input before calling it.

Applied to files:

  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/helpers/claimer.test.ts
  • validator-cli/src/utils/graphQueries.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-12-06T13:44:13.639Z
Learnt from: fcanela
Repo: kleros/vea PR: 377
File: relayer-cli/src/utils/relayerHelpers.ts:6-6
Timestamp: 2024-12-06T13:44:13.639Z
Learning: In `relayer-cli/src/utils/relayerHelpers.ts`, in the `initialize` function, avoid wrapping `claimLock` in a try...catch block because the `LockfileExistsError` already provides a suitable error message, and adding a try...catch block introduces unnecessary complexity.

Applied to files:

  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/helpers/claimer.ts
📚 Learning: 2024-12-09T10:53:55.715Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/bridger.ts:25-109
Timestamp: 2024-12-09T10:53:55.715Z
Learning: In the `bridger-cli/src/bridger.ts` file, refactoring the main loop and adding additional error handling are not needed unless deemed necessary by the developer.

Applied to files:

  • validator-cli/src/utils/claim.test.ts
  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/utils/graphQueries.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-12-09T09:42:34.067Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/transactionHandler.ts:64-77
Timestamp: 2024-12-09T09:42:34.067Z
Learning: In the `TransactionHandler` class (`bridger-cli/src/utils/transactionHandler.ts`), it's acceptable to let methods like `makeClaim` fail without additional error handling.

Applied to files:

  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/helpers/claimer.test.ts
  • validator-cli/src/utils/graphQueries.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-12-02T10:08:28.998Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: validator-cli/src/ArbToEth/watcherArbToGnosis.ts:625-648
Timestamp: 2024-12-02T10:08:28.998Z
Learning: In `validator-cli/src/ArbToEth/watcherArbToGnosis.ts`, the function `findLatestL2BatchAndBlock` already handles the case when `fromArbBlock > latestBlockNumber`, so additional error handling for this case is unnecessary.

Applied to files:

  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/utils/graphQueries.ts
📚 Learning: 2024-11-27T05:13:07.353Z
Learnt from: mani99brar
Repo: kleros/vea PR: 344
File: validator-cli/src/ArbToEth/watcherArbToEth.ts:709-730
Timestamp: 2024-11-27T05:13:07.353Z
Learning: In `validator-cli/src/ArbToEth/watcherArbToEth.ts`, the function `findLatestL2BatchAndBlock` does not require internal validation of parameters because the upper layer handles the necessary validation.

Applied to files:

  • validator-cli/src/helpers/claimer.ts
📚 Learning: 2024-11-25T09:05:40.703Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: validator-cli/src/ArbToEth/watcherArbToGnosis.ts:454-457
Timestamp: 2024-11-25T09:05:40.703Z
Learning: In `validator-cli/src/ArbToEth/watcherArbToGnosis.ts`, when calculating `arbAverageBlockTime`, it's acceptable not to add error handling for division by zero when `blockLatestArb.timestamp` equals `blockoldArb.timestamp` because if it occurs, it indicates a major issue that requires investigation.

Applied to files:

  • validator-cli/src/helpers/claimer.ts
📚 Learning: 2024-11-19T10:25:55.588Z
Learnt from: fcanela
Repo: kleros/vea PR: 344
File: validator-cli/src/utils/arbMsgExecutor.ts:14-14
Timestamp: 2024-11-19T10:25:55.588Z
Learning: In the `validator-cli/src/utils/arbMsgExecutor.ts` file, checks for commonly required environment variables like `PRIVATE_KEY` should be performed earlier in the application lifecycle, before individual functions are executed.

Applied to files:

  • validator-cli/src/helpers/claimer.ts
📚 Learning: 2024-12-09T09:40:49.098Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/transactionHandler.ts:131-144
Timestamp: 2024-12-09T09:40:49.098Z
Learning: In the `TransactionHandler` class, it's acceptable to let methods like `withdrawClaimDeposit` fail without additional error handling.

Applied to files:

  • validator-cli/src/helpers/claimer.ts
📚 Learning: 2024-11-26T11:30:35.723Z
Learnt from: fcanela
Repo: kleros/vea PR: 344
File: relayer-cli/src/devnetRelayExample.ts:9-14
Timestamp: 2024-11-26T11:30:35.723Z
Learning: In `relayer-cli/src/devnetRelayExample.ts`, error handling is managed by the upper layer via `ShutdownManager`'s error signal handler, so adding a `try...catch` block in the main loop is unnecessary.

Applied to files:

  • validator-cli/src/helpers/claimer.ts
📚 Learning: 2025-03-31T09:03:06.510Z
Learnt from: mani99brar
Repo: kleros/vea PR: 396
File: validator-cli/src/utils/epochHandler.ts:67-74
Timestamp: 2025-03-31T09:03:06.510Z
Learning: In `validator-cli/src/utils/epochHandler.ts`, the `getBlockFromEpoch` function deliberately omits error handling for provider calls like `getBlock("latest")` and `getBlock(...)`. The developer prefers to let errors propagate up the call stack rather than handling them within this function.

Applied to files:

  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/utils/graphQueries.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2025-06-05T12:17:27.164Z
Learnt from: mani99brar
Repo: kleros/vea PR: 424
File: validator-cli/src/utils/transactionHandlers/baseTransactionHandler.ts:158-168
Timestamp: 2025-06-05T12:17:27.164Z
Learning: In `validator-cli/src/utils/transactionHandlers/baseTransactionHandler.ts`, when `ContractType.ROUTER` is used in `checkTransactionStatus`, the code is designed so that `veaRouterProvider` should always be defined. If it's undefined, the code should crash rather than being handled gracefully, following a fail-fast design pattern.

Applied to files:

  • validator-cli/src/helpers/claimer.ts
📚 Learning: 2024-12-10T04:59:11.283Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/ethers.ts:31-37
Timestamp: 2024-12-10T04:59:11.283Z
Learning: In the project, `chainId` validation is performed in outer layers, so individual functions like `getVeaInboxProvider` do not need to handle unsupported `chainId`s.

Applied to files:

  • validator-cli/src/helpers/claimer.ts
  • validator-cli/src/utils/graphQueries.ts
📚 Learning: 2024-11-26T08:37:47.591Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: validator-cli/src/ArbToEth/watcherArbToGnosis.ts:829-1112
Timestamp: 2024-11-26T08:37:47.591Z
Learning: Refactoring the `reconstructChallengeProgress` function in `validator-cli/src/ArbToEth/watcherArbToGnosis.ts` into smaller functions is considered unnecessary abstraction.

Applied to files:

  • validator-cli/src/helpers/claimer.test.ts
  • validator-cli/src/utils/claim.ts
📚 Learning: 2025-01-27T04:12:05.847Z
Learnt from: mani99brar
Repo: kleros/vea PR: 388
File: validator-cli/src/ArbToEth/validator.ts:16-17
Timestamp: 2025-01-27T04:12:05.847Z
Learning: In the validator-cli, `any` type is intentionally used for `veaInbox` and `veaOutbox` parameters to maintain chain agnosticism. This is because different chains have their own specific contract types (e.g., VeaInboxArbToEth, VeaOutboxArbToEth, VeaOutboxArbToGnosis) and using union types would make the code more complex and less maintainable.

Applied to files:

  • validator-cli/src/utils/claim.ts
📚 Learning: 2025-01-27T04:12:05.847Z
Learnt from: mani99brar
Repo: kleros/vea PR: 388
File: validator-cli/src/ArbToEth/validator.ts:16-17
Timestamp: 2025-01-27T04:12:05.847Z
Learning: In the validator-cli, `any` type is intentionally used for `veaInbox` and `veaOutbox` parameters to maintain chain agnosticism, as different chains have their own contract types.

Applied to files:

  • validator-cli/src/utils/claim.ts
📚 Learning: 2024-11-20T11:50:19.381Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: validator-cli/src/utils/arbMsgExecutor.ts:44-44
Timestamp: 2024-11-20T11:50:19.381Z
Learning: In `validator-cli/src/utils/arbMsgExecutor.ts`, when calling `childToParentMessage.execute()`, pass `childProvider` as the argument since `childToParentMessage` already contains the parent (Ethereum) RPC context internally.

Applied to files:

  • validator-cli/src/utils/claim.ts
🧬 Code graph analysis (2)
validator-cli/src/helpers/snapshot.test.ts (2)
validator-cli/src/consts/bridgeRoutes.ts (1)
  • Network (102-102)
validator-cli/src/helpers/snapshot.ts (1)
  • isSnapshotNeeded (61-110)
validator-cli/src/utils/graphQueries.ts (1)
validator-cli/src/utils/errors.ts (1)
  • NoMessageSavedError (85-85)
⏰ 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). (7)
  • GitHub Check: Redirect rules - veascan
  • GitHub Check: Header rules - veascan
  • GitHub Check: Pages changed - veascan
  • GitHub Check: Analyze (javascript)
  • GitHub Check: test
  • GitHub Check: dependency-review
  • GitHub Check: Mend Security Check
🔇 Additional comments (14)
validator-cli/src/helpers/claimer.ts (3)

21-21: LGTM: Interface extensions support router-based finality checks.

The optional veaRouterProvider and fetchBlocksAndCheckFinality parameters properly support the new arbToEth finality validation flow without breaking existing callers.

Also applies to: 27-27


77-90: LGTM: Proper parameter threading with sensible fallback.

The queryRpc = veaRouterProvider ?? veaOutboxProvider fallback ensures backward compatibility when the router provider isn't supplied, while supporting the new router-based claim flow.


148-165: LGTM: Properly handles new claims with finality validation.

The refactored logic correctly:

  1. Compares savedSnapshot against both outboxStateRoot and lastClaimedStateroot to detect new messages
  2. Validates finality before proceeding with claims
  3. Handles the first-ever claim scenario (when lastClaimedStateroot == ethers.ZeroHash) by allowing progression through the comparison logic

The finality check integration prevents claiming when finality issues are detected, improving system resilience.

validator-cli/src/helpers/claimer.test.ts (1)

196-197: LGTM: Mock properly supports new finality check flow.

The fetchBlocksAndCheckFinality mock returns [0, 0, false, false], where the last two boolean values represent finalityIssueFlagArb and finalityIssueFlagEth. The false values correctly simulate the no-finality-issues case, allowing the test to verify successful claim execution.

validator-cli/src/helpers/snapshot.test.ts (5)

4-4: LGTM: Test setup properly extended for new snapshot logic.

The additions correctly support the enhanced isSnapshotNeeded interface:

  • ethers import provides ZeroHash constant
  • network and epochPeriod enable snapshot timing logic
  • fetchLastClaimedEpoch and fetchClaimForEpoch mocks support claim-based snapshot decisions
  • Extended veaOutbox mock with queryFilter and Claimed filter matches production contract interface

Also applies to: 7-7, 11-11, 14-15, 28-36


46-55: LGTM: Test parameters consistently updated across all cases.

All test cases now properly pass network, epochPeriod, fetchLastClaimedEpoch, and fetchClaimForEpoch to match the expanded isSnapshotNeeded signature. The consistent threading maintains comprehensive test coverage.

Also applies to: 68-78, 91-101, 114-124, 136-146, 160-170


134-134: Fixed: Mock return type now matches production interface.

The fetchLastSavedMessage mock now correctly returns an object with { id, stateRoot } properties instead of a plain string. This addresses the previous review concern and properly exercises the fallback logic in snapshot.ts (lines 86-93).


159-159: LGTM: Proper use of ethers constant.

Using ethers.ZeroHash instead of a hardcoded zero address improves readability and consistency with ethers v6 conventions.


56-59: LGTM: Proper async test pattern.

All test expectations correctly use await expect(...).resolves.toEqual(...) to properly handle the async isSnapshotNeeded function, ensuring promises are resolved before assertions.

Also applies to: 79-82, 102-105, 125-128, 147-150, 171-174

validator-cli/src/utils/claim.ts (3)

235-254: Good fix: verifyClaimHash no longer mutates the claim object.

The implementation now creates copies with different honest states instead of mutating the input. This addresses the concern from a previous review and makes the function more predictable.


79-126: Robust fallback logic with proper error handling.

The implementation handles multiple failure scenarios:

  • Primary on-chain fetch with graph fallback
  • Hash validation with secondary graph fallback if needed
  • Emitter events for observability (NO_CLAIM_FETCHED, CLAIM_MISMATCH)
  • isFallbackUsed flag prevents redundant graph queries

68-69: Use consistent block range parameters across all queryFilter calls.

The Challenged and VerificationStarted filters don't specify fromBlock or toBlock, while the Claimed filter does. Since these parameters are passed to getClaim, they should be applied consistently to all three queries for optimization and maintainability.

validator-cli/src/utils/graphQueries.ts (2)

259-282: Correct nullable return type and proper error handling.

The function now correctly returns null when no messages exist and throws NoMessageSavedError on actual failures. This addresses the type mismatch noted in a previous review.


55-61: Enhanced query includes verification and challenge data.

The GraphQL query now fetches nested verification and challenge fields, properly aligning with the updated ClaimData interface and supporting the improved claim validation logic in claim.ts.

Copy link
Copy Markdown
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: 0

🧹 Nitpick comments (1)
validator-cli/README.md (1)

20-20: Clarify how to update the Dockerfile for different flags.

The instruction is vague about the mechanics. Users may not know whether this means editing the entrypoint, using docker-compose overrides, or passing arguments at runtime. Consider providing a brief example or explanation.

🔎 Suggested clarification
-Update Dockerfile for passing different flags
+Modify the Dockerfile or docker-compose.yml to pass different flags (e.g., `--path=challenger`) to the entrypoint command.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6232598 and 08d664f.

📒 Files selected for processing (2)
  • relayer-cli/README.md
  • validator-cli/README.md
✅ Files skipped from review due to trivial changes (1)
  • relayer-cli/README.md
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: mani99brar
Repo: kleros/vea PR: 430
File: contracts/src/interfaces/inboxes/IVeaInbox.sol:0-0
Timestamp: 2025-08-27T07:02:45.825Z
Learning: The sendMessage signature simplification in IVeaInbox.sol and related call site updates across relay-cli and test files were fixed in a separate PR by mani99brar.
Learnt from: mani99brar
Repo: kleros/vea PR: 395
File: relayer-cli/src/utils/relayerHelpers.ts:95-97
Timestamp: 2025-01-15T07:41:34.012Z
Learning: The shutdown manager improvements in relayer-cli/src/utils/relayerHelpers.ts, including proper exit code handling, will be addressed in a separate PR to keep the current changes focused.
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: relayer-cli/src/devnetRelayExample.ts:5-6
Timestamp: 2024-11-21T07:44:06.942Z
Learning: The files `contracts/deploy/02-inbox/02-arb-sepolia-to-chiado-inbox.ts` and `contracts/deploy/02-inbox/02-arb-sepolia-to-sepolia-inbox.ts` are not part of the current scope in this PR.
Learnt from: mani99brar
Repo: kleros/vea PR: 434
File: relayer-cli/src/utils/hashiHelpers/hashiTypes.ts:1-16
Timestamp: 2025-10-27T13:45:22.819Z
Learning: In the Vea relayer-cli project, HashiMessage interface and related types use simple number and string types. Type conversion and normalization (e.g., number to bigint, string to bytes) is handled in encoding utilities like encodeMessageForAbi before on-chain calls, rather than widening the interface types themselves.
📚 Learning: 2024-12-09T09:03:31.474Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/graphQueries.ts:12-34
Timestamp: 2024-12-09T09:03:31.474Z
Learning: In the `bridger-cli` project, environment variable validation is handled during dockerization, so explicit validation within individual functions is not necessary.

Applied to files:

  • validator-cli/README.md
📚 Learning: 2024-12-10T11:50:03.499Z
Learnt from: fcanela
Repo: kleros/vea PR: 377
File: relayer-cli/src/utils/lock.ts:53-54
Timestamp: 2024-12-10T11:50:03.499Z
Learning: The `relayer-cli` project plans to transition away from file-based lock mechanisms (e.g., in `src/utils/lock.ts`) due to deployment in Docker containers within a cloud environment, where file-based implementations are not ideal. They intend to adopt a solution suitable for both local and cloud deployments.

Applied to files:

  • validator-cli/README.md
📚 Learning: 2024-11-27T05:06:11.662Z
Learnt from: mani99brar
Repo: kleros/vea PR: 344
File: relayer-cli/src/utils/relayerHelpers.ts:19-30
Timestamp: 2024-11-27T05:06:11.662Z
Learning: In `relayer-cli/src/utils/relayerHelpers.ts`, validation for environment variables like `STATE_DIR` will be added later during dockerization efforts.

Applied to files:

  • validator-cli/README.md
📚 Learning: 2024-12-09T10:53:55.715Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/bridger.ts:25-109
Timestamp: 2024-12-09T10:53:55.715Z
Learning: In the `bridger-cli/src/bridger.ts` file, refactoring the main loop and adding additional error handling are not needed unless deemed necessary by the developer.

Applied to files:

  • validator-cli/README.md
📚 Learning: 2025-01-08T08:42:43.152Z
Learnt from: mani99brar
Repo: kleros/vea PR: 388
File: validator-cli/src/watcher.ts:38-71
Timestamp: 2025-01-08T08:42:43.152Z
Learning: In the validator-cli watcher.ts, errors are intentionally left uncaught to allow the bot to crash, with cleanup and restart mechanism planned to be added after consideration.

Applied to files:

  • validator-cli/README.md
📚 Learning: 2024-12-02T10:08:22.848Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: validator-cli/src/ArbToEth/watcherArbToGnosis.ts:1128-1131
Timestamp: 2024-12-02T10:08:22.848Z
Learning: In `validator-cli/src/ArbToEth/watcherArbToGnosis.ts`, adding graceful shutdown handling is unnecessary because the bot only has TCP connections to be closed, and both client and server are already resilient regarding TCP connections.

Applied to files:

  • validator-cli/README.md
⏰ 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). (6)
  • GitHub Check: Redirect rules - veascan
  • GitHub Check: Header rules - veascan
  • GitHub Check: Pages changed - veascan
  • GitHub Check: dependency-review
  • GitHub Check: test
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (3)
validator-cli/README.md (3)

7-11: LGTM!

Docker command substitution is clear and aligns with the project's shift to Docker-based deployment. The build and run commands are straightforward and correct.


13-16: LGTM!

The workflow descriptions accurately capture the two core functions introduced in this PR: snapshot saving/submission (Bridger) and claim validation (Challenger). These align well with the new snapshot and claimer logic mentioned in the PR objectives.


26-30: LGTM!

The --path flag documentation is clear and provides good granular control. The three modes (challenger, bridger, both) are well-defined, and the default behavior is appropriately indicated.

@mani99brar mani99brar marked this pull request as ready for review January 13, 2026 08:12
@mani99brar mani99brar requested a review from jaybuidl as a code owner January 13, 2026 08:12
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
16 Security Hotspots
0.0% Coverage on New Code (required ≥ 80%)
10.5% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Copy link
Copy Markdown
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

🤖 Fix all issues with AI agents
In @relayer-cli/src/relayer.ts:
- Around line 100-103: The time calculation incorrectly divides currentTS twice;
update the logic in the function using currentTS, getEpochPeriod, and timeLeft
so you use currentTS (seconds) directly: compute remainder as (currentTS %
epochPeriod), set timeLeft = (epochPeriod - (currentTS % epochPeriod)) * 1000 +
100_000 (to keep the 100s buffer in ms), and keep returning Date.now() +
timeLeft; remove the extra Math.floor(currentTS / 1000) division to fix the
double-division bug.

In @relayer-cli/src/utils/hashi.ts:
- Around line 51-57: The code destructures bridgeConfig from fetchBridgeConfig
(getHashiBridgeConfig) without checking for undefined which can throw; update
the logic in the function containing the lines with bridgeConfig, yaruAddress,
yahoAddress, hashiAddress, and sourceRPC to first check if bridgeConfig is falsy
and if so emit BotEvents.HASHI_NOT_CONFIGURED with targetChainId and return
legacyBlockNumber (or blockNumber) to preserve retry state; only then
destructure the properties and keep the existing falsy-address check to emit the
event and return legacyBlockNumber instead of 0.

In @relayer-cli/src/utils/relayerHelpers.ts:
- Around line 76-86: The state file path is built via string concatenation which
can break if STATE_DIR lacks a trailing slash; instead use the existing stateDir
variable and path.join to construct chain_state_file (combine stateDir,
`${network}_${chainId}.json`) before calling fileSystem.writeFileSync; update
references in this block to use stateDir and the joined path so path handling is
consistent with the earlier use of path.join.
🧹 Nitpick comments (7)
relayer-cli/.env.dist (1)

10-10: Optional: Consider alphabetical ordering of environment variables.

Static analysis suggests alphabetizing keys for consistency:

  • SENDER_ADDRESSES_HASHI before SENDER_ADDRESSES_TESTNET (line 10)
  • RPC_ARBITRUM_SEPOLIA before RPC_CHIADO (line 14)
  • RPC_ARBITRUM_ONE before RPC_ARBITRUM_SEPOLIA (line 16)

However, the current semantic grouping (by network type or usage) may be intentional and easier to navigate. Feel free to keep the current structure if it better serves operational needs.

Also applies to: 14-14, 16-16

relayer-cli/src/utils/hashiHelpers/bridgeRoutes.ts (2)

1-9: Consider exporting the IHashiBridge interface.

The interface is only used internally, but consumers of getHashiBridgeConfig may benefit from having the type exported for proper typing of the returned configuration.

♻️ Suggested change
-interface IHashiBridge {
+export interface IHashiBridge {
   sourceChainId: number;
   targetChainId: number;
   sourceRPC: string;
   targetRPC: string;
   yahoAddress: string; // Hashi (Yaho) contract address
   yaruAddress: string; // Hashi (Yaru) contract address
   hashiAddress: string; // Hashi (Hashi) contract address
 }

22-30: Minor inconsistency: field order differs from other bridge configs.

In this config, targetRPC appears before sourceRPC, whereas in other configs sourceRPC comes first. Consider reordering for consistency.

♻️ Suggested reorder
   "421614-10200": {
     sourceChainId: 421614,
     targetChainId: 10200,
-    targetRPC: process.env.RPC_CHIADO!,
     sourceRPC: process.env.RPC_ARBITRUM_SEPOLIA!,
+    targetRPC: process.env.RPC_CHIADO!,
     yahoAddress: "0xDbdF80c87f414fac8342e04D870764197bD3bAC7", // Hashi (Yaho) contract address on Arbitrum Sepolia
     yaruAddress: "0x639c26C9F45C634dD14C599cBAa27363D4665C53", // Hashi (Yaru) contract address on Chiado
     hashiAddress: "0x78E4ae687De18B3B71Ccd0e8a3A76Fed49a02A02", // Hashi (Hashi) contract address on Chiado
   },
relayer-cli/src/utils/relayerHelpers.ts (1)

137-147: Consider adding listener guard for 'exit' event as well.

Signal handlers (SIGINT, SIGTERM, SIGQUIT) check listenerCount before attaching, but the exit handler doesn't have the same guard. This could lead to multiple exit handlers being attached.

Suggested improvement
-  process.on("exit", async () => {
-    await handleExit();
-  });
+  if (process.listenerCount("exit") === 0) {
+    process.on("exit", async () => {
+      await handleExit();
+    });
+  }
relayer-cli/src/utils/hashi.ts (1)

244-256: Inconsistent case normalization in address comparison.

Line 246 uses toLowerCase() on one side and toLocaleLowerCase() on the other. While functionally equivalent for hex addresses, it's cleaner to use consistent methods.

Suggested fix
-      if (log.address.toLowerCase() == yahoAddress.toLocaleLowerCase()) {
+      if (log.address.toLowerCase() === yahoAddress.toLowerCase()) {
relayer-cli/src/utils/hashi.test.ts (1)

21-32: Remove unused MockJsonRpcProvider class.

MockJsonRpcProvider is defined at lines 21-32 but is not used anywhere in the test. Remove the class definition to keep the test file clean.

validator-cli/src/watcher.ts (1)

44-51: Heartbeat calls may block the watch loop if the heartbeat service is slow or unavailable.

The sendHeartbeat calls are awaited inside the main loop. If the heartbeat endpoint is unresponsive or slow, this could delay epoch processing. Consider:

  1. Adding a timeout to heartbeat requests
  2. Using fire-and-forget (non-blocking) for "running" heartbeats
  3. Wrapping in try-catch to prevent heartbeat failures from crashing the watcher

Based on learnings, errors are intentionally left uncaught to allow crash & restart, but heartbeat failures shouldn't be treated as critical errors that warrant a crash.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 08d664f and d400265.

📒 Files selected for processing (16)
  • relayer-cli/.env.dist
  • relayer-cli/README.md
  • relayer-cli/src/relayer.ts
  • relayer-cli/src/utils/botEvents.ts
  • relayer-cli/src/utils/hashi.test.ts
  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/utils/hashiHelpers/bridgeRoutes.ts
  • relayer-cli/src/utils/hashiHelpers/hashiTypes.ts
  • relayer-cli/src/utils/logger.ts
  • relayer-cli/src/utils/relayerHelpers.test.ts
  • relayer-cli/src/utils/relayerHelpers.ts
  • relayer-cli/state/devnet_11155111.json
  • relayer-cli/state/testnet_10200.json
  • relayer-cli/state/testnet_11155111.json
  • relayer-cli/state/testnet_42161.json
  • validator-cli/src/watcher.ts
✅ Files skipped from review due to trivial changes (1)
  • relayer-cli/state/testnet_10200.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • relayer-cli/README.md
🧰 Additional context used
🧠 Learnings (61)
📓 Common learnings
Learnt from: mani99brar
Repo: kleros/vea PR: 430
File: contracts/src/interfaces/inboxes/IVeaInbox.sol:0-0
Timestamp: 2025-08-27T07:02:45.825Z
Learning: The sendMessage signature simplification in IVeaInbox.sol and related call site updates across relay-cli and test files were fixed in a separate PR by mani99brar.
Learnt from: mani99brar
Repo: kleros/vea PR: 395
File: relayer-cli/src/utils/relayerHelpers.ts:95-97
Timestamp: 2025-01-15T07:41:34.012Z
Learning: The shutdown manager improvements in relayer-cli/src/utils/relayerHelpers.ts, including proper exit code handling, will be addressed in a separate PR to keep the current changes focused.
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: relayer-cli/src/devnetRelayExample.ts:5-6
Timestamp: 2024-11-21T07:44:06.942Z
Learning: The files `contracts/deploy/02-inbox/02-arb-sepolia-to-chiado-inbox.ts` and `contracts/deploy/02-inbox/02-arb-sepolia-to-sepolia-inbox.ts` are not part of the current scope in this PR.
Learnt from: fcanela
Repo: kleros/vea PR: 377
File: relayer-cli/src/utils/lock.ts:53-54
Timestamp: 2024-12-10T11:50:03.499Z
Learning: The `relayer-cli` project plans to transition away from file-based lock mechanisms (e.g., in `src/utils/lock.ts`) due to deployment in Docker containers within a cloud environment, where file-based implementations are not ideal. They intend to adopt a solution suitable for both local and cloud deployments.
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/bridger.ts:113-118
Timestamp: 2024-12-10T04:45:36.079Z
Learning: Graceful shutdown handling in `bridger-cli` will be addressed in future PRs.
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/bridger.ts:25-109
Timestamp: 2024-12-09T10:53:55.715Z
Learning: In the `bridger-cli/src/bridger.ts` file, refactoring the main loop and adding additional error handling are not needed unless deemed necessary by the developer.
Learnt from: mani99brar
Repo: kleros/vea PR: 434
File: relayer-cli/src/utils/hashi.ts:206-235
Timestamp: 2025-10-27T13:45:23.420Z
Learning: The Hashi executor in relayer-cli currently only supports routes from Arbitrum Sepolia (chain ID 421614), so the hardcoded SOURCE_CHAIN_ID constant in relayer-cli/src/utils/hashi.ts is acceptable for the current scope. This will be updated when support for other source chains is added.
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/transactionHandler.ts:13-13
Timestamp: 2024-12-09T09:40:28.400Z
Learning: In `bridger-cli/src/utils/transactionHandler.ts`, the `veaOutbox` implementations differ for each chain, but a common interface should be defined for type checks to enhance type safety.
📚 Learning: 2024-12-16T09:24:33.478Z
Learnt from: mani99brar
Repo: kleros/vea PR: 383
File: contracts/test/integration/ArbToGnosis.ts:520-520
Timestamp: 2024-12-16T09:24:33.478Z
Learning: In the TypeScript integration tests (`contracts/test/integration/ArbToGnosis.ts`), adding null checks after retrieving blocks using `await ethers.provider.getBlock` is unnecessary because the test will fail if the block is not found.

Applied to files:

  • relayer-cli/src/utils/relayerHelpers.test.ts
  • relayer-cli/src/utils/hashi.test.ts
📚 Learning: 2024-12-09T10:18:00.133Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/ethers.ts:20-82
Timestamp: 2024-12-09T10:18:00.133Z
Learning: In `bridger-cli/src/utils/ethers.ts`, prefer to keep the existing `chainId` checks without refactoring to avoid overcomplicating the code with additional conditional logic.

Applied to files:

  • relayer-cli/src/utils/relayerHelpers.test.ts
  • relayer-cli/src/utils/hashiHelpers/bridgeRoutes.ts
  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/utils/relayerHelpers.ts
📚 Learning: 2024-11-27T05:06:11.662Z
Learnt from: mani99brar
Repo: kleros/vea PR: 344
File: relayer-cli/src/utils/relayerHelpers.ts:19-30
Timestamp: 2024-11-27T05:06:11.662Z
Learning: In `relayer-cli/src/utils/relayerHelpers.ts`, validation for environment variables like `STATE_DIR` will be added later during dockerization efforts.

Applied to files:

  • relayer-cli/src/utils/relayerHelpers.test.ts
  • relayer-cli/state/devnet_11155111.json
  • relayer-cli/.env.dist
  • relayer-cli/state/testnet_42161.json
  • relayer-cli/src/utils/relayerHelpers.ts
  • relayer-cli/src/utils/hashiHelpers/hashiTypes.ts
📚 Learning: 2024-12-06T13:46:45.497Z
Learnt from: fcanela
Repo: kleros/vea PR: 377
File: relayer-cli/src/utils/lock.test.ts:22-50
Timestamp: 2024-12-06T13:46:45.497Z
Learning: In the `relayer-cli` project, when reviewing tests, avoid suggesting tests that check the functionality of Node.js native libraries like `fs`, as it's part of the native library's responsibilities.

Applied to files:

  • relayer-cli/src/utils/relayerHelpers.test.ts
  • relayer-cli/src/utils/hashi.test.ts
📚 Learning: 2025-01-15T07:41:34.012Z
Learnt from: mani99brar
Repo: kleros/vea PR: 395
File: relayer-cli/src/utils/relayerHelpers.ts:95-97
Timestamp: 2025-01-15T07:41:34.012Z
Learning: The shutdown manager improvements in relayer-cli/src/utils/relayerHelpers.ts, including proper exit code handling, will be addressed in a separate PR to keep the current changes focused.

Applied to files:

  • relayer-cli/src/utils/relayerHelpers.test.ts
  • validator-cli/src/watcher.ts
  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/utils/hashi.test.ts
  • relayer-cli/src/utils/relayerHelpers.ts
  • relayer-cli/src/relayer.ts
📚 Learning: 2024-11-27T04:18:05.872Z
Learnt from: mani99brar
Repo: kleros/vea PR: 344
File: validator-cli/src/ArbToEth/watcherArbToEth.ts:732-745
Timestamp: 2024-11-27T04:18:05.872Z
Learning: In `validator-cli/src/ArbToEth/watcherArbToEth.ts`, input validation inside the `hashClaim` function is unnecessary because the upper layer ensures valid input before calling it.

Applied to files:

  • relayer-cli/src/utils/relayerHelpers.test.ts
  • validator-cli/src/watcher.ts
📚 Learning: 2024-12-06T13:44:13.639Z
Learnt from: fcanela
Repo: kleros/vea PR: 377
File: relayer-cli/src/utils/relayerHelpers.ts:6-6
Timestamp: 2024-12-06T13:44:13.639Z
Learning: In `relayer-cli/src/utils/relayerHelpers.ts`, in the `initialize` function, avoid wrapping `claimLock` in a try...catch block because the `LockfileExistsError` already provides a suitable error message, and adding a try...catch block introduces unnecessary complexity.

Applied to files:

  • relayer-cli/src/utils/relayerHelpers.test.ts
  • relayer-cli/src/utils/relayerHelpers.ts
📚 Learning: 2025-06-05T12:17:21.782Z
Learnt from: mani99brar
Repo: kleros/vea PR: 424
File: validator-cli/src/helpers/claimer.ts:72-76
Timestamp: 2025-06-05T12:17:21.782Z
Learning: In validator-cli/src/helpers/claimer.ts, the outboxStateRoot captured at the beginning of the checkAndClaim function won't change for the epoch being claimed, so there's no race condition concern when reusing it in makeClaim/makeClaimDevnet functions.

Applied to files:

  • relayer-cli/src/utils/relayerHelpers.test.ts
  • validator-cli/src/watcher.ts
  • relayer-cli/src/utils/relayerHelpers.ts
📚 Learning: 2024-11-26T11:30:36.180Z
Learnt from: fcanela
Repo: kleros/vea PR: 344
File: relayer-cli/src/utils/relay.ts:28-40
Timestamp: 2024-11-26T11:30:36.180Z
Learning: In `relayer-cli/src/utils/relay.ts`, avoid suggesting adding try/catch blocks that only log errors and rethrow in the `relay` function.

Applied to files:

  • relayer-cli/src/utils/logger.ts
  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/relayer.ts
📚 Learning: 2024-12-10T11:50:03.499Z
Learnt from: fcanela
Repo: kleros/vea PR: 377
File: relayer-cli/src/utils/lock.ts:53-54
Timestamp: 2024-12-10T11:50:03.499Z
Learning: The `relayer-cli` project plans to transition away from file-based lock mechanisms (e.g., in `src/utils/lock.ts`) due to deployment in Docker containers within a cloud environment, where file-based implementations are not ideal. They intend to adopt a solution suitable for both local and cloud deployments.

Applied to files:

  • relayer-cli/src/utils/logger.ts
  • relayer-cli/src/utils/relayerHelpers.ts
  • relayer-cli/src/relayer.ts
📚 Learning: 2024-11-27T05:00:29.377Z
Learnt from: mani99brar
Repo: kleros/vea PR: 344
File: relayer-cli/src/utils/relay.ts:78-78
Timestamp: 2024-11-27T05:00:29.377Z
Learning: In the `relayer-cli` project, the file `src/devnetRelayer.ts` is intended as an example, and suggestions to modify it can be disregarded unless specifically requested.

Applied to files:

  • relayer-cli/state/devnet_11155111.json
  • relayer-cli/.env.dist
  • relayer-cli/state/testnet_42161.json
  • relayer-cli/src/utils/relayerHelpers.ts
  • relayer-cli/src/relayer.ts
📚 Learning: 2024-11-20T11:50:31.944Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: validator-cli/.env.dist:3-4
Timestamp: 2024-11-20T11:50:31.944Z
Learning: In 'validator-cli/.env.dist', the `RPC_GNOSIS` variable may be intentionally set to `https://rpc.chiadochain.net` as an example.

Applied to files:

  • relayer-cli/.env.dist
📚 Learning: 2024-12-09T09:48:37.012Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/bridger.ts:1-8
Timestamp: 2024-12-09T09:48:37.012Z
Learning: The `bridger-cli` directory contains a `.env.dist` file with environment variables, which will be updated with proper documentation.

Applied to files:

  • relayer-cli/.env.dist
📚 Learning: 2025-07-07T12:29:34.770Z
Learnt from: mani99brar
Repo: kleros/vea PR: 427
File: relayer-cli/.env.dist:24-24
Timestamp: 2025-07-07T12:29:34.770Z
Learning: In relayer-cli/.env.dist, the user (mani99brar) intentionally keeps quotes around environment variable values like `STATE_DIR="/home/user/vea/relayer-cli/state/"` as this works as intended for their use case.

Applied to files:

  • relayer-cli/.env.dist
📚 Learning: 2025-10-27T13:45:23.420Z
Learnt from: mani99brar
Repo: kleros/vea PR: 434
File: relayer-cli/src/utils/hashi.ts:206-235
Timestamp: 2025-10-27T13:45:23.420Z
Learning: The Hashi executor in relayer-cli currently only supports routes from Arbitrum Sepolia (chain ID 421614), so the hardcoded SOURCE_CHAIN_ID constant in relayer-cli/src/utils/hashi.ts is acceptable for the current scope. This will be updated when support for other source chains is added.

Applied to files:

  • relayer-cli/.env.dist
  • relayer-cli/src/utils/hashiHelpers/bridgeRoutes.ts
  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/utils/hashi.test.ts
  • relayer-cli/src/utils/relayerHelpers.ts
  • relayer-cli/src/relayer.ts
📚 Learning: 2024-11-26T11:30:36.180Z
Learnt from: fcanela
Repo: kleros/vea PR: 344
File: relayer-cli/src/utils/relay.ts:28-40
Timestamp: 2024-11-26T11:30:36.180Z
Learning: In `relay.ts`, environment variable validation is covered in earlier stages, so it's unnecessary to suggest adding it within the `relay` function.

Applied to files:

  • relayer-cli/.env.dist
📚 Learning: 2025-03-31T09:03:05.108Z
Learnt from: mani99brar
Repo: kleros/vea PR: 396
File: validator-cli/.env.dist:15-15
Timestamp: 2025-03-31T09:03:05.108Z
Learning: User (mani99brar) has decided to simplify the approach by using a single RPC variable per chain instead of maintaining separate variables for devnet and testnet/mainnet environments, even when they point to the same URL.

Applied to files:

  • relayer-cli/.env.dist
📚 Learning: 2025-08-27T07:02:45.825Z
Learnt from: mani99brar
Repo: kleros/vea PR: 430
File: contracts/src/interfaces/inboxes/IVeaInbox.sol:0-0
Timestamp: 2025-08-27T07:02:45.825Z
Learning: The sendMessage signature simplification in IVeaInbox.sol and related call site updates across relay-cli and test files were fixed in a separate PR by mani99brar.

Applied to files:

  • relayer-cli/.env.dist
  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/utils/hashi.test.ts
📚 Learning: 2024-11-19T10:25:55.588Z
Learnt from: fcanela
Repo: kleros/vea PR: 344
File: validator-cli/src/utils/arbMsgExecutor.ts:14-14
Timestamp: 2024-11-19T10:25:55.588Z
Learning: In the `validator-cli/src/utils/arbMsgExecutor.ts` file, checks for commonly required environment variables like `PRIVATE_KEY` should be performed earlier in the application lifecycle, before individual functions are executed.

Applied to files:

  • relayer-cli/.env.dist
📚 Learning: 2026-01-13T07:50:23.761Z
Learnt from: mani99brar
Repo: kleros/vea PR: 437
File: contracts/deployments/arbitrumSepolia/VeaInboxArbToGnosisDevnet.json:288-291
Timestamp: 2026-01-13T07:50:23.761Z
Learning: In the devnet deployment of VeaInboxArbToGnosisDevnet (contracts/deployments/arbitrumSepolia/VeaInboxArbToGnosisDevnet.json), the routerArbToGnosis constructor argument is intentionally set to 0x879A9F4476D4445A1deCf40175a700C4c829824D (the VeaOutboxArbToGnosis address on Gnosis Chiado) rather than the RouterArbToGnosisDevnet address on Ethereum Sepolia. This is correct for devnet because there is no unhappy path intended in devnet where the Router will be used.

Applied to files:

  • relayer-cli/.env.dist
📚 Learning: 2025-01-06T06:17:34.199Z
Learnt from: mani99brar
Repo: kleros/vea PR: 388
File: validator-cli/.env.dist:9-11
Timestamp: 2025-01-06T06:17:34.199Z
Learning: User (mani99brar) intentionally keeps the same RPC URLs under different environment variables to distinguish between devnet and testnet/mainnet usage, and this is by design rather than an oversight.

Applied to files:

  • relayer-cli/.env.dist
📚 Learning: 2024-12-10T08:00:35.645Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/consts/bridgeRoutes.ts:28-30
Timestamp: 2024-12-10T08:00:35.645Z
Learning: In `bridger-cli/src/consts/bridgeRoutes.ts`, additional validation in the `getBridgeConfig` function is unnecessary because error handling and validation are managed by upper layers in the application.

Applied to files:

  • relayer-cli/src/utils/hashiHelpers/bridgeRoutes.ts
  • validator-cli/src/watcher.ts
📚 Learning: 2024-12-09T09:40:28.400Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/transactionHandler.ts:13-13
Timestamp: 2024-12-09T09:40:28.400Z
Learning: In `bridger-cli/src/utils/transactionHandler.ts`, the `veaOutbox` implementations differ for each chain, but a common interface should be defined for type checks to enhance type safety.

Applied to files:

  • relayer-cli/src/utils/hashiHelpers/bridgeRoutes.ts
  • validator-cli/src/watcher.ts
  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/utils/hashi.test.ts
  • relayer-cli/src/utils/relayerHelpers.ts
  • relayer-cli/src/utils/hashiHelpers/hashiTypes.ts
📚 Learning: 2024-12-09T09:04:04.819Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/graphQueries.ts:36-58
Timestamp: 2024-12-09T09:04:04.819Z
Learning: In `bridger-cli/src/utils/graphQueries.ts` (TypeScript), the `getVerificationStatus` function is no longer needed and has been removed.

Applied to files:

  • relayer-cli/src/utils/hashiHelpers/bridgeRoutes.ts
  • relayer-cli/src/utils/hashi.ts
📚 Learning: 2024-12-09T10:53:55.715Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/bridger.ts:25-109
Timestamp: 2024-12-09T10:53:55.715Z
Learning: In the `bridger-cli/src/bridger.ts` file, refactoring the main loop and adding additional error handling are not needed unless deemed necessary by the developer.

Applied to files:

  • relayer-cli/src/utils/hashiHelpers/bridgeRoutes.ts
  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/relayer.ts
📚 Learning: 2024-12-09T10:54:57.068Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/claim.ts:56-69
Timestamp: 2024-12-09T10:54:57.068Z
Learning: In the TypeScript file 'bridger-cli/src/utils/claim.ts', the upper layers handle input validation for the 'hashClaim' function. Therefore, explicit input validation within 'hashClaim' is not necessary.

Applied to files:

  • relayer-cli/src/utils/hashiHelpers/bridgeRoutes.ts
  • validator-cli/src/watcher.ts
  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/utils/hashi.test.ts
  • relayer-cli/src/utils/relayerHelpers.ts
📚 Learning: 2025-01-06T06:24:17.556Z
Learnt from: mani99brar
Repo: kleros/vea PR: 388
File: validator-cli/src/utils/ethers.ts:32-38
Timestamp: 2025-01-06T06:24:17.556Z
Learning: We only support chain IDs 11155111 and 10200 for bridging in the current bot. For future bridges, chain IDs will be added as needed, and environment validation (fallback handling) will be addressed in a future PR.

Applied to files:

  • relayer-cli/src/utils/hashiHelpers/bridgeRoutes.ts
📚 Learning: 2024-12-02T10:08:22.848Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: validator-cli/src/ArbToEth/watcherArbToGnosis.ts:1128-1131
Timestamp: 2024-12-02T10:08:22.848Z
Learning: In `validator-cli/src/ArbToEth/watcherArbToGnosis.ts`, adding graceful shutdown handling is unnecessary because the bot only has TCP connections to be closed, and both client and server are already resilient regarding TCP connections.

Applied to files:

  • validator-cli/src/watcher.ts
📚 Learning: 2025-01-08T08:42:43.152Z
Learnt from: mani99brar
Repo: kleros/vea PR: 388
File: validator-cli/src/watcher.ts:38-71
Timestamp: 2025-01-08T08:42:43.152Z
Learning: In the validator-cli watcher.ts, errors are intentionally left uncaught to allow the bot to crash, with cleanup and restart mechanism planned to be added after consideration.

Applied to files:

  • validator-cli/src/watcher.ts
📚 Learning: 2024-12-02T10:08:28.998Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: validator-cli/src/ArbToEth/watcherArbToGnosis.ts:625-648
Timestamp: 2024-12-02T10:08:28.998Z
Learning: Avoid adding logging within loops in `validator-cli/src/ArbToEth/watcherArbToGnosis.ts` that could lead to excessive log output.

Applied to files:

  • validator-cli/src/watcher.ts
📚 Learning: 2024-12-02T10:16:56.825Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: validator-cli/src/ArbToEth/watcherArbToGnosis.ts:829-840
Timestamp: 2024-12-02T10:16:56.825Z
Learning: In the `validator-cli/src/ArbToEth/watcherArbToGnosis.ts` file, avoid adding redundant error handling in functions like `reconstructChallengeProgress` when error handling is already adequately managed.

Applied to files:

  • validator-cli/src/watcher.ts
  • relayer-cli/src/utils/hashi.ts
📚 Learning: 2024-11-27T05:13:07.353Z
Learnt from: mani99brar
Repo: kleros/vea PR: 344
File: validator-cli/src/ArbToEth/watcherArbToEth.ts:709-730
Timestamp: 2024-11-27T05:13:07.353Z
Learning: In `validator-cli/src/ArbToEth/watcherArbToEth.ts`, the function `findLatestL2BatchAndBlock` does not require internal validation of parameters because the upper layer handles the necessary validation.

Applied to files:

  • validator-cli/src/watcher.ts
📚 Learning: 2024-12-09T10:54:09.943Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/claim.ts:42-51
Timestamp: 2024-12-09T10:54:09.943Z
Learning: In the `bridger-cli/src/utils/claim.ts` file, within the `fetchClaim` function, explicit error handling for provider calls and event queries is not required; errors should be allowed to propagate naturally.

Applied to files:

  • validator-cli/src/watcher.ts
  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/utils/relayerHelpers.ts
📚 Learning: 2024-12-09T09:42:34.067Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/transactionHandler.ts:64-77
Timestamp: 2024-12-09T09:42:34.067Z
Learning: In the `TransactionHandler` class (`bridger-cli/src/utils/transactionHandler.ts`), it's acceptable to let methods like `makeClaim` fail without additional error handling.

Applied to files:

  • validator-cli/src/watcher.ts
  • relayer-cli/src/utils/hashi.ts
📚 Learning: 2024-11-26T08:37:47.591Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: validator-cli/src/ArbToEth/watcherArbToGnosis.ts:829-1112
Timestamp: 2024-11-26T08:37:47.591Z
Learning: Refactoring the `reconstructChallengeProgress` function in `validator-cli/src/ArbToEth/watcherArbToGnosis.ts` into smaller functions is considered unnecessary abstraction.

Applied to files:

  • validator-cli/src/watcher.ts
📚 Learning: 2024-12-10T04:59:10.224Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/claim.ts:23-32
Timestamp: 2024-12-10T04:59:10.224Z
Learning: In `bridger-cli/src/utils/claim.ts`, within the `fetchClaim` function, when `claimData` is undefined, avoid initializing it with default values, as this can result in incorrect claim values and make issues harder to identify.

Applied to files:

  • validator-cli/src/watcher.ts
  • relayer-cli/src/utils/relayerHelpers.ts
📚 Learning: 2024-12-09T09:42:51.590Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/transactionHandler.ts:79-101
Timestamp: 2024-12-09T09:42:51.590Z
Learning: In the `bridger-cli/src/utils/transactionHandler.ts` file, within the `TransactionHandler` class, it's acceptable to let methods like `startVerification` fail without additional error handling.

Applied to files:

  • validator-cli/src/watcher.ts
  • relayer-cli/src/utils/hashi.ts
📚 Learning: 2024-12-11T08:52:17.062Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/epochHandler.ts:13-13
Timestamp: 2024-12-11T08:52:17.062Z
Learning: In `bridger-cli/src/utils/epochHandler.ts`, the `veaOutbox` parameter is intentionally typed as `any` because the script is designed to be agnostic for multiple contracts.

Applied to files:

  • validator-cli/src/watcher.ts
  • relayer-cli/src/utils/hashi.ts
📚 Learning: 2025-03-31T09:03:06.510Z
Learnt from: mani99brar
Repo: kleros/vea PR: 396
File: validator-cli/src/utils/epochHandler.ts:67-74
Timestamp: 2025-03-31T09:03:06.510Z
Learning: In `validator-cli/src/utils/epochHandler.ts`, the `getBlockFromEpoch` function deliberately omits error handling for provider calls like `getBlock("latest")` and `getBlock(...)`. The developer prefers to let errors propagate up the call stack rather than handling them within this function.

Applied to files:

  • validator-cli/src/watcher.ts
📚 Learning: 2024-12-10T08:27:15.815Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/epochHandler.ts:63-68
Timestamp: 2024-12-10T08:27:15.815Z
Learning: In the file `bridger-cli/src/utils/epochHandler.ts`, the calculation within the `checkForNewEpoch` function is correct as implemented and has been tested.

Applied to files:

  • validator-cli/src/watcher.ts
📚 Learning: 2024-12-09T09:03:31.474Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/graphQueries.ts:12-34
Timestamp: 2024-12-09T09:03:31.474Z
Learning: In `bridger-cli/src/utils/graphQueries.ts`, within the `getClaimForEpoch` function, returning `result['claims'][0]` is sufficient because it will be `undefined` if `result['claims']` is an empty array, making additional checks unnecessary.

Applied to files:

  • validator-cli/src/watcher.ts
📚 Learning: 2024-12-02T10:08:28.998Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: validator-cli/src/ArbToEth/watcherArbToGnosis.ts:625-648
Timestamp: 2024-12-02T10:08:28.998Z
Learning: In `validator-cli/src/ArbToEth/watcherArbToGnosis.ts`, the function `findLatestL2BatchAndBlock` already handles the case when `fromArbBlock > latestBlockNumber`, so additional error handling for this case is unnecessary.

Applied to files:

  • validator-cli/src/watcher.ts
  • relayer-cli/src/utils/hashi.ts
📚 Learning: 2024-12-11T08:52:23.697Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/epochHandler.ts:38-50
Timestamp: 2024-12-11T08:52:23.697Z
Learning: The `getBlockNumberFromEpoch` function in `bridger-cli/src/utils/epochHandler.ts` is currently unused and will be addressed in a future issue.

Applied to files:

  • validator-cli/src/watcher.ts
📚 Learning: 2026-01-13T07:42:15.599Z
Learnt from: mani99brar
Repo: kleros/vea PR: 437
File: relayer-cli/src/utils/hashi.ts:133-140
Timestamp: 2026-01-13T07:42:15.599Z
Learning: In the Hashi executor (`relayer-cli/src/utils/hashi.ts`), particularly in the `executeBatchOnHashi` function, transaction execution errors should be allowed to throw without additional error handling; errors should propagate to upper layers rather than being caught locally.

Applied to files:

  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/utils/hashi.test.ts
  • relayer-cli/src/utils/hashiHelpers/hashiTypes.ts
📚 Learning: 2025-10-27T13:45:22.819Z
Learnt from: mani99brar
Repo: kleros/vea PR: 434
File: relayer-cli/src/utils/hashiHelpers/hashiTypes.ts:1-16
Timestamp: 2025-10-27T13:45:22.819Z
Learning: In the Vea relayer-cli project, HashiMessage interface and related types use simple number and string types. Type conversion and normalization (e.g., number to bigint, string to bytes) is handled in encoding utilities like encodeMessageForAbi before on-chain calls, rather than widening the interface types themselves.

Applied to files:

  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/utils/hashi.test.ts
  • relayer-cli/src/utils/relayerHelpers.ts
  • relayer-cli/src/utils/hashiHelpers/hashiTypes.ts
📚 Learning: 2024-11-26T11:30:41.074Z
Learnt from: fcanela
Repo: kleros/vea PR: 344
File: relayer-cli/src/testnetRelayer.ts:14-22
Timestamp: 2024-11-26T11:30:41.074Z
Learning: In 'relayer-cli/src/testnetRelayer.ts', the error handling strategy is to allow errors to propagate and be handled by an upper layer, so adding try/catch statements in the main loop is not required.

Applied to files:

  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/utils/hashi.test.ts
  • relayer-cli/src/utils/relayerHelpers.ts
  • relayer-cli/src/relayer.ts
📚 Learning: 2024-11-26T11:30:35.723Z
Learnt from: fcanela
Repo: kleros/vea PR: 344
File: relayer-cli/src/devnetRelayExample.ts:9-14
Timestamp: 2024-11-26T11:30:35.723Z
Learning: In `relayer-cli/src/devnetRelayExample.ts`, error handling is managed by the upper layer via `ShutdownManager`'s error signal handler, so adding a `try...catch` block in the main loop is unnecessary.

Applied to files:

  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/utils/relayerHelpers.ts
  • relayer-cli/src/relayer.ts
📚 Learning: 2024-11-26T11:30:37.021Z
Learnt from: fcanela
Repo: kleros/vea PR: 344
File: relayer-cli/src/devnetRelayExample.ts:25-25
Timestamp: 2024-11-26T11:30:37.021Z
Learning: In the `relayer-cli/src/devnetRelayExample.ts` file and similar contexts within the project, explicit handling of unhandled promise rejections when starting the application is not necessary. The team prefers relying on Node.js's default behavior to naturally raise and log errors in such cases, avoiding additional fallback handlers.

Applied to files:

  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/utils/relayerHelpers.ts
  • relayer-cli/src/relayer.ts
📚 Learning: 2024-11-27T05:02:48.754Z
Learnt from: mani99brar
Repo: kleros/vea PR: 344
File: relayer-cli/src/utils/relay.ts:42-73
Timestamp: 2024-11-27T05:02:48.754Z
Learning: In the `relayBatch` function of `relayer-cli/src/utils/relay.ts`, the current code cannot go into an infinite loop according to the user.

Applied to files:

  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/relayer.ts
📚 Learning: 2024-12-09T09:40:49.098Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/transactionHandler.ts:131-144
Timestamp: 2024-12-09T09:40:49.098Z
Learning: In the `TransactionHandler` class, it's acceptable to let methods like `withdrawClaimDeposit` fail without additional error handling.

Applied to files:

  • relayer-cli/src/utils/hashi.ts
📚 Learning: 2024-11-26T11:30:45.728Z
Learnt from: fcanela
Repo: kleros/vea PR: 344
File: relayer-cli/src/testnetRelayer.ts:25-28
Timestamp: 2024-11-26T11:30:45.728Z
Learning: In `relayer-cli/src/testnetRelayer.ts`, error handling for the main execution block is handled within the `ShutdownManager`, and the responsibility is encapsulated there.

Applied to files:

  • relayer-cli/src/utils/hashi.ts
  • relayer-cli/src/utils/hashi.test.ts
  • relayer-cli/src/utils/relayerHelpers.ts
  • relayer-cli/src/relayer.ts
📚 Learning: 2024-11-19T10:59:44.618Z
Learnt from: fcanela
Repo: kleros/vea PR: 344
File: validator-cli/src/ArbToEth/watcherArbToEth.ts:411-414
Timestamp: 2024-11-19T10:59:44.618Z
Learning: In the TypeScript codebase, particularly in `validator-cli/src/ArbToEth/watcherArbToEth.ts`, when there is no error fallback operation, errors should not be caught; they should be allowed to bubble up to enable proper error propagation and handling at higher levels.

Applied to files:

  • relayer-cli/src/utils/hashi.ts
📚 Learning: 2024-11-20T11:50:19.381Z
Learnt from: madhurMongia
Repo: kleros/vea PR: 359
File: validator-cli/src/utils/arbMsgExecutor.ts:44-44
Timestamp: 2024-11-20T11:50:19.381Z
Learning: In `validator-cli/src/utils/arbMsgExecutor.ts`, when calling `childToParentMessage.execute()`, pass `childProvider` as the argument since `childToParentMessage` already contains the parent (Ethereum) RPC context internally.

Applied to files:

  • relayer-cli/src/utils/hashi.ts
📚 Learning: 2024-12-16T09:22:57.434Z
Learnt from: mani99brar
Repo: kleros/vea PR: 383
File: contracts/test/integration/ArbToGnosis.ts:114-114
Timestamp: 2024-12-16T09:22:57.434Z
Learning: In the local Hardhat deployment for testing, `VeaInboxArbToGnosisMock` is deployed with the identifier name `VeaInboxArbToGnosis`, so it's appropriate to retrieve it using `getContract("VeaInboxArbToGnosis")` and cast it to `VeaInboxArbToGnosisMock` in `ArbToGnosis.ts`.

Applied to files:

  • relayer-cli/src/utils/hashi.ts
📚 Learning: 2024-11-21T05:40:34.912Z
Learnt from: mani99brar
Repo: kleros/vea PR: 344
File: validator-cli/src/utils/arbMsgExecutor.ts:52-85
Timestamp: 2024-11-21T05:40:34.912Z
Learning: In the `getMessageStatus` function, returning `undefined` for failed status fetches is acceptable because failures may be due to temporary finality issues.

Applied to files:

  • relayer-cli/src/utils/hashi.ts
📚 Learning: 2024-12-10T04:59:11.283Z
Learnt from: mani99brar
Repo: kleros/vea PR: 370
File: bridger-cli/src/utils/ethers.ts:31-37
Timestamp: 2024-12-10T04:59:11.283Z
Learning: In the project, `chainId` validation is performed in outer layers, so individual functions like `getVeaInboxProvider` do not need to handle unsupported `chainId`s.

Applied to files:

  • relayer-cli/src/utils/relayerHelpers.ts
📚 Learning: 2025-06-05T12:17:17.615Z
Learnt from: mani99brar
Repo: kleros/vea PR: 424
File: validator-cli/src/helpers/validator.ts:71-74
Timestamp: 2025-06-05T12:17:17.615Z
Learning: The challenger functionality in validator-cli/src/helpers/validator.ts is currently only supported for Network.TESTNET. There is no MAINNET support yet, which is why the network is hardcoded to Network.TESTNET when fetching and creating transaction handlers.

Applied to files:

  • relayer-cli/src/utils/relayerHelpers.ts
📚 Learning: 2025-03-31T12:59:49.609Z
Learnt from: mani99brar
Repo: kleros/vea PR: 415
File: relayer-cli/src/consts/bridgeRoutes.ts:56-73
Timestamp: 2025-03-31T12:59:49.609Z
Learning: Environment variable validation for the multi-network relayer will be handled during the dockerization process rather than with inline checks in the code.

Applied to files:

  • relayer-cli/src/utils/relayerHelpers.ts
📚 Learning: 2024-12-06T13:41:06.216Z
Learnt from: fcanela
Repo: kleros/vea PR: 375
File: relayer-cli/src/utils/shutdownManager.test.ts:12-12
Timestamp: 2024-12-06T13:41:06.216Z
Learning: In `shutdownManager.test.ts`, accessing private fields directly using bracket notation is acceptable when demonstrating examples of testing private fields in TypeScript tests.

Applied to files:

  • relayer-cli/src/relayer.ts
📚 Learning: 2025-01-15T07:41:33.847Z
Learnt from: mani99brar
Repo: kleros/vea PR: 395
File: relayer-cli/src/utils/relayerHelpers.ts:35-35
Timestamp: 2025-01-15T07:41:33.847Z
Learning: In the VEA relayer, uncaught errors are intentionally allowed to propagate up to be handled by the shutdownManager, which has handlers for uncaughtException and unhandledRejection events, rather than adding explicit try-catch blocks.

Applied to files:

  • relayer-cli/src/relayer.ts
🧬 Code graph analysis (4)
relayer-cli/src/utils/relayerHelpers.test.ts (2)
relayer-cli/src/utils/logger.ts (1)
  • initialize (40-42)
relayer-cli/src/utils/relayerHelpers.ts (1)
  • initialize (223-223)
relayer-cli/src/utils/hashi.ts (4)
relayer-cli/src/utils/hashiHelpers/bridgeRoutes.ts (1)
  • getHashiBridgeConfig (42-45)
relayer-cli/src/utils/hashiHelpers/hashiTypes.ts (4)
  • HashiMessageState (12-16)
  • HashiMessage (1-10)
  • DispatchedTxnData (25-25)
  • HashiMessageExecutionVars (18-23)
relayer-cli/src/utils/hashiHelpers/abi.ts (2)
  • YaruAbi (13-342)
  • messageDispatchedAbi (5-7)
relayer-cli/src/utils/hashiHelpers/hashiMsgUtils.ts (1)
  • getHashiMsgId (11-23)
relayer-cli/src/utils/relayerHelpers.ts (1)
relayer-cli/src/utils/lock.ts (1)
  • releaseLock (72-85)
relayer-cli/src/relayer.ts (1)
relayer-cli/src/utils/heartbeat.ts (1)
  • sendHeartbeat (6-47)
🪛 dotenv-linter (4.0.0)
relayer-cli/.env.dist

[warning] 10-10: [UnorderedKey] The SENDER_ADDRESSES_HASHI key should go before the SENDER_ADDRESSES_TESTNET key

(UnorderedKey)


[warning] 14-14: [UnorderedKey] The RPC_ARBITRUM_SEPOLIA key should go before the RPC_CHIADO key

(UnorderedKey)


[warning] 16-16: [UnorderedKey] The RPC_ARBITRUM_ONE key should go before the RPC_ARBITRUM_SEPOLIA key

(UnorderedKey)

⏰ 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). (7)
  • GitHub Check: Redirect rules - veascan
  • GitHub Check: Header rules - veascan
  • GitHub Check: Pages changed - veascan
  • GitHub Check: dependency-review
  • GitHub Check: test
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Mend Security Check
🔇 Additional comments (28)
relayer-cli/.env.dist (2)

14-16: Add example RPC endpoint URLs to .env.dist.

The three new RPC variables (RPC_ARBITRUM_SEPOLIA, RPC_STORY, RPC_ARBITRUM_ONE) are used in bridgeRoutes.ts with non-null assertions, and environment validation is deferred to the Docker layer. However, .env.dist should include example endpoint URLs (e.g., public RPC providers or testnet endpoints) to guide developers setting up locally, rather than leaving them empty.


18-22: VEAOUTBOX_CHAINS and HASHI_CHAINS are independent configuration filters; no inconsistency exists.

These environment variables control which routes an operator chooses to relay, not which chains are supported. VEAOUTBOX_CHAINS specifies target chains for VeaOutbox relay, while HASHI_CHAINS specifies source-target chain pairs for Hashi relay. An operator can legitimately exclude chain 10200 from VEAOUTBOX_CHAINS while keeping the 421614-10200 Hashi route active, as these are separate relay systems with separate operational requirements.

Likely an incorrect or invalid review comment.

relayer-cli/src/utils/relayerHelpers.test.ts (3)

23-37: LGTM!

Tests correctly updated to reflect the hashiNoncehashiBlockNumber rename. Mock data, destructuring, and assertions are all consistent with the new naming convention.


39-54: LGTM!

Existing state file test properly validates that hashiBlockNumber is returned from persisted state.


57-68: LGTM!

The updateStateFile test correctly validates the new JSON structure with hashiBlockNumber field.

relayer-cli/state/devnet_11155111.json (1)

1-5: LGTM!

State file correctly updated with the hashiBlockNumber field rename, consistent with the codebase-wide change from hashiNonce.

relayer-cli/state/testnet_11155111.json (1)

1-5: LGTM!

Testnet state file for Sepolia (chain 11155111) correctly includes the new hashiBlockNumber field.

relayer-cli/state/testnet_42161.json (1)

1-5: LGTM!

New testnet state file for Arbitrum One (chain 42161) follows the expected structure with hashiBlockNumber field. The nonce: 0 indicates a fresh state initialization.

relayer-cli/src/utils/hashiHelpers/bridgeRoutes.ts (2)

42-45: LGTM!

The lookup function is clean and straightforward. Returns undefined for unknown chain pairs, which is appropriate for the callers to handle.


16-17: Environment variables are documented in .env.dist and validation is handled during dockerization.

The non-null assertions on RPC_ARBITRUM_SEPOLIA, RPC_SEPOLIA, RPC_CHIADO, RPC_STORY, and RPC_ARBITRUM_ONE are intentional. These variables are clearly documented in the .env.dist file, and environment variable validation for the multi-network relayer is handled during the dockerization process rather than through inline checks.

relayer-cli/src/utils/logger.ts (2)

5-27: LGTM - well-structured logger configuration.

The pino logger setup with conditional Logtail vs pino-pretty transport is clean. The getLogger helper enables context-scoped child loggers.


44-98: LGTM - structured logging with appropriate log levels.

Event handlers are well-organized with proper log levels: info for state transitions, debug for operational details, and error for exceptions. The structured context objects (e.g., { chainId, network }, { nonce, tx }) enable effective log filtering and analysis.

relayer-cli/src/utils/relayerHelpers.ts (2)

198-211: LGTM - Hashi chain configuration parsing.

The parsing of HASHI_CHAINS environment variable with the sourceChainId-targetChainId format is straightforward. Based on learnings, environment variable validation will be addressed during dockerization.


160-165: LGTM - clean type extension.

The RelayerNetworkConfig type extension with optional sourceChainId is well-documented and maintains backward compatibility.

relayer-cli/src/utils/hashiHelpers/hashiTypes.ts (1)

1-31: LGTM - well-designed type system for Hashi workflow.

The new types (HashiMessageState, HashiMessageExecutionVars, DispatchedTxnData) provide a clean abstraction for the log-driven Hashi message workflow. The executable boolean and status enum in HashiMessageState enable clear state tracking. Based on learnings, type conversion to bigint/bytes is handled in encoding utilities before on-chain calls.

relayer-cli/src/relayer.ts (2)

34-54: LGTM - heartbeat integration and per-network scheduling.

The heartbeat telemetry integration and per-network execution timing via executeTimes array is well-structured. The scheduling logic correctly skips networks until their scheduled time.


78-89: LGTM - clean Hashi executor integration.

The Hashi path correctly checks for sourceChainId, runs the executor, updates state with hashiBlockNumber, and returns the next cycle time. The early return cleanly separates Hashi from non-Hashi flows.

relayer-cli/src/utils/hashi.test.ts (2)

98-125: LGTM - comprehensive toExecuteMessage test coverage.

The three test cases cover all execution states: executable (EXECUTABLE), non-executable (THRESHOLD_NOT_MET returning null), and already executed (EXECUTED with executable=false). Assertions correctly verify the HashiMessageState shape.


135-211: LGTM - thorough runHashiExecutor test coverage.

Tests cover key scenarios: empty message list, non-executable messages (already executed), and executable messages. The mock setup correctly simulates the Hashi workflow, and assertions verify both return values and function call arguments.

relayer-cli/src/utils/hashi.ts (3)

85-147: LGTM - batch execution with proper chunking.

The batch execution logic correctly processes messages in chunks of 20, filters for executable messages, normalizes data formats, and handles empty chunks. Based on learnings, transaction errors are allowed to propagate to upper layers.


162-209: LGTM - clean message status checking logic.

The toExecuteMessage and getMessageStatus functions correctly implement the three-state model: threshold not met (returns null), executable (state with executable=true), and already executed (state with executable=false). On-chain calls are properly encoded/decoded.


220-265: LGTM - chunked log fetching with rate limiting.

The getAllMessageDispatchedLogs function implements proper chunked fetching with configurable chunkSize and cooldownMs to prevent RPC rate limiting. The sorted return with toBlock enables progress tracking. Per project patterns, RPC errors propagate to upper layers.

relayer-cli/src/utils/botEvents.ts (1)

21-27: LGTM!

The HASHI_NOT_CONFIGURED event is a sensible addition to the Hashi executor event group, enabling proper logging/handling when Hashi configuration is missing.

validator-cli/src/watcher.ts (5)

18-19: Verify RPC provider compatibility with the increased block limit.

The RPC_BLOCK_LIMIT increase from 100 to 1000 is a 10x change. Some RPC providers impose stricter limits on eth_getLogs or similar calls. Ensure your target providers (Infura, Alchemy, public nodes, etc.) support querying 1000 blocks in a single request to avoid runtime failures.

The CYCLE_DELAY_MS increase to 2 minutes (from ~10s) significantly reduces polling frequency—ensure this aligns with the expected claim/challenge response time requirements.


144-151: LGTM!

The gap handling logic correctly ensures the current claimable epoch (currentEpoch - 1) is always in the watch list. The index increment after push ensures the newly added epoch is processed in the while loop.


192-201: LGTM!

The expanded getClaim signature with network and emitter parameters enables proper event emission for observability (e.g., NO_CLAIM_FETCHED, CLAIM_MISMATCH). The object parameter pattern improves readability with this many arguments.


237-244: LGTM!

The updated cleanup condition correctly prevents premature removal of the current claimable epoch and the latest tracked epoch. This ensures epochs remain monitored even when no active transactions are pending.

Note: After the gap handling logic (lines 147-151), latestEpoch will equal currentEpoch - 1 in most non-DEVNET cases, making the two conditions partially redundant. This is harmless but could be simplified if desired.


187-191: No action needed — both target networks support the "finalized" block tag.

The code targets Arbitrum Sepolia (inbox) and Ethereum Sepolia (outbox), both of which support the "finalized" block tag. This is confirmed by both networks' RPC documentation and the fact that the codebase already uses "finalized" extensively in arbToEthState.ts without error handling. The concern about unsupported networks does not apply to this implementation.

Likely an incorrect or invalid review comment.

@mani99brar mani99brar merged commit 4638f44 into dev Jan 20, 2026
13 of 14 checks passed
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.

3 participants