Skip to content

fix(evm): accept PascalCase debug call-frame types (zkSync-era nodes) - #562

Open
SQD-Trevor-Agent wants to merge 1 commit into
masterfrom
alert-fix/eUZPoL-zklink-pascalcase-frames
Open

fix(evm): accept PascalCase debug call-frame types (zkSync-era nodes)#562
SQD-Trevor-Agent wants to merge 1 commit into
masterfrom
alert-fix/eUZPoL-zklink-pascalcase-frames

Conversation

@SQD-Trevor-Agent

Copy link
Copy Markdown

Cause (proven)

The dump-zklink-nova-mainnet-0 pod has been crash-looping since ~20:21 UTC on 2026-09-05 (alert ArchiveDumpRestarting). Pod logs:

Error: invalid debug call frames for transaction 0xed925dd5e36a55d920d682b8e90904105bd69cc3e9406ba68c679bbc0f10c31e: root frame has unsupported type Call
    at getBlocks (/squid/evm/evm-rpc/lib/data-source/get-blocks.js:27:60)
rpcUrl: https://rpc.zklink.io/   failedBlocks: [8345775,8345777,8345779]  retries: 5

zklink-nova is a zkSync-Era-based L3. Its debug_traceTransaction/debug_traceBlockByNumber callTracer returns frame types in PascalCase ("type": "Call"), verified live against https://rpc.zklink.io/:

{"type":"Call","from":"0x00..00","to":"0x00..8001", "calls":[{"type":"Call", ...}]}

The debug-frame verification introduced in #548 (checkDebugFrameStructure / checkCallFrameTree in evm-rpc/src/verification.ts) matches frame types against sets containing only CALL/call (and camelCase variants), not Call. So checkDebugFrameStructure returns root frame has unsupported type Call, the block is marked _isInvalid, and after 5 retries getBlocks throws → the dump process crashes → restart loop → no data written.

This shipped to production when the evm-dump:ac90a36d image (which contains the #548 verification) was deployed to zklink-nova at ~20:21 UTC on 2026-09-05; the code has been on master since 26f7703, and the casing has always been zklink's format, so the trigger was the deploy, not a chain change. The normalization mapper (evm-normalization/src/mapping.ts) switches on the same exact strings and would throw Unexpected case: Call on the same data.

This is a legitimate on-chain format our own code fails to recognize — the fix is to support it, not to skip/disable the check.

Fix

Match debug call-frame types case-insensitively in both the verifier and the mapper, so CALL / call / Call are all handled uniformly. This also folds the previously ad-hoc lowercase/camelCase entries into a single canonical (upper-cased) comparison.

Tests (red → green)

  • evm/evm-rpc/src/verification.call-frame-tree.test.ts: added accepts PascalCase frame types and accepts a PascalCase root call frame.
    Pre-fix: expected 'root frame has unsupported type Call' to be undefined. Post-fix: pass.
  • evm/evm-normalization/src/mapping.debug-frame.test.ts: added maps a Call frame.
    Pre-fix: Error: Unexpected case: Call. Post-fix: pass.

Verified locally: rush build green (both packages compile), both package suites green (the one unrelated failure in test/verification.test.ts > transaction sender recovery is a 5s-timeout on slow ECDSA recovery in the sandbox and passes with --testTimeout=60000).

Falsification

If zklink's dump still logs unsupported type <X> for a type <X> that is not a casing variant of CALL/CALLCODE/DELEGATECALL/STATICCALL/INVALID/CREATE/CREATE2/SELFDESTRUCT/STOP, then it is a genuinely new frame kind and this fix is insufficient.

Related to #548 (introduced the frame verification); this is a follow-up casing bug in that feature, not a duplicate.

zkSync-era nodes (e.g. zklink-nova) serialize debug callTracer frame
types in PascalCase ('Call', 'Create', 'DelegateCall'). The frame
verification (checkDebugFrameStructure/checkCallFrameTree) and the
normalization mapper only matched UPPER/camelCase, so every zklink block
was rejected with 'root frame has unsupported type Call' and, after 5
retries, crashed the dump into a restart loop.

Match frame types case-insensitively in both the verifier and the
mapper so any casing (CALL/call/Call) is handled uniformly.
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.

1 participant