-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat/validator tests #388
base: dev
Are you sure you want to change the base?
feat/validator tests #388
Conversation
WalkthroughThe pull request introduces significant enhancements to the validator CLI, focusing on blockchain bridge monitoring and transaction validation. The changes include new utility functions, improved error handling, and a restructured watcher mechanism for tracking claims and epochs across Arbitrum and Ethereum networks. Key modifications involve updating RPC configurations, adding comprehensive test suites, implementing new transaction handling logic, and creating more robust event logging and state management utilities. Changes
Sequence DiagramsequenceDiagram
participant Watcher
participant EpochHandler
participant ClaimValidator
participant TransactionHandler
participant Blockchain
Watcher->>EpochHandler: Get Challengeable Epochs
EpochHandler-->>Watcher: Return Epoch Range
loop For Each Epoch
Watcher->>ClaimValidator: Check Claim Status
ClaimValidator->>Blockchain: Query Claim
ClaimValidator-->>Watcher: Claim Details
Watcher->>TransactionHandler: Process Claim
TransactionHandler->>Blockchain: Submit Transactions
end
Poem
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
❌ Deploy Preview for veascan failed. Why did it fail? →
|
Quality Gate failedFailed conditions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Nitpick comments (24)
validator-cli/.env.dist (2)
23-23
: Document chain ID and consider grouping with network configurations.The chain ID
421611
corresponds to Arbitrum Sepolia testnet. Consider:
- Adding a comment to document this
- Grouping it with other network-specific configurations
-VEAOUTBOX_CHAIN_ID=421611 +# Chain IDs +VEAOUTBOX_CHAIN_ID=421611 # Arbitrum Sepolia testnet
Line range hint
1-32
: Improve overall file organization and documentation.Consider restructuring the file to group related configurations more logically:
# Authentication PRIVATE_KEY= -# Devnet RPCs -RPC_CHIADO=https://rpc.chiadochain.net -RPC_ARB_SEPOLIA=https://sepolia-rollup.arbitrum.io/rpc -RPC_SEPOLIA= +# Network Configuration +## Chain IDs +ARBITRUM_CHAIN_ID=421611 # Arbitrum Sepolia testnet -# Testnet or Mainnet RPCs -RPC_ARB=https://sepolia-rollup.arbitrum.io/rpc -RPC_ETH= -RPC_GNOSIS=https://rpc.chiadochain.net +## RPC Endpoints +### Testnet +RPC_ARB_TESTNET=https://sepolia-rollup.arbitrum.io/rpc # Arbitrum Sepolia +RPC_ETH_TESTNET= # Ethereum Sepolia +RPC_GNOSIS_TESTNET=https://rpc.chiadochain.net # Gnosis Chiado -# Testnet or Mainnet Addresses -# VEA Arbitrum to Ethereum +# Bridge Configuration +## VEA Arbitrum to Ethereum Bridge VEAINBOX_ARB_TO_ETH_ADDRESS=0xE12daFE59Bc3A996362d54b37DFd2BA9279cAd06 VEAOUTBOX_ARB_TO_ETH_ADDRESS=0x209BFdC6B7c66b63A8382196Ba3d06619d0F12c9 -# VEA Arbitrum to GNOSIS +## VEA Arbitrum to Gnosis Bridge VEAINBOX_ARB_TO_GNOSIS_ADDRESS=0x854374483572FFcD4d0225290346279d0718240b VEAOUTBOX_ARB_TO_GNOSIS_ADDRESS=0x2f1788F7B74e01c4C85578748290467A5f063B0b VEAROUTER_ARB_TO_GNOSIS_ADDRESS=0x5BE03fDE7794Bc188416ba16932510Ed1277b193 GNOSIS_AMB_ADDRESS=0x8448E15d0e706C0298dECA99F0b4744030e59d7d -VEAOUTBOX_CHAIN_ID=421611 - -# Devnet Addresses +# Transaction Batcher Configuration VEAINBOX_ARBSEPOLIA_TO_SEPOLIA_ADDRESS=0x906dE43dBef27639b1688Ac46532a16dc07Ce410 VEAOUTBOX_ARBSEPOLIA_TO_SEPOLIA_ADDRESS=0x906dE43dBef27639b1688Ac46532a16dc07Ce410 - - TRANSACTION_BATCHER_CONTRACT_ADDRESS_SEPOLIA=0xe7953da7751063d0a41ba727c32c762d3523ade8 TRANSACTION_BATCHER_CONTRACT_ADDRESS_CHIADO=0xcC0a08D4BCC5f91ee9a1587608f7a2975EA75d73validator-cli/src/watcher.ts (2)
31-54
: Be cautious with array splicing during iteration.Inside the nested loop, you’re removing elements from
epochRange
usingsplice(i, 1)
while incrementingi
. Though you decrementi
in that same branch, this pattern can still become error-prone if any new logic is added or altered. Consider simplifying iteration logic to reduce the risk of off-by-one errors or unexpected skips.
66-66
: Add an explicit type annotation for thems
parameter.Explicitly annotate the parameter type (e.g.,
ms: number
) to enhance readability and ensure type safety, especially if you plan to share or reuse this utility function.validator-cli/src/utils/claim.ts (2)
29-40
: Unify the approach when no claim is found.Returning
null
on line 30 versus throwingClaimNotFoundError
on line 38 may confuse callers relying on a single code path. Consider consistently handling the “no claim found” state to avoid ambiguity in upstream logic.
52-63
: Revisit the logic assigning thehonest
field.Assigning
claim.honest = 1
or2
tries to guess which party is honest and then re-hashes. This approach might become brittle if more than two possibilities or additional states are introduced. Consider a dedicated function or an enumerated type for claim plausibility to improve extensibility.validator-cli/src/ArbToEth/transactionHandler.ts (2)
34-34
: Avoid hard-coding the chain ID in the class.Storing
chainId = 11155111
directly in the class might require multiple code edits if you expand to other networks. PasschainId
as a constructor parameter or retrieve it from a configuration to ensure flexibility and maintainability.
76-105
: Clarify return semantics ofcheckTransactionStatus
.Currently, returning
true
signifies the transaction is pending or not final, whilefalse
means it is fully confirmed. This can be confusing for consumers of the function. Consider inverting the return value or renaming the method to more explicitly convey thattrue
means “still in progress.”validator-cli/src/utils/arbToEthState.ts (1)
56-58
: Potentially large block range queries.
fromBlockEthFinalized
is computed in a way that may result in scanning a large range on the Ethereum chain. Ensure these queries are optimized or batched to handle mainnet-scale data efficiently.validator-cli/src/utils/shutdown.ts (3)
4-4
: Consider using a more descriptive class nameWhile
ShutdownSignal
is acceptable, a more explicit name likeShutdownManager
orShutdownController
could improve readability and clarity of purpose in the codebase.
11-13
: Use a conventional boolean accessor name“
getIsShutdownSignal
” works, but adopting a name like “isShutdownRequested
” or “isShutdown
” can make the code more readable and standard.- public getIsShutdownSignal(): boolean { + public isShutdown(): boolean { return this.isShutdownSignal; }
15-17
: Add logging or hooks to facilitate debuggingSetting the shutdown signal indicates a key transition. Consider adding logging or optional callback hooks to help debug or manage shutdown lifecycle events.
validator-cli/src/utils/emitter.ts (1)
9-9
: Optimize repeated calls toObject.values(...)
for performanceRepeatedly calling
Object.values(BotEvents).includes(event)
can introduce overhead in large-scale or frequent event emissions. Consider using aSet
of allowed events for more efficient lookups, if performance becomes critical.+const botEventsSet = new Set(Object.values(BotEvents)); export class MockEmitter extends EventEmitter { emit(event: string | symbol, ...args: any[]): boolean { - if (Object.values(BotEvents).includes(event as BotEvents)) { + if (botEventsSet.has(event as BotEvents)) { return true; } return super.emit(event, ...args); } }validator-cli/src/utils/errors.ts (1)
1-7
: Pass the message directly tosuper(...)
By passing the error message directly into
super(...)
, you preserve stack traces more seamlessly. Assigningthis.message
works, but it’s often safer to rely on the parent class constructor.class ClaimNotFoundError extends Error { constructor(epoch: number) { - super(); - this.name = "ClaimNotFoundError"; - this.message = `No claim was found for ${epoch}`; + super(`No claim was found for ${epoch}`); + this.name = "ClaimNotFoundError"; } }validator-cli/src/utils/botEvents.ts (1)
19-19
: Normalize naming conventionThe enum key
CANT_EXECUTE_SNAPSHOT
is capitalized differently than others (most are lowercase snake case). Consider unifying naming conventions to maintain code consistency.- CANT_EXECUTE_SNAPSHOT = "CANT_EXECUTE_SNAPSHOT", + CANT_EXECUTE_SNAPSHOT = "cant_execute_snapshot",validator-cli/src/consts/bridgeRoutes.ts (1)
1-15
: Consider adding a fallback or sanity check if environment variables are undefined.While upper layers may handle errors, undefined environment variables can lead to runtime issues. A short check or fallback can make the code more resilient, especially in production environments.
- ... + if (!process.env.RPC_ARB || !process.env.RPC_ETH) { + console.warn("Required RPC environment variables are missing. The bridge configuration might be incomplete."); + } ...Also applies to: 17-42
validator-cli/src/utils/epochHandler.test.ts (1)
34-35
: Validate the rounding operation in the new test.When the function returns
Math.floor(now / (600 * 1000)) - 2
, confirm that integer division is the desired approach. If partial epochs are relevant, the floor might skip potentially challengeable epochs close to transition boundaries.validator-cli/src/utils/epochHandler.ts (2)
9-9
: Handle missing or invalid bridge configuration.If
fetchBridgeConfig(chainId)
returnsundefined
or missing fields, it may cause a runtime error. Even though upstream layers might already validate, a graceful early return can improve maintainability and debugging.- const { sequencerDelayLimit, epochPeriod } = fetchBridgeConfig(chainId); + const config = fetchBridgeConfig(chainId); + if (!config) { + throw new Error(`Bridge config not found for chainId: ${chainId}`); + } + const { sequencerDelayLimit, epochPeriod } = config;
49-51
: Consider adding a fallback for missing epochPeriod.If
epochPeriod
is missing or invalid, this could produce unexpected results. A short check would help avoid silent failures.validator-cli/src/utils/arbMsgExecutor.ts (1)
42-43
: Log or handle the scenario for missing messages more explicitly.Currently, a console error is printed if no messages are found. You might want to throw an exception (similar to
messageExecutor
) or return a fallback status to ensure consistent error handling.- console.error("No child-to-parent messages found"); + throw new Error("No child-to-parent messages found");Also applies to: 55-55
validator-cli/src/utils/ethers.ts (2)
41-45
: Consider multi-chain logic expansion
getVeaRouter
only returns the router for chain ID10200
. If future expansions add new router addresses for other networks, you may want to extend or centralize the chain-based logic.
52-53
: Naming consistency for Devnet
getVeaOutboxArbToEthDevnet
is specialized. If you add more devnet functions, ensure naming is consistent and consider a unified approach for dev/test networks.validator-cli/src/utils/logger.ts (1)
1-99
: Add log levels or verbosity control
While the logger is straightforward, consider introducing standard log levels (e.g., debug, info, warn, error) for more granular control during production. This can help reduce noise and streamline debugging.export const configurableInitialize = (emitter: EventEmitter) => { // Bridger state logs emitter.on(BotEvents.STARTED, () => { - console.log("Validator started"); + console.info("[STARTED] Validator started"); }); // ... }validator-cli/src/ArbToEth/validator.test.ts (1)
1-219
: Comprehensive tests
The tests forchallengeAndResolveClaim
methodically verify each scenario. For concurrency or race conditions (e.g., multiple challenges in quick succession), you might want to add further scenario coverage or concurrency safety checks if relevant.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (22)
validator-cli/.env.dist
(1 hunks)validator-cli/jest.config.ts
(1 hunks)validator-cli/package.json
(2 hunks)validator-cli/src/ArbToEth/transactionHandler.test.ts
(1 hunks)validator-cli/src/ArbToEth/transactionHandler.ts
(1 hunks)validator-cli/src/ArbToEth/validator.test.ts
(1 hunks)validator-cli/src/ArbToEth/validator.ts
(1 hunks)validator-cli/src/ArbToEth/watcherArbToEth.ts
(0 hunks)validator-cli/src/consts/bridgeRoutes.ts
(1 hunks)validator-cli/src/utils/arbMsgExecutor.ts
(3 hunks)validator-cli/src/utils/arbToEthState.ts
(1 hunks)validator-cli/src/utils/botEvents.ts
(1 hunks)validator-cli/src/utils/claim.test.ts
(1 hunks)validator-cli/src/utils/claim.ts
(1 hunks)validator-cli/src/utils/emitter.ts
(1 hunks)validator-cli/src/utils/epochHandler.test.ts
(1 hunks)validator-cli/src/utils/epochHandler.ts
(1 hunks)validator-cli/src/utils/errors.ts
(1 hunks)validator-cli/src/utils/ethers.ts
(2 hunks)validator-cli/src/utils/logger.ts
(1 hunks)validator-cli/src/utils/shutdown.ts
(1 hunks)validator-cli/src/watcher.ts
(1 hunks)
💤 Files with no reviewable changes (1)
- validator-cli/src/ArbToEth/watcherArbToEth.ts
✅ Files skipped from review due to trivial changes (1)
- validator-cli/jest.config.ts
🧰 Additional context used
📓 Learnings (6)
validator-cli/src/utils/epochHandler.ts (1)
Learnt from: mani99brar
PR: kleros/vea#370
File: bridger-cli/src/utils/epochHandler.ts:13-24
Timestamp: 2024-12-10T08:26:12.411Z
Learning: In `bridger-cli/src/utils/epochHandler.ts`, the `setEpochRange` function does not require validation checks for `startEpoch` being non-negative or the epoch range being too large because the upper layer ensures `startEpoch` is always valid and the epoch range is appropriately managed.
validator-cli/.env.dist (1)
Learnt from: madhurMongia
PR: kleros/vea#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.
validator-cli/src/utils/arbMsgExecutor.ts (1)
Learnt from: madhurMongia
PR: kleros/vea#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.
validator-cli/src/utils/epochHandler.test.ts (1)
Learnt from: mani99brar
PR: kleros/vea#370
File: bridger-cli/src/utils/epochHandler.ts:13-24
Timestamp: 2024-12-10T08:26:12.411Z
Learning: In `bridger-cli/src/utils/epochHandler.ts`, the `setEpochRange` function does not require validation checks for `startEpoch` being non-negative or the epoch range being too large because the upper layer ensures `startEpoch` is always valid and the epoch range is appropriately managed.
validator-cli/src/utils/ethers.ts (1)
Learnt from: mani99brar
PR: kleros/vea#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.
validator-cli/src/consts/bridgeRoutes.ts (1)
Learnt from: mani99brar
PR: kleros/vea#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.
🪛 Biome (1.9.4)
validator-cli/src/utils/arbToEthState.ts
[error] 18-18: Don't use 'Boolean' as a type.
Use lowercase primitives for consistency.
Safe fix: Use 'boolean' instead
(lint/complexity/noBannedTypes)
🔇 Additional comments (17)
validator-cli/.env.dist (1)
14-21
: Verify bridge contract addresses and checksum format.The contract addresses need to be verified for correctness and proper checksum format.
Run the following script to validate the addresses:
✅ Verification successful
Let me gather more information about these addresses by checking for any configuration or documentation files that might help verify them.
Let me check the deployment files to verify these addresses.
Based on the verification results, I can now provide the final response:
✓ Contract addresses verified and properly checksummed
All addresses in the
.env.dist
file have been verified:
VEA Arbitrum to Ethereum:
- VeaInboxArbToEth (0xE12daFE59Bc3A996362d54b37DFd2BA9279cAd06) - Found in deployment files and properly checksummed
- VeaOutboxArbToEth (0x209BFdC6B7c66b63A8382196Ba3d06619d0F12c9) - Found in deployment files and properly checksummed
VEA Arbitrum to GNOSIS:
- VeaInboxArbToGnosis (0x854374483572FFcD4d0225290346279d0718240b) - Found in deployment files and properly checksummed
- VeaOutboxArbToGnosis (0x2f1788F7B74e01c4C85578748290467A5f063B0b) - Found in deployment files and properly checksummed
- VeaRouterArbToGnosis (0x5BE03fDE7794Bc188416ba16932510Ed1277b193) - Found in deployment files
- GnosisAMB (0x8448E15d0e706C0298dECA99F0b4744030e59d7d) - Found in deployment configuration
All addresses are properly checksummed and match the deployed contract addresses in the deployment files.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify contract addresses exist and are properly checksummed # Function to check if address is properly checksummed using web3 check_addresses() { while IFS='=' read -r key value; do if [[ $value =~ ^0x[a-fA-F0-9]{40}$ ]]; then echo "Checking $key: $value" # Use ast-grep to find any references to this address in the codebase ast-grep --pattern "$value" fi done } # Extract and check all contract addresses grep -E "^VEA.*ADDRESS=" validator-cli/.env.dist | check_addresses grep "GNOSIS_AMB_ADDRESS" validator-cli/.env.dist | check_addressesLength of output: 2940
Script:
#!/bin/bash # Search for documentation or configuration files that might contain these addresses echo "Searching for documentation files..." fd -e md -e txt -e json echo -e "\nSearching for address references in markdown files..." rg -i "0x[a-fA-F0-9]{40}" -t md echo -e "\nChecking for deployment or configuration files..." fd -e yaml -e yml -e json -e config echo -e "\nSearching for any test files that might use these addresses..." fd -e test.js -e test.ts -e spec.js -e spec.tsLength of output: 5977
Script:
#!/bin/bash # Check deployment files for the addresses echo "Checking VEA Arbitrum to Ethereum addresses..." for addr in "0xE12daFE59Bc3A996362d54b37DFd2BA9279cAd06" "0x209BFdC6B7c66b63A8382196Ba3d06619d0F12c9"; do rg -l "$addr" contracts/deployments/ done echo -e "\nChecking VEA Arbitrum to GNOSIS addresses..." for addr in "0x854374483572FFcD4d0225290346279d0718240b" "0x2f1788F7B74e01c4C85578748290467A5f063B0b" "0x5BE03fDE7794Bc188416ba16932510Ed1277b193" "0x8448E15d0e706C0298dECA99F0b4744030e59d7d"; do rg -l "$addr" contracts/deployments/ done echo -e "\nChecking contract addresses in deployment files..." cat contracts/deployments/arbitrumSepolia/VeaInboxArbToEthTestnet.json contracts/deployments/arbitrumSepolia/VeaOutboxArbToEthTestnet.json 2>/dev/null || trueLength of output: 50414
validator-cli/src/watcher.ts (1)
68-71
: LGTM for the module entrypoint condition.The approach correctly prevents
watch()
from being auto-invoked when the file is imported rather than run directly. No issues spotted here.validator-cli/src/ArbToEth/validator.ts (1)
63-65
: Verify concurrency handling on claim challenges.When
claimSnapshot != claim.stateRoot && claim.challenger == ethers.ZeroAddress
, multiple watchers or parallel instances could attempt to initiate a challenge simultaneously. Ensure the contract handles concurrency gracefully—otherwise, subsequent attempts might throw or revert.✅ Verification successful
Let me search for more information about the contract implementation and challenge handling.
Let me search for the contract implementation to understand how challenges are handled.
Let me try a different search pattern to find the challenge claim implementation.
Let me search for the contract's challenge handling implementation.
Let me search for the transaction handler's challenge implementation with a different pattern.
Let me search for more context about the contract's challenge handling and concurrency protection.
Based on the code analysis, I can now provide the final response:
Concurrency is handled safely through state checks in the contract
The contract's
_challenge
function has built-in protection against concurrent challenges through state checks:
- It verifies
_claim.challenger == address(0)
to ensure the claim hasn't already been challenged- It checks
_claim.honest == Party.None
to confirm the claim hasn't been verified- The state updates are atomic within the transaction, updating both the challenger address and claim hash
These checks ensure that only the first challenge transaction will succeed, while subsequent concurrent challenge attempts will revert with "Claim already challenged." This makes it safe for multiple watchers to attempt challenges simultaneously.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for all invocations of 'challengeAndResolveClaim' to see if concurrency is managed at the call sites. rg -A 5 "challengeAndResolveClaim"Length of output: 4730
Script:
#!/bin/bash # Search for the contract implementation of challengeClaim ast-grep --pattern 'function challengeClaim($$$)' # Search for the transaction handler implementation rg -A 10 "class ArbToEthTransactionHandler" # Search for any race condition handling or mutex patterns rg -i "mutex|lock|concurrent|race"Length of output: 83715
Script:
#!/bin/bash # Search for the contract implementation rg -A 10 "function challengeClaim" # Search for the transaction handler implementation rg -A 10 "async function challengeClaim"Length of output: 79
Script:
#!/bin/bash # Search for the transaction handler implementation rg -A 10 "class ArbToEthTransactionHandler" # Search for challenge-related functions in the transaction handler ast-grep --pattern 'async function $FUNC($$$) { $$$ }' --pattern-ids FUNC=challengeClaim # Look for the contract implementation rg -A 10 "VeaOutboxArbToEth"Length of output: 69776
Script:
#!/bin/bash # Search for the contract's challenge implementation rg -A 10 "function challenge" # Search for the transaction handler's challenge implementation rg -A 10 "async function challengeClaim" validator-cli/src/ArbToEth/transactionHandler.tsLength of output: 68762
Script:
#!/bin/bash # Search for the transaction handler's challenge implementation rg -A 10 "challengeClaim" validator-cli/src/ArbToEth/transactionHandler.ts # Search for the contract's challenge handling rg -A 10 "function _challenge" contracts/src/arbitrumToEth/VeaOutboxArbToEth.solLength of output: 1159
Script:
#!/bin/bash # Search for the contract's challenge event and state changes rg -A 10 "event Challenged" contracts/src/arbitrumToEth/VeaOutboxArbToEth.sol # Search for any mutex or lock patterns in the contract rg -A 10 "mapping.*=>.*challenger" contracts/src/arbitrumToEth/VeaOutboxArbToEth.sol # Search for the transaction handler's challenge implementation rg -A 20 "challengeClaim" validator-cli/src/ArbToEth/transactionHandler.tsLength of output: 1784
validator-cli/src/utils/epochHandler.test.ts (1)
20-23
: Double-check edge cases for large epoch ranges.The test ensures the correct range for typical epoch values. However, consider adding a test for extremely large
currentEpoch
or situations wherestartEpoch
might approach zero. Even if upper layers typically guard this, extra coverage can prevent future regressions.validator-cli/src/utils/epochHandler.ts (1)
21-30
: Verify correctness of epoch calculation logic.The final array includes epochs up to
veaEpochOutboxClaimableNow - 1
. Make sure that's the intended boundary. Off-by-one errors are common in epoch-based logic, so confirm that you don’t miss or overshoot the desired final epoch.✅ Verification successful
Let me gather more information about the epoch calculation logic and its usage.
Based on the test file and implementation details gathered, I can now provide the final response:
The epoch calculation logic is correctly implemented
The epoch boundary calculation in
setEpochRange
is correct and intentional. Here's why:
- The test file explicitly verifies that
result[result.length - 1]
equalscurrentEpoch - 1
- This aligns with the system's design where:
- Only past epochs are claimable (as noted in the code comment)
- The epoch calculation uses floor division and subtracts 1 to ensure we're working with completed epochs
- The contract deployment configurations (found in deploy files) show this is consistent across different chains with varying epoch periods (e.g., 600s for devnet, 1800s for testnet, 7200s for mainnet)
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Checking for usage of setEpochRange beyond tests to confirm alignment with epoch boundaries rg -A 8 'setEpochRange'Length of output: 3979
Script:
#!/bin/bash # Check the test file to understand the expected behavior cat validator-cli/src/utils/epochHandler.test.ts # Look for any other files that might be using or defining epoch-related constants rg "epochPeriod|sequencerDelayLimit" -A 3Length of output: 76918
validator-cli/src/utils/arbMsgExecutor.ts (1)
13-17
: Clarify which message is being executed.Only the first child-to-parent message (
messages[0]
) is handled. If multiple messages exist, these lines ignore subsequent messages. Is that intentional? If not, consider iterating through all messages or clarifying why only the first one matters.validator-cli/src/utils/ethers.ts (5)
12-13
: Confirm usage of chain-specific imports
The imports forchallengeAndResolveClaimArbToEth
andArbToEthTransactionHandler
appear correct; just ensure they're needed only for chain 11155111 to avoid confusion.
48-49
: No concerns found
ThegetWETH
function looks straightforward and matches established patterns.
76-83
: Good to export
Exporting all utility functions centrally is helpful; this looks consistent and well-organized.
23-29
: Handle unsupported chain IDs
ThegetVeaInbox
function only handles chain IDs11155111
and10200
. For any other chain ID, no inbox is returned, which can lead to silent failures if a different chain ID is passed. Consider throwing an error or logging a warning for better visibility.function getVeaInbox(veaInboxAddress: string, privateKey: string, web3ProviderURL: string, chainId: number) { switch (chainId) { case 11155111: return VeaInboxArbToEth__factory.connect(veaInboxAddress, getWallet(privateKey, web3ProviderURL)); case 10200: return VeaInboxArbToGnosis__factory.connect(veaInboxAddress, getWallet(privateKey, web3ProviderURL)); + default: + throw new Error(`Chain ID ${chainId} is not supported for getVeaInbox`); } }
60-65
: Verify chain-specific validators
getClaimValidator
only explicitly supports chain ID11155111
. If other networks might require a claim validator, consider adding explicit error handling or more logic.+ default: + throw new Error(`No claim validator configured for chain ID: ${chainId}`);validator-cli/src/utils/claim.test.ts (1)
1-188
: Thorough test coverage
Your tests cover multiple scenarios, including valid claims, challengers, and verification. This level of detail is excellent. Consider adding boundary cases such as extreme block timestamps or network failures if feasible.validator-cli/src/ArbToEth/transactionHandler.test.ts (2)
126-130
: Good Null Transaction HandlingThe test correctly ensures that a
null
transaction hash immediately yields a non-final status without errors.
176-176
: Complete or Remove the TODO TestThere is a pending
it.todo("should set challengeTxn as completed when txn is final")
. To ensure full coverage, either implement the test or remove the TODO if it's no longer needed.Would you like me to open a new issue to track this?
validator-cli/package.json (3)
13-17
: Confirm Updated Entry Point and Watcher ConsistencyThe
start
script has moved from./src/ArbToEth/watcher.ts
to./src/watcher.ts
. Verify that any references to the old watcher file have been updated for consistent entry points.
18-18
: New Test Script AddedThe
test
script ("jest --coverage"
) is a good addition. It improves confidence in changes by measuring test coverage.
32-34
: Jest Dependencies Look GoodAdding
@types/jest
,jest
, andts-jest
ensures a proper TypeScript testing environment.
RPC_ARB=https://sepolia-rollup.arbitrum.io/rpc | ||
RPC_ETH= | ||
RPC_GNOSIS=https://rpc.chiadochain.net |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consolidate duplicate RPC endpoints.
The same RPC URLs are defined multiple times:
RPC_ARB_SEPOLIA
andRPC_ARB
both point tohttps://sepolia-rollup.arbitrum.io/rpc
RPC_CHIADO
andRPC_GNOSIS
both point tohttps://rpc.chiadochain.net
Consider consolidating these into single variables with clear naming to avoid confusion:
# Testnet RPCs
-RPC_ARB=https://sepolia-rollup.arbitrum.io/rpc
+RPC_ARB_TESTNET=https://sepolia-rollup.arbitrum.io/rpc # Arbitrum Sepolia
-RPC_GNOSIS=https://rpc.chiadochain.net
+RPC_GNOSIS_TESTNET=https://rpc.chiadochain.net # Gnosis Chiado
📝 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.
RPC_ARB=https://sepolia-rollup.arbitrum.io/rpc | |
RPC_ETH= | |
RPC_GNOSIS=https://rpc.chiadochain.net | |
# Testnet RPCs | |
RPC_ARB_TESTNET=https://sepolia-rollup.arbitrum.io/rpc # Arbitrum Sepolia | |
RPC_ETH= | |
RPC_GNOSIS_TESTNET=https://rpc.chiadochain.net # Gnosis Chiado |
ArbProvider: JsonRpcProvider, | ||
veaEpoch: number, | ||
veaEpochPeriod: number | ||
): Promise<[Block, Block, Boolean] | undefined> => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use boolean
instead of Boolean
.
Per the static analysis hint, prefer lowercase boolean
over the uppercase Boolean
in the return type for consistency and best practices.
-): Promise<[Block, Block, Boolean] | undefined> => {
+): Promise<[Block, Block, boolean] | undefined> => {
📝 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.
): Promise<[Block, Block, Boolean] | undefined> => { | |
): Promise<[Block, Block, boolean] | undefined> => { |
🧰 Tools
🪛 Biome (1.9.4)
[error] 18-18: Don't use 'Boolean' as a type.
Use lowercase primitives for consistency.
Safe fix: Use 'boolean' instead
(lint/complexity/noBannedTypes)
class ContractNotSupportedError extends Error { | ||
constructor(contract: string) { | ||
super(); | ||
this.name = "ContractNotSupportedError"; | ||
this.message = `Unsupported contract type: ${contract}`; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Based on the search results, I can now provide a final response:
Custom error handling needs to be implemented for ContractNotSupportedError
While ClaimNotSetError
and ClaimNotFoundError
are properly used and handled in the codebase (in transactionHandler.ts
, claim.ts
, and their respective test files), there are no visible usages or error handling patterns for ContractNotSupportedError
. This error class is defined but appears to be unused, which could lead to unhandled exceptions if it's thrown anywhere in the codebase.
- Consider implementing proper error handling for
ContractNotSupportedError
where contract type validations occur - If this error class is not being used, consider removing it to maintain clean code
🔗 Analysis chain
Confirm consistent handling of custom errors
Ensure that other parts of the application catch and handle ContractNotSupportedError
(and the other new errors) appropriately to prevent unhandled exceptions.
Let me try a different approach to verify the error handling.
Let me try one more search to check for error handling patterns.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Searches for catch blocks or explicit error handling for each custom error class
rg "catch" -A 5 | rg "ContractNotSupportedError|ClaimNotFoundError|ClaimNotSetError"
Length of output: 84
Script:
#!/bin/bash
# Search for any usage or references of the custom error classes
rg "ContractNotSupportedError|ClaimNotFoundError|ClaimNotSetError" -A 3
# Also search for error handling patterns in TypeScript files
rg "try\s*{" -t ts -A 10
Length of output: 5956
Script:
#!/bin/bash
# Search for try-catch blocks in TypeScript files
rg "try {" -t ts -A 10
# Search for any direct references to ContractNotSupportedError
rg "ContractNotSupportedError" -A 3 -B 3
Length of output: 838
routerAddress?: string; | ||
roueterProvider?: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct the spelling of "roueterProvider".
There's a potential typo in the property name roueterProvider
and its usage. Consider renaming it to routerProvider
to maintain consistency and clarity.
Apply this diff to fix the property name:
- roueterProvider?: string;
+ routerProvider?: string;
And update its usage:
- roueterProvider: process.env.RPC_ETH,
+ routerProvider: process.env.RPC_ETH,
Also applies to: 37-37
function getVeaOutbox(veaOutboxAddress: string, privateKey: string, web3ProviderURL: string, chainId: number) { | ||
switch (chainId) { | ||
case 11155111: | ||
return VeaOutboxArbToEth__factory.connect(veaOutboxAddress, getWallet(privateKey, web3ProviderURL)); | ||
case 10200: | ||
return VeaOutboxArbToGnosis__factory.connect(veaOutboxAddress, getWallet(privateKey, web3ProviderURL)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Ensure uniform chain ID handling in outbox
Similar to getVeaInbox
, this switch statement only covers two chain IDs. Consider handling other chain IDs or at least providing a fallback error.
const getTransactionHandler = (chainId: number) => { | ||
switch (chainId) { | ||
case 11155111: | ||
return ArbToEthTransactionHandler; | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Based on the search results, I can now provide a final response:
Add default error case for unsupported chain IDs
The codebase shows that chain ID 10200 is supported in other switch statements for VeaInbox and VeaOutbox connections, but getTransactionHandler
only handles 11155111 (Sepolia) without any error handling for unsupported chains. Adding a default case is necessary for consistent error handling across the codebase.
validator-cli/src/utils/ethers.ts
: Add default case to handle unsupported chain IDs ingetTransactionHandler
+ default:
+ throw new Error(`No transaction handler configured for chain ID: ${chainId}`);
🔗 Analysis chain
Confirm transaction handler coverage
getTransactionHandler
only covers chain ID 11155111
. If other networks need transaction handling, add separate implementations or an error.
+ default:
+ throw new Error(`No transaction handler configured for chain ID: ${chainId}`);
Let me gather information about transaction handlers and chain IDs in the codebase.
Let me search for more specific information about transaction handlers and chain support.
🏁 Scripts executed
The following scripts were executed for the analysis:
Error: No shell scripts found
Script:
#!/bin/bash
# Search for chain ID references and transaction handlers
rg -A 5 "chainId.*11155111|case.*11155111"
# Look for other transaction handler implementations
ast-grep --pattern 'class $_TransactionHandler'
# Search for imports of transaction handlers
rg "import.*TransactionHandler"
Length of output: 4072
Script:
#!/bin/bash
# Look for other chain IDs in switch statements
rg -A 3 "switch.*chainId"
# Search for other TransactionHandler implementations
fd -e ts -e js transactionHandler
# Look for any error handling related to unsupported chains
rg "throw.*chain.*[Ii]nvalid|throw.*chain.*support"
Length of output: 1841
it("should return false if transaction is not final", async () => { | ||
jest.spyOn(mockEmitter, "emit"); | ||
veaInboxProvider.getTransactionReceipt.mockResolvedValue({ | ||
blockNumber: finalityBlock - (transactionHandler.requiredConfirmations - 1), | ||
}); | ||
const trnxHash = "0x123456"; | ||
const status = await transactionHandler.checkTransactionStatus(trnxHash, ContractType.INBOX); | ||
expect(status).toBeTruthy(); | ||
expect(mockEmitter.emit).toHaveBeenCalledWith( | ||
BotEvents.TXN_NOT_FINAL, | ||
trnxHash, | ||
transactionHandler.requiredConfirmations - 1 | ||
); | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mismatch Between Test Name and Assertions
The test title says "should return false if transaction is not final", but it checks expect(status).toBeTruthy()
. This contradictory behavior can confuse maintainers.
Use one of the following fixes to align the test name or logic:
-it("should return false if transaction is not final", async () => {
+it("should return true if transaction is not final", async () => {
Or invert the assertion:
-expect(status).toBeTruthy();
+expect(status).toBeFalsy();
Committable suggestion skipped: line range outside the PR's diff.
PR-Codex overview
This PR introduces significant updates to the
validator-cli
project, including the addition of new classes, error handling, event logging, and refactoring of existing functions to enhance the functionality of the Arbitrum to Ethereum bridge.Detailed summary
ShutdownSignal
class for shutdown management.BotEvents
enum for event handling.ClaimNotFoundError
,ClaimNotSetError
,ContractNotSupportedError
.setEpochRange
andgetLatestChallengeableEpoch
functions.messageExecutor
function to useJsonRpcProvider
.package.json
with Jest configuration and dependencies.initialize
function for event emissions.challengeAndResolveClaim
function for claim validation.Summary by CodeRabbit
Release Notes
New Features
Improvements
Infrastructure
Chores