Skip to content

Validate duplicate addresses in config at parse time#1311

Merged
DZakh merged 3 commits into
mainfrom
claude/zealous-allen-phvjxy
Jun 11, 2026
Merged

Validate duplicate addresses in config at parse time#1311
DZakh merged 3 commits into
mainfrom
claude/zealous-allen-phvjxy

Conversation

@DZakh

@DZakh DZakh commented Jun 11, 2026

Copy link
Copy Markdown
Member

Summary

Add validation to detect and reject duplicate addresses in config files at parse time, preventing opaque database constraint violations at runtime. The same address cannot be configured for multiple contracts on the same chain, nor can it be listed twice for a single contract. However, the same address is allowed across different chains.

Key Changes

  • Rust validation (packages/cli/src/config_parsing/validation.rs): Added address deduplication check per chain that rejects:

    • Same address under two different contracts on one chain
    • Same address listed twice for one contract (case-insensitive)
    • Allows same address on different chains
    • Includes comprehensive test coverage for all three scenarios
  • ReScript config parsing (packages/envio/src/Config.res): Added parallel validation during fromPublic to catch address conflicts before they reach the database, with clear error messages indicating the offending address, chain, and contract(s)

  • Dynamic contract registration (packages/envio/src/FetchState.res): Enhanced batch-level conflict detection to track all addresses being registered in a single batch (across contracts), ensuring two contracts cannot register the same address within one batch. Includes handling for conflicts between events and no-events registrations.

  • Test coverage (scenarios/test_codegen/test/Config_test.res, scenarios/test_codegen/test/lib_tests/FetchState_test.res): Added tests validating:

    • Rejection of same address on two contracts in one chain
    • Rejection of duplicate address for one contract
    • Allowance of same address on different chains
    • Batch-level conflict detection for dynamic contracts

Implementation Details

  • Address comparison is case-insensitive (checksum and lowercase spellings are treated as the same address) to match the database primary key behavior on (chainId, address)
  • Error messages clearly distinguish between the two failure modes (same contract vs. different contracts) to guide users toward the correct fix
  • Validation occurs at config load time in both the Rust CLI and ReScript runtime, providing early feedback

https://claude.ai/code/session_01Ga6MwYHPWo6GbqPdkPYrMy

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Configuration validation now enforces address uniqueness per chain, preventing duplicate contract addresses on the same chain while allowing reuse across different chains.
    • Dynamic contract registration improved to detect and resolve address conflicts within registration batches.
  • Tests

    • Added test coverage for address uniqueness validation and conflict resolution in configurations and dynamic contract registrations.

claude added 2 commits June 11, 2026 10:50
The same address under two contract definitions (or listed twice under
one) on a single chain violated the (chainId, address) primary key of
envio_addresses at storage init, surfacing only on deploy as an opaque
'duplicate key value violates unique constraint "envio_addresses_pkey"'
with no hint of the offending address or contracts.

Validate at config parse time in the CLI (codegen fails fast) and again
in Config.fromPublic as a runtime safety net for non-EVM ecosystems and
stale codegen output, naming the chain, address, and contract pair.

https://claude.ai/code/session_01Ga6MwYHPWo6GbqPdkPYrMy
registerDynamicContracts already warned and skipped a dynamic contract
whose address was owned by another contract on fetchState.indexingAddresses,
but the same-batch guard was dead code: it looked the address up in the
per-contract dict keyed by the DC's own contract name, where a different
contract name can never appear. Two contracts registering the same fresh
address within one batch were both accepted — the address landed in both
contracts' partitions while only one row survived in envio_addresses.
Conflicts between events and no-events contracts in one batch slipped
through the same way.

Track a batch-level address dict across all contracts (including no-events
ones) and consult it from both registration paths, so in-batch conflicts
get the same warn-and-skip treatment as conflicts against indexingAddresses.

https://claude.ai/code/session_01Ga6MwYHPWo6GbqPdkPYrMy
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This PR enforces address uniqueness constraints per chain across config parsing and dynamic contract registration layers. Rust EVM validation, ReScript config loading, and runtime batch registration now consistently reject duplicate or conflicting addresses on the same chain while permitting reuse across different chains.

Changes

Address Uniqueness Validation Per Chain

Layer / File(s) Summary
Rust EVM config validation
packages/cli/src/config_parsing/validation.rs
Per-chain duplicate address detection using lowercased address mapping. Rejects same address for different contracts or duplicated within one contract on the same chain. EVM validation test suite covers rejection for cross-contract and case-insensitive duplicates, plus acceptance across chains.
ReScript Config parsing and per-chain validation
packages/envio/src/Config.res, scenarios/test_codegen/test/Config_test.res
SVM accountFilters schema and svmAbi type annotations are clarified into explicit multi-line record shapes. Config.fromPublic adds per-chain address uniqueness validation that builds a canonical address-to-contract-name map and throws targeted errors for duplicates or conflicts. Config tests assert rejection for same address across different contracts on a chain, rejection for duplicate addresses within a single contract, and acceptance when the same address is used on different chains.
FetchState dynamic batch registration
packages/envio/src/FetchState.res, scenarios/test_codegen/test/lib_tests/FetchState_test.res
registerDynamicContracts now tracks all batch-registered addresses in a registeringAddresses dictionary to detect same-batch conflicts. Conflict detection applies to both filterByAddresses and no-events registration paths, with conflict warnings and splicing logic. FetchState tests verify that the first registration in a batch wins when addresses conflict, regardless of whether the registration is events-capable or no-events.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Validate duplicate addresses in config at parse time' directly and concisely summarizes the main objective of this PR: adding validation to detect and reject duplicate addresses during config parsing rather than at runtime.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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

@DZakh DZakh enabled auto-merge (squash) June 11, 2026 13:26
@DZakh DZakh merged commit f768e7e into main Jun 11, 2026
7 of 8 checks passed
@DZakh DZakh deleted the claude/zealous-allen-phvjxy branch June 11, 2026 13:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants