Skip to content

feat(eth): allow eth_call and eth_estimateGas from contract and non-existent senders - #7419

Closed
0xDevNinja wants to merge 2 commits into
ChainSafe:mainfrom
0xDevNinja:0xdevninja/issue-7394-eth-call-skip-sender
Closed

feat(eth): allow eth_call and eth_estimateGas from contract and non-existent senders#7419
0xDevNinja wants to merge 2 commits into
ChainSafe:mainfrom
0xDevNinja:0xdevninja/issue-7394-eth-call-skip-sender

Conversation

@0xDevNinja

Copy link
Copy Markdown
Contributor

Summary

Ports filecoin-project/lotus#13724 to Forest. Closes #7394.

Ethereum tooling assumes eth_call and eth_estimateGas work from senders that Filecoin's explicit path rejects: Safe's protocol-kit issues eth_call with from == to for EIP-1271 checks, dApps estimate gas before an account is funded, and viem defaults from to the connected wallet even for reads. Forest ran both methods on the FVM's explicit path, which requires the sender to be an existing account-type actor, so all of the above failed.

This mirrors Geth (and Lotus) by skipping sender validation for these two methods only:

  • Sender does not exist on chain: apply an implicit zero-value send to the address so the FVM instantiates an ephemeral placeholder actor, then run the message on the explicit path so gas accounting matches a real first send.
  • Sender exists but is an EVM contract: run the message on the implicit path, which skips the account-type / nonce / balance checks.

Everything runs on the VM's in-memory buffered state; nothing is persisted.

Design notes (Forest specifics)

  • Forest routes both eth_call and eth_estimateGas through StateManager::call_with_gas (explicit apply), so both cases are gated there behind a new skip_sender_validation flag. The strict public API is unchanged (thin wrappers), and Filecoin.GasEstimateGasLimit / the other Filecoin RPCs keep strict validation — the skip path is scoped to the two eth methods.
  • eth_call tries the strict path first and retries on the skip path when the receipt is SysErrSenderInvalid (contract sender) or the call returns the new typed Error::SenderValidationFailed (missing sender).
  • eth_estimateGas detects a contract or missing sender up front (via the sender actor's code) and estimates on the skip path: initial estimate, overestimation multiplier, then the usual gas search.

Known deficiency (inherited from Lotus)

As documented in the upstream PR, estimates from contract senders miss the on-chain inclusion cost on the implicit path; the 1.25x overestimation multiplier covers it for realistic calls. The proper fix needs a new FVM ApplyKind and a ref-fvm/ffi release.

Tests

Added RPC conformance cases (eth_call / eth_estimateGas from a non-existent sender, V1 + V2). Rejections are tolerated identically across nodes so the cases stay stable against a Lotus that predates the equivalent change.

Validation status

  • cargo check / clippy --all-targets -D warnings (modulo the pre-existing generated _go_bindings.rs cast lints) / cargo fmt all clean.
  • The completion criteria call for a gas benchmark against Lotus. That needs the RPC conformance harness against a Lotus build carrying lotus#13724, which is why this is a draft — I would like the conformance CI to run before I call the parity guaranteed. Happy to add contract-sender fixtures or adjust the approach based on what you would prefer to see benchmarked.

…xistent senders

Ethereum tooling assumes both work: Safe's protocol-kit issues eth_call with
from == to for EIP-1271 checks, dApps estimate gas before an account is funded,
and viem defaults from to the connected wallet even for reads. Forest rejected
these because both paths run the message on the FVM's explicit path, which
requires the sender to be an existing account-type actor.

Mirror Geth (and Lotus) by skipping sender validation for these two RPC methods:

- Sender does not exist on chain: apply an implicit zero-value send to the
  address so the FVM instantiates an ephemeral placeholder actor, then run the
  message on the explicit path so gas accounting matches a real first send.
- Sender exists but is not a valid sender type (an EVM contract): run the
  message on the implicit path, which skips the account-type, nonce and balance
  checks.

The skip path is scoped to eth_call and eth_estimateGas; Filecoin.GasEstimateGasLimit
and the other Filecoin RPCs keep strict sender validation. eth_call retries on
the skip path when the strict apply returns a SysErrSenderInvalid receipt or a
SenderValidationFailed error; eth_estimateGas detects a contract or missing
sender up front and estimates on the skip path (initial estimate, overestimation
multiplier, then a gas search).

Nothing is persisted; all of this runs on the VM's in-memory buffered state.

Ref ChainSafe#7394
Add RPC conformance cases exercising eth_call and eth_estimateGas with a sender
address that does not exist on chain, on both the V1 and V2 API paths. These
guard the ephemeral-placeholder sender path added for ChainSafe#7394. Rejections are
tolerated identically on both nodes so the cases stay stable against a Lotus
that predates the equivalent change.

Ref ChainSafe#7394
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 385b4bf7-4c89-4eaa-b760-c8a93c46e547

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
✨ Simplify code
  • Create PR with simplified code

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.

@sudo-shashank

Copy link
Copy Markdown
Contributor

@0xDevNinja, Thanks for your interest!
This issue hasn't been assigned yet. Please wait for a maintainer to assign it or give you the go-ahead before you start writing code.

For more details, please see the contribution guidelines: https://github.com/ChainSafe/forest/blob/main/CONTRIBUTING.md#i-want-to-contribute

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.

Allow eth_call and eth_estimateGas from contract and non-existent senders

2 participants