fix(cfg): link fallback block from entry node in control flow graph#705
Merged
Conversation
The CFG builder deduplicated blocks with a `HashSet`, returning early whenever a block had already been visited. This dropped the edge from the current parent into the existing block, so when a fallback handler was first reached through the dispatcher's fall-through path, the direct `CALLDATASIZE < 4` edge from the entry node was never added. Track visited blocks in a `HashMap<String, NodeIndex>` instead, so an already-seen block's node index can be looked up and the parent edge still linked (without recursing again). This restores the missing entry -> fallback edge, e.g. for WETH (0xc02a...cc2) node 0 now links to 0xaf. Closes #627
Contributor
❌ Eval Report for fea72d3
|
Contributor
|
| Metric | Value |
|---|---|
| Base branch | 66.50% |
| PR branch | 66.15% |
| Diff | -0.36% |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed? Why?
Fixes #627. The
cfgcommand was omitting the edge from the entry node to the fallback handler in the control flow graph. For contracts like WETH (0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2), node0should link to the fallback block whenCALLDATASIZE < 4, but that edge was missing.Root cause:
build_cfgdeduplicated blocks using aHashSet<String>and returned early whenever a block was already seen—before the parent→child edge was added. Since the symbolic-execution trace visits the dispatcher before the entry node's direct jump-taken branch, the fallback block gets mapped first as a dispatcher descendant. When the entry node later tries to link to it, the block is already inseen_nodes, so the edge is silently dropped.Fix: Changed
seen_nodesto aHashMap<String, NodeIndex<u32>>. When a block has already been seen, we look up its node index and still add the edge from the current parent before returning (no recursion, so loop protection is preserved).Notes to reviewers
crates/cfg/src/core/graph.rsandcrates/cfg/src/core/mod.rstest_cfg_links_fallback_blockincrates/core/tests/test_cfg.rsHow has it been tested?
0only had0 -> 1; after, it correctly has0 -> 1(fall-through) and0 -> 67(jump to fallback at0xaf)test_cfg_links_fallback_block, a live-contract regression test that uses the RPC endpoint to verify the entry node links to the0xaffallback blockcfgintegration and unit tests passcargo +nightly fmt --checkandcargo clippy --all-featurespass