Skip to content

Fix negative event counters in multi-chain reorg-on-reorg scenarios#1032

Closed
DZakh wants to merge 5 commits into
release-v2.32.7from
claude/backport-fixes-YzLXm
Closed

Fix negative event counters in multi-chain reorg-on-reorg scenarios#1032
DZakh wants to merge 5 commits into
release-v2.32.7from
claude/backport-fixes-YzLXm

Conversation

@DZakh
Copy link
Copy Markdown
Member

@DZakh DZakh commented Mar 10, 2026

Summary

This PR fixes a critical bug where event counters could go negative during multi-chain reorg-on-reorg scenarios. The issue occurred when a reorg was detected while another rollback was in progress, causing event counter restoration to only apply to the reorging chain instead of all chains.

Key Changes

GlobalState.res - Counter Restoration Fix

  • Root cause fix: Modified validatePartitionQueryResponse to restore event counters for ALL chains when re-reorging from RollbackReady state, not just the reorg chain
  • Changed from ChainMap.update (single chain) to ChainMap.mapWithKey (all chains) to ensure every chain's counter is properly restored before the new rollback subtracts again
  • Added comprehensive comments explaining why all chains must be restored even if they have no progress diff entry

RpcSource.res - Block Miner Address Handling

  • Refactored block miner address conversion logic to always apply the address conversion (either lowercase or standard) instead of conditionally wrapping the entire result object
  • Ensures consistent handling of the miner field regardless of the lowercaseAddresses configuration

Test Coverage

Added 4 comprehensive regression tests to prevent future regressions:

  1. Reorg threshold on restart: Verifies no false reorg threshold when DB is freshly initialized
  2. Multi-chain reorg-on-reorg loop: Tests the exact scenario that triggered the negative counter bug with 2 chains
  3. Reorg-on-reorg with 3 chains: Extended test with 3 chains to ensure all non-reorg chains are properly restored
  4. Chunked partition handling: Tests that rollback correctly handles chunked query partitions without duplicates
  5. Efficient refetch after rollback: Verifies efficient block refetching with chunked partitions
  6. Infinite reorg loop prevention: Tests edge case where reorg chain has no events processed since target checkpoint

Mock.Indexer Enhancement

  • Added optional batchSize parameter to Mock.Indexer.make to support testing scenarios with specific batch size constraints

Implementation Details

The fix ensures that when a reorg is detected during rollback (transitioning from RollbackReady to ReorgDetected), the event counter restoration in validatePartitionQueryResponse applies to every chain in the indexer, not just the chain that detected the new reorg. This prevents the second rollback from subtracting events that were already rolled back in the first rollback, which would cause negative counters on non-reorg chains.

https://claude.ai/code/session_017jqSDS8homENyhbexMaoG4

claude added 3 commits March 10, 2026 12:44
Cherry-pick from main. When a second reorg occurred during RollbackReady
state, only the reorging chain's counter was restored. This fix restores
event counters for ALL chains during rollback transitions.

https://claude.ai/code/session_017jqSDS8homENyhbexMaoG4
…essed (#1027)

Cherry-pick from main. Fixes infinite reorg->rollback loop when a
blockchain reorganization is detected on a chain with no events
processed since the target checkpoint. Now properly rolls back
reorgDetection and fetchState even when no progress diff exists.

https://claude.ai/code/session_017jqSDS8homENyhbexMaoG4
Cherry-pick from PR #930. Apply Address.Evm.fromAddressOrThrow when
lowercaseAddresses=false for both log.address and block.miner fields.
Previously, addresses from RPC providers that returned unchecksummed
data would not be properly checksummed.

https://claude.ai/code/session_017jqSDS8homENyhbexMaoG4
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 10, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bb38c514-4774-4f5a-867e-867e38e2f9a0

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/backport-fixes-YzLXm

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

claude added 2 commits March 10, 2026 13:01
The cherry-picked tests from PRs #1026/#1027 used `sourceConfig:
Config.CustomSources(...)` which is the v3 API. This branch uses
`sources: [...]` in Mock.Indexer.chainConfig.

https://claude.ai/code/session_017jqSDS8homENyhbexMaoG4
The tests from PRs #1026/#1027 use Vitest APIs (t.expect().toEqual()),
partition-aware Mock APIs (~resolveAt, call.resolve/payload), and
metrics with "p" field that don't exist on this branch (pre-Vitest
migration). The production code fixes are retained.

https://claude.ai/code/session_017jqSDS8homENyhbexMaoG4
@DZakh DZakh mentioned this pull request Mar 10, 2026
@DZakh DZakh closed this Mar 10, 2026
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