fix(evm): handle non-compute limit exceeds on the keyless-deploy path#341
fix(evm): handle non-compute limit exceeds on the keyless-deploy path#341wayzeek wants to merge 1 commit into
Conversation
A keyless-deploy call whose intrinsic usage latched a non-compute limit (e.g. calldata over the data-size limit) reached the Rex3 overhead-gas charge in `execute_keyless_deploy_call`, where a `false` from `record_compute_gas` was assumed to mean a compute-gas exceed. Any other `check_limit()` result hit `unreachable!()`, aborting the node on pre-Rex4 specs, which lack the `frame_result_if_exceeding_limit` guard ahead of interceptor dispatch. Consult the aggregate `check_limit()` for the dimension that actually tripped: a frame-local compute-gas exceed still reverts with `InsufficientComputeGas`, a TX-level compute-gas exceed keeps its existing halt-without-rescue behavior, and a TX-level non-compute exceed now rescues remaining gas before halting, matching `create_exceeded_limit_result` / `reject_if_tx_limit_overflow` on the non-intercepted path. Also self-latch in `AdditionalLimit::merge_usage` so it upholds the resource-limit protocol on its own, consistent with the other non-compute recorders. The fixed path previously panicked, so no valid chain could have depended on its outcome; the compute-gas paths that already worked are unchanged.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0c8518b5d8
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| _ => { | ||
| // TX-level non-compute: rescue gas here, since the interceptor | ||
| // short-circuit skips `after_frame_run`'s rescue. | ||
| limit.rescue_gas(&gas); | ||
| let mut result = make_halt!(); |
There was a problem hiding this comment.
Gate this changed REX3 result behind a new spec
For a REX3 top-level keylessDeploy whose intrinsic calldata exceeds a non-compute transaction limit, this new branch replaces the prior node abort with a consensus-visible DataLimitExceeded halt and a rescued-gas refund. AGENTS.md explicitly marks REX3 as frozen and requires new EVM behavior to be introduced behind a new spec, so applying this behavior directly to MegaSpecId::REX3 changes historical-spec execution rather than preserving it.
Useful? React with 👍 / 👎.
Summary
execute_keyless_deploy_callcharges the keyless-deploy overhead gas and, on Rex3+, records it as compute gas. WhenAdditionalLimit::record_compute_gasreturnedfalse, the code assumed the only possible cause was a compute-gas exceed and treated every othercheck_limit()result asunreachable!().That assumption is wrong.
record_compute_gasreturnsfalsewhenever any dimension has latched an exceed (its leading short-circuit), including an intrinsic data-size, KV, or state-growth overflow recorded inbefore_tx_start. Pre-Rex4 specs have noframe_result_if_exceeding_limitguard ahead of interceptor dispatch, so that latch first surfaces here with compute gas still within limit, hits theunreachable!(), and aborts the node. A keyless-deploy call whose outer calldata exceeds the transaction data-size limit is enough to trigger it on Rex3.Changes
check_limit()for the dimension that actually tripped. A frame-local compute-gas exceed still reverts withInsufficientComputeGas; a TX-level compute-gas exceed keeps its existing halt-without-rescue behavior; a TX-level non-compute exceed now rescues the remaining gas before halting, matchingcreate_exceeded_limit_resultandreject_if_tx_limit_overflowon the non-intercepted path (interceptor short-circuiting skipsafter_frame_run, so the rescue has to happen here).AdditionalLimit::merge_usagenow runscheck_limit()so it self-latches per the resource-limit protocol, consistent with the other non-compute recorders. Behavior-neutral for its sole caller.Backward compatibility
The fixed path previously panicked, so no valid chain could have depended on its outcome, and the compute-gas paths that already worked are unchanged. Rex3/Rex4/Rex5 stay frozen.
Testing
test_rex3_keyless_deploy_data_size_overflow_halts_without_panic: a Rex3 keyless deploy with oversized calldata now halts withDataLimitExceededand the remaining gas is rescued. It panics without the fix.cargo test -p mega-evmpasses (1048 tests);cargo fmt --all --checkandcargo clippyare clean.