Skip to content

fix(evm): handle non-compute limit exceeds on the keyless-deploy path#341

Open
wayzeek wants to merge 1 commit into
megaeth-labs:mainfrom
wayzeek:wayzeek/fix/keyless-deploy-limit-panic
Open

fix(evm): handle non-compute limit exceeds on the keyless-deploy path#341
wayzeek wants to merge 1 commit into
megaeth-labs:mainfrom
wayzeek:wayzeek/fix/keyless-deploy-limit-panic

Conversation

@wayzeek

@wayzeek wayzeek commented Jul 16, 2026

Copy link
Copy Markdown

Summary

execute_keyless_deploy_call charges the keyless-deploy overhead gas and, on Rex3+, records it as compute gas. When AdditionalLimit::record_compute_gas returned false, the code assumed the only possible cause was a compute-gas exceed and treated every other check_limit() result as unreachable!().

That assumption is wrong. record_compute_gas returns false whenever any dimension has latched an exceed (its leading short-circuit), including an intrinsic data-size, KV, or state-growth overflow recorded in before_tx_start. Pre-Rex4 specs have no frame_result_if_exceeding_limit guard ahead of interceptor dispatch, so that latch first surfaces here with compute gas still within limit, hits the unreachable!(), 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

  • 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; a TX-level non-compute exceed now rescues the remaining gas before halting, matching create_exceeded_limit_result and reject_if_tx_limit_overflow on the non-intercepted path (interceptor short-circuiting skips after_frame_run, so the rescue has to happen here).
  • AdditionalLimit::merge_usage now runs check_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

  • New test_rex3_keyless_deploy_data_size_overflow_halts_without_panic: a Rex3 keyless deploy with oversized calldata now halts with DataLimitExceeded and the remaining gas is rescued. It panics without the fix.
  • cargo test -p mega-evm passes (1048 tests); cargo fmt --all --check and cargo clippy are clean.

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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +210 to +214
_ => {
// 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!();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

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