Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Feat(validator)/claimer #417

Open
wants to merge 33 commits into
base: dev
Choose a base branch
from
Open

Feat(validator)/claimer #417

wants to merge 33 commits into from

Conversation

mani99brar
Copy link
Contributor

@mani99brar mani99brar commented Apr 7, 2025

Multi network support

Now the validator can support multiple networks (devnet/tesnet on multiple chains) with config provided in .env file.

claimer

Added claimer (checkAndClaim()) for ArbToEth route which is responsible for making claims, starting verification and verifying them for saved snapshots on testnet:

  • new messages in inbox
  • if last claim was challenged
    For devnet it uses the special devnetAdvanceState() to complete claim and verification in a single transaction, the PRIVATE_KEY should be of the devnet owner.

Added pm2 support

subgraphs as fallbacks for contract event logs

When resolving older epochs the block range is searched heuristically which results into errors due to exceeding rpc block limit , so in case of error in logs subgraph is used. It uses the veascan-subgraph endpoints.

Summary by CodeRabbit

  • New Features

    • Enhanced network configurations for Devnet, Testnet, and Mainnet with updated subgraph endpoints.
    • Improved CLI functionality with automatic restart, file-watching, and dynamic event notifications.
    • Expanded bot path options to support different operational modes.
    • Introduced new error handling mechanisms for various operational scenarios.
  • Refactor

    • Streamlined configuration settings and claim processing logic with robust error handling.
    • Consolidated parameters for clearer network and transaction management.
    • Enhanced transaction handling logic with improved structure and clarity.
  • Chores

    • Upgraded dependencies and removed deprecated packages to improve system stability.

Copy link
Contributor

coderabbitai bot commented Apr 7, 2025

Walkthrough

This pull request introduces extensive configuration and code updates for the validator-cli project. Changes include modifications to environment settings (RPC endpoints, network and subgraph configurations), revisions to transaction handling and claim processing logic, and the addition of new error classes, utilities, and tests. Several obsolete or devnet-specific files were removed, while the watcher, bot configuration, logger, and graph query modules were enhanced for clarity and robustness. Overall, the refactoring focuses on streamlining network-specific behavior, improving error handling, and ensuring consistency across the codebase.

Changes

File(s) Change Summary
validator-cli/.env.dist Removed obsolete RPC and address configurations; added new NETWORKS, VEAOUTBOX_CHAINS, and subgraph endpoints
validator-cli/ecosystem.config.js Removed old app entries; added a new validator-cli entry with updated ts-node settings and autorestart enabled
validator-cli/package.json Upgraded pm2 version and removed web3 & web3-batched-send dependencies
validator-cli/src/ArbToEth/claimer.ts, .../claimer.test.ts Introduced new checkAndClaim function with comprehensive tests covering Devnet and Testnet scenarios
validator-cli/src/ArbToEth/transactionHandler.ts, .../transactionHandler.test.ts Refactored transaction handler with new methods (makeClaim, startVerification, etc.) and updated parameter handling
validator-cli/src/ArbToEth/transactionHandlerDevnet.ts Added Devnet-specific transaction handler to manage state advancement
validator-cli/src/ArbToEth/validator.ts Updated challengeAndResolveClaim to require a claim parameter and remove the fetch operation
validator-cli/src/consts/bridgeRoutes.ts Restructured bridge configurations using RouteConfigs and enforced error handling in getBridgeConfig
Deleted files:
validator-cli/src/devnet/arbToChiado/happyPath.ts,
validator-cli/src/devnet/arbToSepolia/happyPath.ts,
validator-cli/src/utils/devnet.ts,
validator-cli/src/watcherDevnet.ts
Removed obsolete devnet and happyPath scripts
validator-cli/src/utils/botConfig.ts, .../botConfig.test.ts Added new bot configuration module to manage CLI paths and network settings
validator-cli/src/utils/botEvents.ts Expanded and renamed bot event types to reflect detailed bot states
validator-cli/src/utils/claim.ts, .../claim.test.ts Refactored claim fetching logic with a new ClaimParams interface and improved error handling
validator-cli/src/utils/epochHandler.ts, .../epochHandler.test.ts Redesigned epoch range functions to use object parameters and added getBlockFromEpoch
validator-cli/src/utils/errors.ts Renamed and added multiple error classes (e.g., NotDefinedError, InvalidBotPathError) for better specificity
validator-cli/src/utils/ethers.ts Updated functions to include a network parameter; added support for new network-specific handlers
validator-cli/src/utils/graphQueries.ts Introduced new functions to query claim, verification, challenger, and snapshot data from a subgraph
validator-cli/src/utils/logger.ts Revised event logging with dynamic messages and additional listeners for new bot events
validator-cli/src/watcher.ts Updated watcher logic to enforce environment checks, integrate network configurations, and emit enhanced events
validator-cli/tsconfig.json Added compiler options for module resolution, JSON support, and output directory configuration

Sequence Diagram(s)

sequenceDiagram
    participant Caller as Watcher/Caller
    participant Claimer as checkAndClaim
    participant Provider as VeaOutbox/Provider
    participant TxHandler as TransactionHandler
    participant Evt as EventEmitter

    Caller->>Claimer: Invoke checkAndClaim(params)
    Claimer->>Provider: Fetch state root & finalized block
    Provider-->>Claimer: Return state details
    Claimer->>Claimer: Calculate claimable epoch
    alt No existing claim & DEVNET
        Claimer->>Claimer: Retrieve snapshot & last claim epoch
    else Claim exists or non-DEVNET
        Claimer->>TxHandler: Process claim (withdraw, verify, etc.)
    end
    Claimer->>Evt: Emit relevant events
    Evt-->>Caller: Notify status update
Loading

Possibly related PRs

  • feat/arb-sep-to-sep-testnet #344: The changes in the main PR, which involve updates to the .env.dist file for network configurations and the removal of specific RPC and address variables, are related to the retrieved PR that introduces new environment variables and configurations for the testnet, as both address similar aspects of network setup and configuration management.
  • feat/validator tests #388: The changes in the main PR regarding the removal and addition of RPC and address configurations in the .env.dist file are related to the modifications in the retrieved PR, which also involves updates to the .env.dist file, specifically concerning RPC URLs and addresses for various blockchain networks. Both PRs focus on the configuration of network-related settings.
  • Feat/arb sep chaido deploy #359: The changes in the main PR regarding the updates to the .env.dist file and the introduction of new configurations for the Gnosis network are related to the modifications in the retrieved PR, which also includes updates to the .env.dist file with new RPC configurations for Gnosis and Arbitrum, indicating a direct connection at the code level.

Suggested labels

Type: Feature🗿, Package: Contracts, Type: Maintenance :construction:

Suggested reviewers

  • alcercu
  • jaybuidl
  • madhurMongia

Poem

Hoppin' through lines of code in the night,
I nibble on bugs till everything's right.
New configs and tests make my heart beat fast,
In fields of refactor, improvements are vast.
CodeRabbit cheers with a twitch of its nose—
A joyful hop where quality grows!
🥕🐇


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

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

Documentation and Community

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

Copy link

netlify bot commented Apr 7, 2025

Deploy Preview for veascan ready!

Name Link
🔨 Latest commit 30b174d
🔍 Latest deploy log https://app.netlify.com/sites/veascan/deploys/67f3838da3f15a00083bf2f7
😎 Deploy Preview https://deploy-preview-417--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 site configuration.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 13

🧹 Nitpick comments (41)
validator-cli/src/utils/botConfig.ts (4)

1-1: Remove unused import DevnetOwnerNotSetError.
It seems you've imported DevnetOwnerNotSetError but never used it in this file. Consider removing it to keep the imports clean.


16-38: Clarify the return type of getBotPath.
Your doc states the function returns BotPaths, but its signature specifies number. Consider updating the function signature to explicitly return BotPaths for stronger type safety.


45-62: Consider logging a warning when no chain IDs are found.
If VEAOUTBOX_CHAINS is not set, this function silently returns an empty configuration array. Logging a warning could help diagnose misconfigurations.


64-72: Refine type casting in validateNetworks.
Casting networks as unknown and then to Network[] is risky. Consider more explicit type checks or a guarded approach to enhance reliability and maintain strict type safety.

validator-cli/src/ArbToEth/transactionHandlerDevnet.ts (1)

13-15: Consider making devnetAdvanceStateTxn mandatory.
If devnet usage always sets or needs devnetAdvanceStateTxn, consider making it non-null to simplify your logic and reduce branching.

validator-cli/src/ArbToEth/claimer.ts (1)

30-68: Solid setup for checkAndClaim.
The calculation of claimAbleEpoch and conditional creation of transactionHandler is intuitive. Consider adding logs or error handling if outboxStateRoot or the finalized block retrieval fails.

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

33-35: Clarify CLI argument usage in documentation.
You created cliCommand and derive the path from it. Provide inline comments or function docstrings to clarify how command-line arguments map to getBotPath.


36-36: Validate networkConfigs length before indexing.
When you do networkConfigs[0], ensure that the array is not empty. If it is, you could run into an out-of-bounds error.

 if (networkConfigs.length === 0) {
   throw new Error("No network configurations found. Please check your environment variables.");
 }
 emitter.emit(BotEvents.STARTED, path, networkConfigs[0].networks);

37-38: Consider using a Map for better clarity.
transactionHandlers and toWatch are keyed by [epoch: number] or [key: string]. A Map<string, number[]> could be more self-documenting, but it’s fine if you prefer plain objects.


43-45: Emit watchers in a structured manner.
You emit BotEvents.WATCHING for each network. Consider grouping or labeling them more explicitly, especially if you manage logs across multiple watchers.


46-48: Initialize arrays only if needed.
This logic is fine, but you might consider a small helper function to manage toWatch[networkKey] initialization, to improve readability.


51-53: Consider concurrency or repeated calls.
You fetch latestBlock repeatedly. Evaluate if it might be more efficient to do a single provider.getBlock("latest") outside or cache it for a short duration.


67-69: Handle empty epoch arrays gracefully.
If toWatch[networkKey] ever ends up empty, ensure i won't become -1 at runtime. The while loop won't run, but just watch for a potential logic corner case.


83-96: Separate logic for challenge resolution vs claim.
You're toggling challenge resolution based on path > BotPaths.CLAIMER in the same loop. If more paths are added, consider factoring these into separate watchers or modules for clarity.


97-112: Collapse the if-block when path == BOTH.
If you anticipate adding new watchers, consolidating repeated logic for “CLAIMER or BOTH” ensures fewer code branches.


122-128: Check epoch push for duplicates.
You push currentLatestEpoch if > last epoch. If there's a big time jump or slow loop, you might skip epochs in between. Usually that's fine, but confirm it matches your strategy.


135-135: Make wait reusable or configurable.
wait(10s) is a basic approach. If you want dynamic intervals or logging, consider turning this wrapper into a more robust utility.

validator-cli/src/consts/bridgeRoutes.ts (4)

3-10: Maintain consistent import ordering.
You’re pulling in multiple JSON ABIs for devnet/testnet. Keep them organized (e.g., alphabetical or grouped by network) to avoid confusion as the file grows.


37-48: Validate epoch periods for each environment.
DEVNET: 1800/3600, TESTNET: 7200—these are presumably correct. Make sure devnet and testnet intervals align with actual chain configs or reason about finality times.


50-62: Check the Gnosis testnet router.
You’ve included veaRouter for arbToGnosisConfigs[Network.TESTNET]. If a user sets up a devnet with a new router, you might need symmetrical logic.


86-89: Improve the error message.
When the bridge is not found, specify the chainId in the error:

 if (!bridge) {
-  throw new Error("Bridge not found for chain");
+  throw new Error(`Bridge not found for chainId ${chainId}`);
 }
validator-cli/src/utils/claim.test.ts (5)

1-1: Confirm usage of getAddress.
You import getAddress from ethers, but usage in this file might be minimal. If you are not using it, consider removing it.


5-5: Avoid confusion with mock from node:test.
If you’re using Jest, mixing the node:test mocking library can be confusing. Ensure your setup is consistent across the codebase.


18-21: Encapsulate mock functions with a naming convention.
getClaimForEpoch, getVerificationForClaim, and getChallengerForClaim are all jest mocks. Use a clear naming strategy so it’s obvious these are test doubles.


40-42: Check dynamic/undeclared properties.
veaOutbox.getAddress = jest.fn() might be unused or leftover from older code. If it’s not needed, remove it.


204-204: Validate final ClaimNotFoundError usage.
Confirm that throwing ClaimNotFoundError is the desired outcome for an invalid claim. This helps ensure consistent error handling across the codebase.

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

36-45: Update JSDoc comment to reflect new parameter structure

The function signature has been updated to use the ClaimParams interface, but the JSDoc comment (lines 30-35) still refers to individual parameters.

Consider updating the JSDoc to reflect the new parameter structure:

/**
 *
- * @param veaOutbox VeaOutbox contract instance
- * @param epoch epoch number of the claim to be fetched
+ * @param params ClaimParams object containing the parameters for fetching a claim
 * @returns claim type of ClaimStruct
 */

58-89: LGTM! Robust error handling with fallback mechanism

The try-catch block with fallback to graph queries is a great implementation of the PR objective to use subgraphs as fallbacks for contract event logs. This enhances resilience when searching the block range heuristically fails.

However, on line 82, consider using optional chaining:

-    if (verificationFromGraph && verificationFromGraph.startTimestamp) {
+    if (verificationFromGraph?.startTimestamp) {
🧰 Tools
🪛 Biome (1.9.4)

[error] 82-82: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


135-135: Use const instead of var for consistent style

Modern JavaScript/TypeScript practices recommend using const for variables that aren't reassigned.

-  var claimResolveState: ClaimResolveState = {
+  const claimResolveState: ClaimResolveState = {
validator-cli/src/utils/epochHandler.ts (1)

23-29: Update JSDoc comment to reflect new parameter structure

The function signature has been updated to use the EpochRangeParams interface, but the JSDoc comment (lines 12-21) still refers to individual parameters.

Consider updating the JSDoc to reflect the new parameter structure:

/**
 * Sets the epoch range to check for claims.
 *
- * @param currentTimestamp - The current timestamp
- * @param chainId - The chain ID
- * @param now - The current time in milliseconds (optional, defaults to Date.now())
- * @param fetchBridgeConfig - The function to fetch the bridge configuration (optional, defaults to getBridgeConfig)
+ * @param params - EpochRangeParams object containing the parameters for setting epoch range
 *
 * @returns The epoch range to check for claims
 */
validator-cli/src/utils/graphQueries.ts (1)

19-46: Consider parameterizing the GraphQL query.

Inline string interpolation in GraphQL queries can sometimes be brittle or expose potential injection paths. Though the risk may be limited in your environment, using the variables feature of graphql-request can make queries more maintainable and secure.

-      `{
-          claims(where: {epoch: ${epoch}, outbox: "${outbox}"}) { ... }
-       }`
+      `query getClaimForEpoch($epoch: Int!, $outbox: String!) {
+          claims(where: {epoch: $epoch, outbox: $outbox}) { ... }
+       }`,
+      { epoch, outbox }
validator-cli/src/ArbToEth/transactionHandler.ts (2)

64-65: Inaccurate code comment vs. actual duration.

MAX_PENDING_TIME is defined as 5 * 60 * 1000, i.e. 300,000ms (5 minutes), whereas the comment states “3 minutes.” Please reconcile one or the other for clarity.

-export const MAX_PENDING_TIME = 5 * 60 * 1000; // 3 minutes
+export const MAX_PENDING_TIME = 5 * 60 * 1000; // 5 minutes

294-335: Challenge deposit logic is sound but consider fallback checks.

The logic ensures deposit coverage and sets safe upper bounds on maxPriorityFeePerGas. In a production environment, verifying that the deposit is sufficient and the user’s wallet has enough ETH for gas might help avoid silent transaction failures.

validator-cli/src/utils/logger.ts (6)

23-31: Consider clarifying array logging.
When multiple networks are provided, directly embedding the networks array in the log could produce a raw array printout. For more readable logs, consider joining them or formatting them more explicitly (e.g., networks.join(", ")).


49-51: Include epoch detail if relevant.
Currently, “No snapshot saved for epoch” does not show the epoch. If the data is available from the emitter, consider adding it for more diagnostic clarity.


89-91: Minor grammar refinement.
Consider changing “Verification cant start” to “Verification can’t start” or “Verification cannot start.”


93-95: Improve textual consistency.
Likewise, consider “Can't verify snapshot” or “Cannot verify snapshot” for clarity and professionalism.


119-120: Consider logging the epoch.
The message “Withdrawing challenge deposit for epoch” omits which epoch. If that data is known, including it can aid debugging.


133-135: Event logging is correct.
Optionally, you could include which epoch the challenger won.

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

28-28: Add an explicit Network type.
Although network is used, it’s untyped in this function signature. Explicitly typing it as network: Network would enhance type safety.


31-33: Potential missing default for chain IDs.
These case statements return contracts for known chain IDs, but if an unrecognized chain ID is passed, the function returns nothing. Consider adding a default case to throw an error for unknown chain IDs.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2cf51c6 and 28e6095.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (28)
  • validator-cli/.env.dist (1 hunks)
  • validator-cli/ecosystem.config.js (1 hunks)
  • validator-cli/package.json (1 hunks)
  • validator-cli/src/ArbToEth/claimer.test.ts (1 hunks)
  • validator-cli/src/ArbToEth/claimer.ts (1 hunks)
  • validator-cli/src/ArbToEth/transactionHandler.test.ts (8 hunks)
  • validator-cli/src/ArbToEth/transactionHandler.ts (5 hunks)
  • validator-cli/src/ArbToEth/transactionHandlerDevnet.ts (1 hunks)
  • validator-cli/src/ArbToEth/validator.test.ts (2 hunks)
  • validator-cli/src/ArbToEth/validator.ts (4 hunks)
  • validator-cli/src/consts/bridgeRoutes.ts (1 hunks)
  • validator-cli/src/devnet/arbToChiado/happyPath.ts (0 hunks)
  • validator-cli/src/devnet/arbToSepolia/happyPath.ts (0 hunks)
  • validator-cli/src/utils/botConfig.test.ts (1 hunks)
  • validator-cli/src/utils/botConfig.ts (1 hunks)
  • validator-cli/src/utils/botEvents.ts (1 hunks)
  • validator-cli/src/utils/claim.test.ts (8 hunks)
  • validator-cli/src/utils/claim.ts (5 hunks)
  • validator-cli/src/utils/devnet.ts (0 hunks)
  • validator-cli/src/utils/epochHandler.test.ts (2 hunks)
  • validator-cli/src/utils/epochHandler.ts (4 hunks)
  • validator-cli/src/utils/errors.ts (2 hunks)
  • validator-cli/src/utils/ethers.ts (3 hunks)
  • validator-cli/src/utils/graphQueries.ts (1 hunks)
  • validator-cli/src/utils/logger.ts (5 hunks)
  • validator-cli/src/watcher.ts (2 hunks)
  • validator-cli/src/watcherDevnet.ts (0 hunks)
  • validator-cli/tsconfig.json (1 hunks)
💤 Files with no reviewable changes (4)
  • validator-cli/src/devnet/arbToSepolia/happyPath.ts
  • validator-cli/src/devnet/arbToChiado/happyPath.ts
  • validator-cli/src/watcherDevnet.ts
  • validator-cli/src/utils/devnet.ts
🧰 Additional context used
🧬 Code Definitions (13)
validator-cli/src/utils/botConfig.test.ts (2)
validator-cli/src/utils/botConfig.ts (1)
  • getBotPath (21-38)
validator-cli/src/utils/errors.ts (1)
  • InvalidBotPathError (63-63)
validator-cli/src/ArbToEth/claimer.ts (4)
validator-cli/src/ArbToEth/transactionHandler.ts (1)
  • ArbToEthTransactionHandler (68-409)
validator-cli/src/utils/claim.ts (1)
  • ClaimHonestState (193-193)
validator-cli/src/utils/graphQueries.ts (1)
  • getLastClaimedEpoch (148-148)
validator-cli/src/utils/ethers.ts (1)
  • getTransactionHandler (123-123)
validator-cli/src/ArbToEth/transactionHandlerDevnet.ts (2)
validator-cli/src/ArbToEth/transactionHandler.ts (4)
  • Transactions (39-49)
  • Transaction (34-37)
  • ArbToEthTransactionHandler (68-409)
  • TransactionHandlerConstructor (23-32)
validator-cli/src/consts/bridgeRoutes.ts (1)
  • getBridgeConfig (92-92)
validator-cli/src/watcher.ts (6)
validator-cli/src/utils/errors.ts (1)
  • MissingEnvError (66-66)
validator-cli/src/utils/botConfig.ts (2)
  • getBotPath (21-38)
  • getNetworkConfig (49-62)
validator-cli/src/consts/bridgeRoutes.ts (1)
  • getBridgeConfig (92-92)
validator-cli/src/utils/epochHandler.ts (2)
  • setEpochRange (77-77)
  • getBlockFromEpoch (77-77)
validator-cli/src/utils/claim.ts (1)
  • getClaim (193-193)
validator-cli/src/ArbToEth/claimer.ts (1)
  • CheckAndClaimParams (117-117)
validator-cli/src/ArbToEth/claimer.test.ts (2)
validator-cli/src/ArbToEth/claimer.ts (2)
  • CheckAndClaimParams (117-117)
  • checkAndClaim (117-117)
validator-cli/src/utils/claim.ts (1)
  • ClaimHonestState (193-193)
validator-cli/src/utils/graphQueries.ts (1)
validator-cli/src/utils/errors.ts (1)
  • ClaimNotFoundError (60-60)
validator-cli/src/utils/claim.test.ts (2)
validator-cli/src/utils/graphQueries.ts (3)
  • getClaimForEpoch (147-147)
  • getVerificationForClaim (149-149)
  • getChallengerForClaim (150-150)
validator-cli/src/utils/claim.ts (1)
  • getClaim (193-193)
validator-cli/src/utils/claim.ts (2)
validator-cli/src/utils/graphQueries.ts (4)
  • getClaimForEpoch (147-147)
  • getVerificationForClaim (149-149)
  • getChallengerForClaim (150-150)
  • getSnapshotSentForEpoch (151-151)
validator-cli/src/utils/errors.ts (1)
  • ClaimNotFoundError (60-60)
validator-cli/src/ArbToEth/validator.ts (2)
validator-cli/src/ArbToEth/transactionHandler.ts (1)
  • ArbToEthTransactionHandler (68-409)
validator-cli/src/utils/emitter.ts (1)
  • defaultEmitter (4-4)
validator-cli/src/ArbToEth/transactionHandler.test.ts (4)
validator-cli/src/ArbToEth/transactionHandler.ts (3)
  • TransactionHandlerConstructor (23-32)
  • MAX_PENDING_CONFIRMATIONS (65-65)
  • Transaction (34-37)
validator-cli/src/utils/emitter.ts (2)
  • MockEmitter (6-14)
  • defaultEmitter (4-4)
validator-cli/src/consts/bridgeRoutes.ts (1)
  • getBridgeConfig (92-92)
validator-cli/src/utils/errors.ts (1)
  • ClaimNotSetError (61-61)
validator-cli/src/consts/bridgeRoutes.ts (1)
veascan-web/src/consts/bridges.ts (1)
  • bridges (39-58)
validator-cli/src/ArbToEth/transactionHandler.ts (4)
validator-cli/src/utils/emitter.ts (1)
  • defaultEmitter (4-4)
validator-cli/src/consts/bridgeRoutes.ts (1)
  • getBridgeConfig (92-92)
validator-cli/src/utils/errors.ts (1)
  • ClaimNotSetError (61-61)
validator-cli/src/utils/arbMsgExecutor.ts (1)
  • messageExecutor (82-82)
validator-cli/src/utils/ethers.ts (4)
validator-cli/src/utils/errors.ts (2)
  • NotDefinedError (62-62)
  • InvalidNetworkError (65-65)
validator-cli/src/ArbToEth/claimer.ts (1)
  • checkAndClaim (117-117)
validator-cli/src/ArbToEth/transactionHandlerDevnet.ts (1)
  • ArbToEthDevnetTransactionHandler (19-71)
validator-cli/src/ArbToEth/transactionHandler.ts (1)
  • ArbToEthTransactionHandler (68-409)
🪛 Biome (1.9.4)
validator-cli/src/utils/claim.ts

[error] 82-82: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

validator-cli/src/utils/ethers.ts

[error] 39-45: This case is falling through to the next case.

Add a break or return statement to the end of this case to prevent fallthrough.

(lint/suspicious/noFallthroughSwitchClause)


[error] 102-108: This case is falling through to the next case.

Add a break or return statement to the end of this case to prevent fallthrough.

(lint/suspicious/noFallthroughSwitchClause)

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: test
  • GitHub Check: Analyze (javascript)
  • GitHub Check: dependency-review
  • GitHub Check: Scorecard analysis
🔇 Additional comments (82)
validator-cli/tsconfig.json (2)

2-4: Validate "include" configuration.

The "include" array now clearly specifies the "src" directory and is properly closed, ensuring that all intended source files are included during compilation.


5-13: Enhance TypeScript compiler settings.

The added "compilerOptions" block sets essential settings such as "baseUrl", "module", "moduleResolution", and output directory ("outDir"). These improvements promote better module resolution, compatibility between CommonJS and ES Modules, and facilitate the build process.

validator-cli/src/utils/epochHandler.test.ts (5)

1-1: Updated the imports to include the new EpochRangeParams type

The import statement now includes EpochRangeParams which aligns with the refactoring of the setEpochRange function to use an object parameter pattern instead of individual arguments.


14-14: Adjust the startEpoch calculation

The subtraction value in the calculation of startEpoch has been changed from 2 to 1, which affects the range of epochs being tested. Ensure this change correctly aligns with the updated implementation of the setEpochRange function.


20-33: Good refactoring to use object parameters

The refactoring to use an object parameter pattern is a good practice for functions with multiple parameters. This improves code readability and makes the parameter passing more explicit.


34-34: Updated assertion to match the modified function behavior

The expectation has been updated to check for currentEpoch instead of currentEpoch - 1, reflecting changes in the underlying implementation of setEpochRange.


42-43: Simplified function call with direct value

The call to getLatestChallengeableEpoch has been simplified by passing a hardcoded value directly instead of using a variable, which is cleaner. The removed fetchBridgeConfig mock suggests the function no longer requires this parameter.

validator-cli/src/utils/errors.ts (7)

1-2: Added new imports for error handling

The added imports for BotPaths and Network support the new error classes that need to reference valid paths and networks.


19-25: Improved error class for reusability

Renamed TransactionHandlerNotDefinedError to the more generic NotDefinedError and updated it to accept a parameter, making it more reusable across different scenarios. This is a good practice for improving code maintainability.


27-33: Added error class for invalid bot paths

The InvalidBotPathError class provides clear error messages that include the valid options from BotPaths, helping developers quickly identify and fix bot path issues.


35-41: Added error class for devnet owner configuration

This error supports the PR's devnet functionality which requires the PRIVATE_KEY of the devnet owner to be set.


43-49: Added error class for network validation

This error aligns with the PR's multi-network support feature, allowing clear validation of supported networks. The error message helpfully lists all valid networks from the Network enum.


51-57: Added error class for missing environment variables

This is useful for validating required environment variables, which is especially important given the PR's mention of configurable functionality through the .env file.


59-67: Updated exports to include all error classes

The export statement has been properly updated to include all new error classes, making them available for use throughout the application.

validator-cli/ecosystem.config.js (1)

4-14: Updated PM2 configuration for the validator

The configuration has been significantly improved to support the validator-cli with the following enhancements:

  1. Created a single entry point named "validator-cli" using the watcher script
  2. Added proper TypeScript configuration with interpreter arguments
  3. Enabled watch and autorestart to improve reliability and automatic recovery
  4. Added TS_NODE_PROJECT environment variable to ensure correct TypeScript configuration

These changes align well with the PR objective of adding PM2 support for better process management.

validator-cli/src/utils/botConfig.test.ts (1)

1-25: Well-structured unit tests with good coverage.

The new test file provides excellent coverage for the getBotPath function, thoroughly testing all its code paths including:

  • Default path behavior
  • Claimer path detection
  • Challenger path detection
  • Error handling for invalid paths

The test implementations are clear, concise, and follow Jest best practices.

validator-cli/src/ArbToEth/validator.ts (4)

9-10: LGTM: Network and ClaimStruct imports added appropriately.

These imports support the multi-network functionality mentioned in the PR objectives.


15-16: Good enhancement: Added claim parameter to interface.

Adding the claim parameter to the ChallengeAndResolveClaimParams interface properly reflects the changes in function signature.


30-32: Improved parameter handling with better error checking.

The function now directly accepts the claim as a parameter and includes proper null checking, which improves error handling. This approach is cleaner than fetching the claim within the function.

Also applies to: 43-46


64-73: Network configuration hardcoded for transaction handler.

The network is explicitly set to Network.TESTNET with a comment explaining this is appropriate since TESTNET and MAINNET use the same contracts. This aligns with the multi-network support objective of the PR.

validator-cli/src/ArbToEth/validator.test.ts (3)

43-43: Simplified test setup with direct claim property assignment.

The test now directly assigns the mock claim to the dependency object, which is a cleaner approach that matches the updated function signature in validator.ts.


56-58: Added test cleanup to prevent state leakage.

Adding afterEach with jest.clearAllMocks() ensures that mock state doesn't leak between tests, which is a best practice for test isolation.


61-61: Updated test to use direct claim assignment.

This change correctly reflects the new implementation where claims are passed directly rather than fetched within the function.

validator-cli/src/ArbToEth/claimer.test.ts (5)

1-5: Appropriate imports for the claimer test suite.

The imports correctly include the necessary dependencies for testing the claimer functionality, including ethers, the function under test, and required types.


6-133: Well-structured test setup with comprehensive mocks.

The test setup is thorough and well-organized:

  • Mock objects for all dependencies
  • Transaction handler with appropriate mock implementations
  • Clear structure with beforeEach and afterEach hooks
  • Type safety with CheckAndClaimParams

This provides a solid foundation for testing the claimer functionality across different scenarios.


134-163: Comprehensive error case testing.

These tests validate that the checkAndClaim function correctly handles various error scenarios:

  • No claim for a passed epoch
  • No snapshot saved
  • No new messages in the inbox

Thorough error case testing helps ensure robustness of the implementation.


164-181: Devnet-specific functionality well tested.

The test properly validates the devnet-specific behavior mentioned in the PR objectives, confirming that the devnetAdvanceState function is called for devnet environments to handle both claim and verification in a single transaction.


182-232: Comprehensive testnet scenario coverage.

The testnet tests cover all the key scenarios:

  • Making a new claim when none exists
  • Making a claim when the last one was challenged
  • Withdrawing claim deposit when claimer is honest
  • Starting verification when not yet started
  • Verifying snapshot when verification is started

This thorough coverage ensures the testnet-specific functionality works as expected.

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

5-9: Enum BotPaths is clear and maintainable.
No issues found here. This numeric enum effectively organizes the possible bot paths.


40-43: Interface NetworkConfig looks good.
No concerns found; it's straightforward and well-defined.

validator-cli/src/ArbToEth/transactionHandlerDevnet.ts (4)

1-12: Imports appear in good order.
All imported entities are used and relevant to devnet transaction handling.


17-17: Ensure the correct chain ID.
11155111 corresponds to the Sepolia test network. Please confirm if this constant is intentional for devnet usage, or if a separate chain ID is required.

Would you like to confirm references to devnet in your environment variables or code?


19-31: Subclass design is clear.
This extension of ArbToEthTransactionHandler is well-structured, neatly adding devnet-specific transaction properties while preserving existing logic.


32-49: Caution with forced devnet casting.
veaOutbox is cast to VeaOutboxArbToEthDevnet without runtime checks. Ensure at runtime that the provided contract truly matches the devnet interface to avoid undefined behavior.

validator-cli/src/ArbToEth/claimer.ts (4)

1-3: Imports appear consistent.
All imported modules (Events, ethers, providers) are pertinent to the claiming logic.


4-28: Interface CheckAndClaimParams is comprehensive.
It clearly outlines all parameters for claim-related operations. No immediate suggestions.


82-95: Conditional claim creation logic is consistent.
The checks for new messages or challenged claims appear correct. No issues found in this block.


96-115: Check transitions for claim.honest exhaustively.
There's no explicit handling for ClaimHonestState.CHALLENGER. Ensure no use case is omitted if the claim’s honesty state is set to CHALLENGER.

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

31-32: Ensure consistency in environment variable management.
It's good that you're checking for PRIVATE_KEY early. Consider extending this pattern to other essential environment variables so you fail fast if something else is missing.


78-82: Handle null claims carefully.
getClaim may return null; you handle it in line 83. That's correct. Just watch for a second pass logic if the same epoch remains in toWatch.


114-119: Remove epoch from toWatch only after final settlement.
Line 116-118 deletes the epoch if no updates. This can be correct. However, if a late transaction finalizes an older epoch, you risk missing it. Thoroughly confirm your business logic.


55-65:

✅ Verification successful

Ensure correct epoch detection logic.
Your logic sets the epoch to the single latest one on devnet or a range on testnet. Verify that the boundary conditions (e.g., crossing from devnet to testnet in the same run) never happen or are handled.

Follow-up: Confirm that setEpochRange will produce correct results for short epoch periods and that no off-by-one errors occur for boundary epochs.


🏁 Script executed:

#!/bin/bash
# Searching for setEpochRange usage to confirm no off-by-one issues
rg -A 2 'setEpochRange'

Length of output: 1523


Confirm Epoch Detection Logic and Boundary Conditions

  • The code in validator-cli/src/watcher.ts correctly distinguishes DEVNET (using a single epoch based on a floored calculation) from other networks (using a range generated by setEpochRange).
  • A scan of the codebase confirms that setEpochRange is thoroughly exercised in tests (see validator-cli/src/utils/epochHandler.test.ts), which should help ensure correct behavior even with short epoch periods and around boundary values.
  • Please double-check that any potential scenario where a network might change (e.g., DEVNET to testnet mid-run) is either impossible or explicitly handled.

70-76: 💡 Verification agent

🧩 Analysis chain

Validate epochBlock for correctness.
You compute epochBlock from getBlockFromEpoch. If for any reason that function returns an invalid or negative block number, be sure to handle it.

Ask the user to verify if the underlying block retrieval is robust:


🏁 Script executed:

#!/bin/bash
# Checking references to getBlockFromEpoch for error handling
rg -A 5 'getBlockFromEpoch'

Length of output: 1972


Validate and Safeguard epochBlock Calculation

After reviewing the implementation, it appears that the function getBlockFromEpoch (defined in validator-cli/src/utils/epochHandler.ts) does not currently validate its output. In particular, if getBlockFromEpoch happens to return an invalid or negative block number, the subsequent arithmetic in watcher.ts may lead to unintended behavior. For robust error handling, please add a safeguard to verify that epochBlock is a valid (non-negative) block number before it is used.

  • In validator-cli/src/watcher.ts (lines 70–76), perform a check to ensure that epochBlock >= 0 (or meets your defined validity criteria).
  • If an invalid value is detected, handle the condition appropriately (e.g., log an error, throw an exception, or apply a fallback strategy).
  • Alternatively, consider adding validation inside getBlockFromEpoch itself so that it returns either a guaranteed valid block number or a clear error state.
⛔ Skipped due to learnings
Learnt from: mani99brar
PR: kleros/vea#396
File: validator-cli/src/utils/epochHandler.ts:67-74
Timestamp: 2025-04-07T05:14:00.213Z
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.
validator-cli/src/consts/bridgeRoutes.ts (5)

11-13: Double-check veaInboxArbToGnosisTestnet import.
Line 11 references VeaOutboxArbToEthTestnet.json but is named veaInboxArbToGnosisTestnet. Confirm it’s not a copy-paste error.


21-22: Use typed optional fields consistently.
You introduced routerRPC?: string; and placed routeConfig as [key in Network]: RouteConfigs. Confirm that each route expects or tolerates a missing routerRPC.


32-35: Enum usage is clear.
Using Network.DEVNET / Network.TESTNET is a neat approach. Just ensure no additional networks slip in unhandled.


72-72: Maintain consistency in bridging data.
You have routeConfig: arbToEthConfigs for chainId 11155111. Ensure this corresponds to the correct bridging route (Arb → Eth).


81-82: Router RPC usage.
You define routerRPC for chainId=10200 with process.env.RPC_ETH. Confirm it’s correct for Gnosis bridging.

validator-cli/src/utils/claim.test.ts (5)

58-58: Validate synergy with hashClaim.
You mock the claimHashes call. Check that the hashed result matches the claim’s structure to avoid mismatch in some test scenarios.


71-72: Reassigning to mockClaimParams.veaOutbox right before calling.
This ensures the function sees the fresh mock. Good practice. Consider more descriptive variable names so it’s clearer which version of veaOutbox you’re injecting.


137-161: Fallback on subgraphs test scenario is robust.
You simulate “Logs not available” and confirm the subgraph approach. Great coverage. Just ensure subgraph queries are tested for real volumes or partial data.


163-166: Testing for no claim found.
You properly check ethers.ZeroHash from claimHashes. This negative test scenario is valuable.


172-180: Assertion on both on-chain logs and subgraph data.
You handle “no logs found” by also returning null from subgraph mocks. This setup is consistent with your fallback approach. Good job.

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

4-4: LGTM! Well-structured event organization

The additions to BotEvents align well with the multi-network support and claimer functionality goals of this PR, particularly:

  • Bridger state events like WATCHING and NO_CLAIM_REQUIRED
  • More granular claim state events that describe the process flow
  • New ADV_DEVNET section specifically for devnet state
  • Transaction monitoring capabilities with TXN_EXPIRED

The organization by event category (Bridger, Epoch, Claim, Devnet, Transaction) improves code readability and maintainability.

Also applies to: 9-9, 14-14, 17-22, 24-24, 27-30, 33-34, 41-41

validator-cli/.env.dist (1)

15-19: LGTM! Improved configuration for multi-network support

The addition of chain IDs and subgraph endpoints directly fulfills the PR objectives by:

  1. Supporting multiple networks through VEAOUTBOX_CHAINS configuration
  2. Implementing subgraphs as fallbacks for contract event logs

This approach is more flexible than the previous network-specific configuration.

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

6-11: LGTM! Well-structured imports for fallback mechanisms

The addition of graph query functions provides the necessary fallback mechanisms for retrieving data when direct contract event logs fail, which aligns with the PR objective of using subgraphs as fallbacks.


13-17: LGTM! Properly exported enum

The ClaimHonestState enum is correctly defined and exported, making it accessible for other parts of the codebase.


19-28: LGTM! Well-structured interface

The ClaimParams interface provides a clean way to organize parameters for the getClaim function, which improves code maintainability and readability.


146-162: LGTM! Consistent error handling pattern

The error handling in getClaimResolveState follows the same pattern as in getClaim, using graph queries as fallbacks when direct contract event logs fail. This consistency is good for maintainability.

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

4-10: LGTM! Well-structured interface

The EpochRangeParams interface provides a clear organization of parameters for the setEpochRange function, which improves code maintainability and readability.


44-48: LGTM! Improved array creation

Using Array.from is a more elegant approach than the previous method of creating an array with new Array().fill().map().

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

4-17: Well-defined interface.

Your ClaimData interface thoroughly documents all claim-related fields (e.g., id, bridger, stateroot, etc.). This promotes clarity for other parts of the codebase consuming or providing such data.


48-74: Return type mismatch risk.

The function’s signature returns Promise<ClaimData>, but if claims is empty, result['claims'][0] will be undefined. Consider throwing a ClaimNotFoundError if no claim is retrieved, or adjust the return type to Promise<ClaimData | undefined> to accurately reflect the possibility of no results.

validator-cli/src/ArbToEth/transactionHandler.test.ts (3)

1-8: Imports and new references look good.

All the updated imports for transactionHandler and related interfaces/classes are correct and consistent with the usage patterns in this test file.


148-185: Well-structured claim tests.

The new tests for makeClaim() confirm correct transaction creation and status checking. This coverage ensures repeated or pending transactions don’t trigger additional claims, which is crucial for robust bridging logic.


294-365: Comprehensive challenge claim tests.

These tests effectively verify both happy and unhappy paths (claim set vs. not set, pending transaction vs. new transaction). Good work ensuring challenge logic is exercised thoroughly.

validator-cli/src/ArbToEth/transactionHandler.ts (1)

117-147: Smart use of TXN_EXPIRED.

The newly introduced expiration logic for pending transactions prevents indefinite waiting when transactions are stuck or dropped, providing a practical “escape hatch” in the bridging workflow.

validator-cli/src/utils/logger.ts (8)

3-4: All good on new imports.
The imports for BotPaths and Network are straightforward and appear to be used properly further in the file.


33-34: Straightforward chain-watching logs.
No issues found. The new event listener appears correct.


45-46: Clear logging for no-claim scenario.
No concerns. This event clarifies that no claim is necessary for the given epoch.


54-55: Consistent epoch logging.
This message cleanly indicates a passed epoch for claiming. No issues.


76-78: Transaction expiration logging looks good.
The event name and message align well to indicate an expired transaction.


81-84: Accurate log for claim initiation.
This clarifies that a claim process is starting for the specified epoch.


85-88: Verification start logging is comprehensive.
Indicates precisely when verification is initiated.


103-105: Log alignment is consistent.
This event mapping for a challenged claim matches other epoch-based logs, no issues noticed.

validator-cli/src/utils/ethers.ts (7)

5-5: Import addition looks correct.
This factory import is used to support Gnosis Devnet functionality.


14-18: New imports appear consistent.
They align with updated references to checkAndClaim, ArbToEthDevnetTransactionHandler, and new error classes.


20-21: Renaming parameter to rpcUrl is coherent.
This improves clarity and consistency with other functions.


37-37: Function signature now includes network.
This refactor to accept network: Network aligns well with multi-network handling.


77-83: Claim validator looks fine.
Adding network to the signature is consistent. The default case properly throws NotDefinedError for unsupported chain IDs.


84-98: Claimer logic is robust.
The nested switch handles both chainId and network with appropriate errors in the default cases.


122-122: Export addition for getClaimer.
No issues. This preserves consistency with other exported functions.

Comment on lines +25 to +26
"pm2": "^6.0.5",
"typescript": "^4.9.5"
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Updated PM2 and removed Web3 dependencies

  1. PM2 has been upgraded from ^5.2.2 to ^6.0.5, which aligns with the PR objective of adding PM2 support.
  2. The web3 and web3-batched-send dependencies have been removed, suggesting a shift in how the application interacts with the blockchain.

🏁 Script executed:

#!/bin/bash
# Check for any remaining web3 imports in the codebase that might break after removing these dependencies
rg -i "require\(['\"]web3['\"]" --type ts
rg -i "import.*from ['\"]web3['\"]" --type ts
rg -i "web3-batched-send" --type ts

Length of output: 277


Action Required: Remove Remaining Web3 References

The changes in validator-cli/package.json correctly update PM2 to ^6.0.5 and remove the Web3-related dependencies. However, verification revealed that the file relayer-cli/src/utils/relay.ts still imports:

  • import Web3 from "web3";
  • import initializeBatchedSend from "web3-batched-send";

Please update or remove these imports to ensure consistency with the dependency removals and to prevent potential runtime issues.

Comment on lines +50 to +70
public async devnetAdvanceState(stateRoot: string): Promise<void> {
this.emitter.emit(BotEvents.ADV_DEVNET, this.epoch);
const currentTime = Date.now();
const transactionStatus = await this.checkTransactionStatus(
this.transactions.devnetAdvanceStateTxn,
ContractType.OUTBOX,
currentTime
);
if (transactionStatus != TransactionStatus.NOT_MADE && transactionStatus != TransactionStatus.EXPIRED) {
return;
}
const deposit = getBridgeConfig(CHAIN_ID).deposit;
const startVerifTrx = await this.veaOutboxDevnet.devnetAdvanceState(this.epoch, stateRoot, {
value: deposit,
});
this.emitter.emit(BotEvents.TXN_MADE, startVerifTrx.hash, this.epoch, "Advance Devnet State");
this.transactions.devnetAdvanceStateTxn = {
hash: startVerifTrx.hash,
broadcastedTimestamp: currentTime,
};
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add robust error handling around devnetAdvanceState.
If the transaction reverts or fails, the code doesn't catch exceptions. Consider a try/catch to log errors or revert state if the call fails.

Comment on lines 69 to 81
if (network == Network.DEVNET) {
const devnetTransactionHandler = transactionHandler as ArbToEthDevnetTransactionHandler;
if (claim == null) {
[savedSnapshot, claimData] = await Promise.all([
veaInbox.snapshots(epoch),
fetchLatestClaimedEpoch(veaOutbox.target),
]);

newMessagesToBridge = savedSnapshot != outboxStateRoot && savedSnapshot != ethers.ZeroHash;
if (newMessagesToBridge && savedSnapshot != ethers.ZeroHash) {
await devnetTransactionHandler.devnetAdvanceState(savedSnapshot);
return devnetTransactionHandler;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Double-check concurrency for DEVNET state advancement.
After devnetAdvanceState, there's no explicit confirmation of successful finality. Adding a verification step or error-handling logic could ensure the devnet state advanced properly.

Comment on lines 49 to 50
const veaInbox = getVeaInbox(routeConfig[network].veaInbox.address, privKey, inboxRPC, chainId, network);
const veaOutbox = getVeaOutbox(routeConfig[network].veaOutbox.address, privKey, outboxRPC, chainId, network);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Validate contract addresses.
Ensure routeConfig[network].veaInbox.address and .veaOutbox.address are not undefined or invalid. If environment misconfiguration occurs, it can break these calls.

Comment on lines 40 to 42
for (const networkConfig of networkConfigs) {
const { chainId, networks } = networkConfig;
const { routeConfig, inboxRPC, outboxRPC } = getBridgeConfig(chainId);
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Catch potential errors from getBridgeConfig.
If bridgeRoutes.ts throws when a config is missing, ensure you handle it gracefully, logging relevant info.


🏁 Script executed:

#!/bin/bash
# Checking references to getBridgeConfig calls to confirm they are wrapped in try/catch or properly handled
rg -A 3 'getBridgeConfig'

Length of output: 9949


Error Handling for Missing Bridge Configurations

The current implementation in validator-cli/src/watcher.ts (lines 40–42) calls getBridgeConfig(chainId) directly, which will throw an error when a configuration is missing. To avoid runtime crashes, please wrap the call in a try/catch block and log sufficient details (e.g., the chainId and error message) to help diagnose the issue. For example:

-    const { routeConfig, inboxRPC, outboxRPC } = getBridgeConfig(chainId);
+    let routeConfig, inboxRPC, outboxRPC;
+    try {
+      ({ routeConfig, inboxRPC, outboxRPC } = getBridgeConfig(chainId));
+    } catch (error) {
+      console.error(`Failed to load bridge config for chainId ${chainId}:`, error);
+      continue; // or handle the failure as required
+    }

This change will ensure that if a config is missing, the error is managed gracefully without crashing the application.

📝 Committable suggestion

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

Suggested change
for (const networkConfig of networkConfigs) {
const { chainId, networks } = networkConfig;
const { routeConfig, inboxRPC, outboxRPC } = getBridgeConfig(chainId);
for (const networkConfig of networkConfigs) {
const { chainId, networks } = networkConfig;
- const { routeConfig, inboxRPC, outboxRPC } = getBridgeConfig(chainId);
+ let routeConfig, inboxRPC, outboxRPC;
+ try {
+ ({ routeConfig, inboxRPC, outboxRPC } = getBridgeConfig(chainId));
+ } catch (error) {
+ console.error(`Failed to load bridge config for chainId ${chainId}:`, error);
+ continue; // or handle the failure as required
+ }
// ... rest of the loop code
}

Comment on lines +68 to +75
const getBlockFromEpoch = async (epoch: number, epochPeriod: number, provider: JsonRpcProvider): Promise<number> => {
const epochTimestamp = epoch * epochPeriod;
const latestBlock = await provider.getBlock("latest");
const baseBlock = await provider.getBlock(latestBlock.number - 1000);
const secPerBlock = (latestBlock.timestamp - baseBlock.timestamp) / (latestBlock.number - baseBlock.number);
const blockFallBack = Math.floor((latestBlock.timestamp - epochTimestamp) / secPerBlock);
return latestBlock.number - blockFallBack;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add validation for calculated block number

The getBlockFromEpoch function calculates a block number based on the average block time, but doesn't validate that the result is positive and within range.

Consider adding validation to ensure the returned block number is valid:

  const blockFallBack = Math.floor((latestBlock.timestamp - epochTimestamp) / secPerBlock);
- return latestBlock.number - blockFallBack;
+ const calculatedBlock = latestBlock.number - blockFallBack;
+ // Ensure block number is valid (not negative and not greater than latest block)
+ return Math.max(0, Math.min(calculatedBlock, latestBlock.number));

Also, consider adding a comment about the assumption of constant block time:

// Note: This calculation assumes relatively consistent block times over the range,
// which may not hold during periods of network congestion.

Comment on lines +124 to +144
const getSnapshotSentForEpoch = async (epoch: number, veaInbox: any): Promise<{ txHash: string }> => {
try {
const subgraph = process.env.VEAINBOX_SUBGRAPH;
const veaInboxAddress = veaInbox.toLowerCase();

const result: SenSnapshotResponse = await request(
`${subgraph}`,
`{
snapshots(where: {epoch: ${epoch}, inbox_: { id: "${veaInboxAddress}" }}) {
fallback{
txHash
}
}
}`
);
return result.snapshots[0].fallback[0];
} catch (e) {
console.log(e);
return undefined;
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential undefined return from the catch block.

The function’s signature enforces a return type of { txHash: string }, yet the catch block returns undefined. You might want to:

  1. Throw a dedicated error if the call fails, or
  2. Change the return type to Promise<{ txHash: string } | undefined>

Additionally, if result.snapshots is empty, result.snapshots[0] could be undefined, causing a runtime error. Consider validating the array length first.

Copy link

sonarqubecloud bot commented Apr 7, 2025

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

17-19: Use a typed interface or type alias for mockClaimParams.
This aligns with the prior comment in previous reviews, improving readability and maintainability.

🧹 Nitpick comments (19)
validator-cli/src/utils/botConfig.ts (6)

1-3: Consider placing dotenv config at the entry point.
In many Node.js projects, calling require("dotenv").config() at the main entry point (rather than within a utility file) helps centralize environment loading.


16-21: Doc comments are clear.
Minor note: You may include parameter details in JSDoc for better tooling support.


21-38: Path parsing logic is straightforward.
Overall logic is correct. One minor improvement could involve validating the extracted path is non-empty.


40-43: Naming might be more expressive.
NetworkConfig is acceptable, but consider a more descriptive name (e.g., ChainNetworksConfig) if multiple networks map to a single chain ID.


45-62: Configuration struct creation is effective.
Returning an array of NetworkConfig is fine, though you might align it with a dictionary keyed by chain ID if you foresee direct chain lookups in the future.


64-72: Validate networks logic is correct.
The as unknown as Network[] cast works, but consider a more direct approach (e.g., mapping and narrowing the string to valid enum members) to avoid double casting.

validator-cli/src/consts/bridgeRoutes.ts (3)

3-13: Importing multiple devnet/testnet artifacts.
These JSON imports are untyped (inferred as any). If desired, consider generating contract type definitions to benefit from compile-time checks.


25-30: Definition of RouteConfigs is clear.
If you want stricter checks, you could define a specific type for these contract artifacts instead of any.


86-90: Improves error handling in getBridgeConfig.
Consider including the chain ID in the error message to help with debugging, e.g., `Bridge not found for chain ${chainId}`.

-  if (!bridge) throw new Error(`Bridge not found for chain`);
+  if (!bridge) throw new Error(`Bridge not found for chain ${chainId}`);
validator-cli/src/ArbToEth/claimer.ts (3)

30-81: Central logic in checkAndClaim is well-structured.
The flow for devnet vs. standard networks is clear. Consider logging any caught exceptions from veaOutbox.stateRoot() to aid debugging.


104-122: makeClaim logic for testnet / mainnet.
Properly checks newMessagesToBridge or lastClaimChallenged. Potential extension: log if savedSnapshot matches the outbox state root for easier visibility.


124-144: verifyClaim covers multiple claim states.
The transitions for CLAIMER, NONE, or presence of challenger are well-defined. Consider verifying block finality for advanced reorg safety.

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

13-17: Consider adding inline documentation for the enum values.
Adding brief comments for each enum value (e.g., NONE, CLAIMER, CHALLENGER) can improve readability for future maintainers.

 enum ClaimHonestState {
   NONE = 0,
+  // No honest party identified
   CLAIMER = 1,
+  // Claimer is honest
   CHALLENGER = 2,
+  // Challenger is honest
 }

19-28: Replace any with a more specific type for veaOutbox.
Using any may mask potential type errors. Consider defining or importing the correct type from the contract’s type definitions.

 interface ClaimParams {
-  veaOutbox: any;
+  veaOutbox: VeaOutbox; // or another suitable contract interface
   veaOutboxProvider: JsonRpcProvider;
   epoch: number;

72-89: Catch block is too broad.
Catching all errors without logging critical details (e.g., stack trace) may complicate debugging. Consider logging or narrowing error handling.

 } catch (error) {
+  console.error("Error in getClaim (on-chain filter):", error);
   const claimFromGraph = await fetchClaimForEpoch(epoch, await veaOutbox.getAddress());
   ...
 }

146-162: Log caught errors when querying for snapshot logs.
Similar to the pattern in getClaim, consider logging or differentiating relevant errors to ease diagnosis.

 } catch (error) {
+  console.error("Error fetching SnapshotSent logs from chain:", error);
   const sentSnapshotFromGraph = await getSnapshotSentForEpoch(epoch, await veaInbox.getAddress());
   ...
 }
validator-cli/src/watcher.ts (3)

31-38: Validate PRIVATE_KEY in a single place.
Throwing MissingEnvError early is good, but consider logging the environment or referencing an .env file for user clarity.

 const privKey = process.env.PRIVATE_KEY;
 if (!privKey) {
+  console.warn("Ensure PRIVATE_KEY is set in the .env file or environment variables.");
   throw new MissingEnvError("PRIVATE_KEY");
 }

47-98: Parallelizing processNetwork calls for each route.
Invoking processNetwork in a loop is fine if concurrency is acceptable. Alternatively, consider concurrency management or rate limiting if needed.

for (const networkConfig of networkConfigs) {
-  await processNetwork(path, networkConfig, transactionHandlers, toWatch, emitter);
+  // Consider concurrency or wrapping in Promise.all
+  // await Promise.all(networkConfigs.map((networkConfig) => processNetwork(...)));
}

174-175: Utility for controlled delays.
wait function is a typical async pattern. If more precise scheduling or cancellation is needed, consider advanced queue management.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 28e6095 and 30b174d.

📒 Files selected for processing (9)
  • validator-cli/src/ArbToEth/claimer.ts (1 hunks)
  • validator-cli/src/ArbToEth/transactionHandler.test.ts (8 hunks)
  • validator-cli/src/consts/bridgeRoutes.ts (1 hunks)
  • validator-cli/src/utils/botConfig.ts (1 hunks)
  • validator-cli/src/utils/claim.test.ts (7 hunks)
  • validator-cli/src/utils/claim.ts (5 hunks)
  • validator-cli/src/utils/epochHandler.test.ts (2 hunks)
  • validator-cli/src/utils/ethers.ts (3 hunks)
  • validator-cli/src/watcher.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • validator-cli/src/utils/epochHandler.test.ts
  • validator-cli/src/utils/ethers.ts
🧰 Additional context used
🧬 Code Definitions (5)
validator-cli/src/ArbToEth/claimer.ts (5)
validator-cli/src/ArbToEth/transactionHandler.ts (2)
  • ArbToEthTransactionHandler (68-409)
  • makeClaim (154-179)
validator-cli/src/utils/claim.ts (2)
  • getClaim (193-193)
  • ClaimHonestState (193-193)
validator-cli/src/utils/graphQueries.ts (1)
  • getLastClaimedEpoch (148-148)
validator-cli/src/utils/ethers.ts (1)
  • getTransactionHandler (133-133)
validator-cli/src/ArbToEth/transactionHandlerDevnet.ts (1)
  • ArbToEthDevnetTransactionHandler (19-71)
validator-cli/src/utils/claim.ts (2)
validator-cli/src/utils/graphQueries.ts (4)
  • getClaimForEpoch (147-147)
  • getVerificationForClaim (149-149)
  • getChallengerForClaim (150-150)
  • getSnapshotSentForEpoch (151-151)
validator-cli/src/utils/errors.ts (1)
  • ClaimNotFoundError (60-60)
validator-cli/src/utils/claim.test.ts (2)
validator-cli/src/utils/graphQueries.ts (2)
  • getVerificationForClaim (149-149)
  • getChallengerForClaim (150-150)
validator-cli/src/utils/claim.ts (1)
  • getClaim (193-193)
validator-cli/src/consts/bridgeRoutes.ts (1)
veascan-web/src/consts/bridges.ts (1)
  • bridges (39-58)
validator-cli/src/ArbToEth/transactionHandler.test.ts (4)
validator-cli/src/ArbToEth/transactionHandler.ts (4)
  • TransactionHandlerConstructor (23-32)
  • ArbToEthTransactionHandler (68-409)
  • MAX_PENDING_CONFIRMATIONS (65-65)
  • Transaction (34-37)
validator-cli/src/utils/emitter.ts (2)
  • MockEmitter (6-14)
  • defaultEmitter (4-4)
validator-cli/src/consts/bridgeRoutes.ts (1)
  • getBridgeConfig (92-92)
validator-cli/src/utils/errors.ts (1)
  • ClaimNotSetError (61-61)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Scorecard analysis
🔇 Additional comments (41)
validator-cli/src/ArbToEth/transactionHandler.test.ts (15)

1-12: Updated imports align with new architecture.

The imports have been properly updated to support multi-network functionality, with the addition of Network and getBridgeConfig from bridgeRoutes. The new TransactionHandlerConstructor interface has been correctly imported to support the refactored constructor parameters.


15-22: LGTM - Test setup with proper chainId value.

Setting the chainId to 11155111 (Sepolia testnet) aligns with the multi-network support objective mentioned in the PR, and the test variables are properly initialized.


22-61: Test setup refactored for parameter object pattern.

The introduction of the transactionHandlerParams object follows good practice by encapsulating all constructor parameters, making the code more maintainable and easier to extend with new parameters in the future.


29-39: Mock setup properly includes new transaction methods.

The mock setup correctly includes all new methods that have been added to the ArbToEthTransactionHandler class (claim, startVerification, verifySnapshot, withdrawClaimDeposit), ensuring comprehensive test coverage for the new functionality.


65-81: Constructor tests updated to use parameter object.

The tests have been properly refactored to use the new transactionHandlerParams object, ensuring that all properties are correctly initialized in both scenarios (with and without a claim).


84-106: Transaction status test updated to use Transaction objects.

The tests now correctly use the Transaction object type with broadcastedTimestamp as required by the updated implementation. The constant MAX_PENDING_CONFIRMATIONS is correctly used for consistency.


148-185: Comprehensive tests for makeClaim functionality.

The new tests for makeClaim cover key scenarios:

  1. Successfully making a claim when no transaction is pending
  2. Not making a claim when a transaction is already pending

The implementation correctly retrieves gas estimates and includes the required deposit value from the bridge configuration.


187-238: Thorough test coverage for startVerification method.

The tests cover all important scenarios:

  1. Successfully starting verification when conditions are met
  2. Not starting when a transaction is already pending
  3. Throwing an error when claim is not set
  4. Not starting when the timeout hasn't passed yet

The test properly uses configuration values from the bridge config to determine the verification flip time.


240-288: Complete test coverage for verifySnapshot method.

Similar to startVerification, these tests thoroughly cover successful verification, pending transaction handling, error cases when claim is not set, and timeout validation. The implementation correctly calculates the verification flip time using the minChallengePeriod from bridge configuration.


290-332: Robust tests for withdrawClaimDeposit functionality.

The tests ensure deposits can be withdrawn when conditions are met, prevent duplicate transactions when a withdrawal is pending, and throw appropriate errors when the claim is not set. This is consistent with the PR's objective of enhancing claimer functionality.


334-380: Tests for challenger path properly refactored.

The tests for challenging claims have been correctly updated to use the new Transaction object format and contract type constants. Error handling for missing claims is properly tested.


380-380: Missing test implementation for final transaction case.

The test.todo entry indicates a planned test for checking when the challenge transaction is completed that hasn't been implemented yet.

Would you like me to implement the missing test case for the "should set challengeTxn as completed when txn is final" scenario?


422-426: Event name updated for consistency.

The test now correctly checks for the WITHDRAWING_CHALLENGE_DEPOSIT event instead of the previously used WITHDRAWING, which makes the event naming more specific and clear about what type of withdrawal is occurring.


429-469: Tests for sendSnapshot properly updated.

The tests have been correctly modified to use the new Transaction object format and properly check ContractType.INBOX. Error handling when claim is not set is also properly tested.


471-502: resolveChallengedClaim tests correctly refactored.

The tests have been properly updated to use the Transaction object format and the correct contract type constant. Both success and pending transaction cases are handled.

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

5-9: Enum usage looks good.
No issues found.


11-14: Interface declaration is concise.
No concerns here.

validator-cli/src/utils/claim.test.ts (7)

56-70: Mocking out claim hashes and parameters.
The approach to mocking outbox calls with mockResolvedValueOnce is sound, ensuring the test focuses on getClaim.


98-99: No issues found with the challenger test.
It cleanly covers challenger data retrieval.


127-129: Sets provider for verification context.
Attaching veaOutboxProvider is appropriate for verifying claims.


135-159: Fallback to subgraphs test is comprehensive.
This effectively simulates a fallback scenario when logs aren’t available on-chain.


163-164: Null claim scenario test is valid.
Ensures getClaim handles missing on-chain data gracefully.


175-180: Throws error when no claim is found.
Logic is correct, verifying that the function properly raises ClaimNotFoundError.


202-202: Checks invalid claim path.
Ensures handling for honest state mismatch.

validator-cli/src/consts/bridgeRoutes.ts (5)

21-22: Added optional routerRPC and routeConfig.
This flexible approach helps unify RPC endpoints and route details.


32-35: Enum for Network.
Straightforward usage; good for clarity among devnet/testnet distinctions.


37-48: ArbToEth configs properly segmented by devnet/testnet.
The epochPeriod difference is intuitive.


50-62: ArbToGnosis configs similarly structured.
Consistent approach with optional veaRouter for testnet.


72-82: RouterRPC usage introduced.
Ensures bridging routes can be expanded as needed for cross-chain calls.

validator-cli/src/ArbToEth/claimer.ts (2)

1-28: CheckAndClaimParams interface is comprehensive.
These optional fetch functions are useful for dependency injection in tests.


83-102: makeClaimDevnet handles devnet logic.
Recognizes new messages vs. zero hash. If conditions are not met, it’s correct to emit NO_CLAIM_REQUIRED.

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

6-11: Imports appear consistent and well-organized.
They streamline access to fallback retrieval methods from graphQueries.


36-45: Good use of destructuring with default fetch functions.
This approach supports dependency injection, making the function more testable and flexible.


115-125: Documentation looks great.
Explicit doc comments for parameters (e.g., fromBlock, toBlock) are helpful for external collaborators.


193-193: Exporting these declarations centralizes functionality effectively.
This organized export provides clarity for importing modules.

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

2-5: Imports for bridging and Ethers utilities are clear and concise.
They align with the subsequent usage in network setup and transaction handling.


10-14: Centralizing configuration imports.
Reading BotPaths, NetworkConfig, and claim param types from separate modules helps keep this file focused on watcher logic.


16-16: Constant naming is descriptive.
RPC_BLOCK_LIMIT is clearly documented, making it easy to adjust if RPC constraints change.


19-19: Doc comment addition.
Adding a high-level explanation about the watcher's purpose benefits maintainability.


40-43: Graceful loop approach.
The while loop and 10s wait cycle ensures minimal overhead for watchers. Reevaluate the interval if more frequent checks are needed.

Also applies to: 45-45


100-172: Effective decomposition into processEpochsForNetwork.
This modular approach keeps processNetwork lean and more testable. The iteration logic for epochs is straightforward.

Comment on lines +58 to +65
try {
const [claimLogs, challengeLogs, verificationLogs] = await Promise.all([
veaOutbox.queryFilter(veaOutbox.filters.Claimed(null, epoch, null), fromBlock, toBlock),
veaOutbox.queryFilter(veaOutbox.filters.Challenged(epoch, null), fromBlock, toBlock),
veaOutbox.queryFilter(veaOutbox.filters.VerificationStarted(epoch), fromBlock, toBlock),
]);
claim.stateRoot = claimLogs[0].data;
claim.claimer = `0x${claimLogs[0].topics[1].slice(26)}`;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Check for empty claimLogs to avoid index out-of-range errors.
If claimLogs is empty, accessing claimLogs[0] will throw an error, bypassing the fallback logic in the catch block.

 try {
   const [claimLogs, ...] = await Promise.all([...]);
-  claim.stateRoot = claimLogs[0].data;
-  claim.claimer = `0x${claimLogs[0].topics[1].slice(26)}`;
+  if (claimLogs.length > 0) {
+    claim.stateRoot = claimLogs[0].data;
+    claim.claimer = `0x${claimLogs[0].topics[1].slice(26)}`;
+  } else {
+    throw new Error("No claim logs found");
+  }
   ...
 } catch {
📝 Committable suggestion

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

Suggested change
try {
const [claimLogs, challengeLogs, verificationLogs] = await Promise.all([
veaOutbox.queryFilter(veaOutbox.filters.Claimed(null, epoch, null), fromBlock, toBlock),
veaOutbox.queryFilter(veaOutbox.filters.Challenged(epoch, null), fromBlock, toBlock),
veaOutbox.queryFilter(veaOutbox.filters.VerificationStarted(epoch), fromBlock, toBlock),
]);
claim.stateRoot = claimLogs[0].data;
claim.claimer = `0x${claimLogs[0].topics[1].slice(26)}`;
try {
const [claimLogs, challengeLogs, verificationLogs] = await Promise.all([
veaOutbox.queryFilter(veaOutbox.filters.Claimed(null, epoch, null), fromBlock, toBlock),
veaOutbox.queryFilter(veaOutbox.filters.Challenged(epoch, null), fromBlock, toBlock),
veaOutbox.queryFilter(veaOutbox.filters.VerificationStarted(epoch), fromBlock, toBlock),
]);
if (claimLogs.length > 0) {
claim.stateRoot = claimLogs[0].data;
claim.claimer = `0x${claimLogs[0].topics[1].slice(26)}`;
} else {
throw new Error("No claim logs found");
}
// ...other code
} catch (error) {
// existing fallback error handling
}

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant