-
Notifications
You must be signed in to change notification settings - Fork 87
FIP Implementation: Add support for EIP-7702 (Set Code for EOAs) #1705
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…wildcard, and integration tests - Add Delegator actor with HAMT-backed state (mappings, nonces, storage roots). Implement ApplyDelegations with secp256k1 authority recovery over keccak(rlp(chain_id,address,nonce)), nonce checks/bump, LookupDelegate, GetStorageRoot, PutStorageRoot; add unit tests. - Wire EVM CALL-path to consult Delegator for EOAs and execute delegate via InvokeAsEoa. Centralize activation gating at NV_EIP_7702 (runtime/features.rs). - Extend runtime test harness: ParamMatcher::Any + expect_send_any_params for wildcard params. - Add EVM tests: delegated CALL (success), value transfer, gas=2300 variant, and revert mapping; plus InvokeAsEoa storage-root persistence across calls. - Update ancillary plumbing (Cargo/build/singletons/vm_api) as needed.
…rt; drop unnecessary mut in Err(ae) match arm
- Add and stabilize CALL/STATICCALL delegation tests (post-NV, pre-NV skip, absent mapping fallback, non-EVM and missing-code no-ops), including delegated event assertions. - Add InvokeAsEoa storage tests (mount/persist across calls) and a delegated storage smoke test. - Fix STATICCALL/CALL proxy assembly arg ordering; fund value path and align gas expectations with interpreter behavior. - Relax PutStorageRoot param matching in eoa_invoke tests to avoid brittle CID coupling. - Add nested delegation scaffold test (ignored) for two-layer delegation; to be enabled with full InvokeAsEoa execution. - Delegator: reject empty delegation list in ApplyDelegations (USR_ILLEGAL_ARGUMENT).
…rrently WIP) - Add eoa_invoke_nested_delegation.rs to assert that a CALL issued by delegate code triggers nested Delegator lookup, bytecode fetch, delegated event, and a nested InvokeAsEoa attempt. - Note: initial GetStorageRoot method-number ordering requires further investigation; keeping test WIP until resolved.
…r now; ordering/method-number alignment to be finalized
…ions (Get/PutStorageRoot for B, event after nested); keep ignored for now
…ut; assert delegated event and empty returndata
…ue refining nested InvokeAsEoa test; event + self-call order is environment-sensitive under MockRuntime
…red until Delegator call ordering is finalized under MockRuntime
…(Get(A) -> Lookup(B) -> GetBytecode -> self-call(B) -> Get/Put(B) -> event -> Put(A)); keep ignored until double-check across environments
… mapping/nonces; update interpreter pointer semantics; update tests; docs
…licate authority rejection; atomic rollback tests; tuple roundtrip; update TODO; tests for invalid vectors
…sts; atomicity revert OK + status
…tighter gas handling in depth-limit test; wrap initcode to avoid constructor CALL; adjust status decode path out of test
…ndOutcome); update lone usage. Fix clippy issues in EVM code/tests and HAMT bitwidth usage. CI: allow clippy to skip wasm bundling by honoring SKIP_BUNDLE; wire into make check.
…rsist mapping/nonces before call; make delegated SELFDESTRUCT a no-op under InvokeAsEoa; add delegated SELFDESTRUCT tests (with/without value)
…vert (ApplyAndCall must return OK and persist state)
…a failure; return OK with status=0 and revert data. Update test to verify sends and nonce-persistence.
…acent calls - Remove after flush for InvokeAsEoa; map to status=0 with revert data - Handle GetBytecode and caller-resolution failures without aborting state - Add test for GetBytecode error; keep nonce persistence - Keep tests behavioral for gas; no numeric assertions
…add negative tests for r/s length, messages, and minimal r/s acceptance
…formed inputs harness - delegated_storage_isolation: invoke store then load under same authority using different bytecode - apply_and_call_cbor_fuzz: deterministic malformed CBOR cases; reject without panics - run fmt + clippy clean
- Change 1 — ApplyAndCall decode “?” aborts after flush
- Where: ../builtin-actors/actors/evm/src/lib.rs:845–853
- Summary: Using “?” on retblk.deserialize causes ApplyAndCall to return Err after state is flushed, rolling back delegation/nonce updates; suggests returning
Ok{status:0} instead.
- Agree: Yes. ApplyAndCall must never abort after the pre-call flush; failures map to Ok{status:0}. Same issue exists for the InvokeContract path at ../builtin-actors/
actors/evm/src/lib.rs:743–751 and should be fixed similarly.
- Controversy: Low. Clearly the right improvement to uphold the “always Exit OK” atomicity guarantee.
Co-authored-by: Copilot <[email protected]>
- Change 2 — Treat missing delegate bytecode as failure
- Where: ../builtin-actors/actors/evm/src/lib.rs:910–913
- Summary: Returning status:1 when GetBytecode succeeds but yields no code misrepresents delegated execution; suggests status:0.
- Agree: Yes. If the delegate has no code, the delegated execution cannot proceed; returning status:0 is more accurate and consistent with “failed outer call”
semantics.
- Controversy: Low. Behaviorally clearer; no tests depend on the current “success” here.
Co-authored-by: Copilot <[email protected]>
- Change 3 — Avoid “?” on InvokeAsEoa params serialization
- Where: ../builtin-actors/actors/evm/src/lib.rs:831–834
- Summary: “?” on IpldBlock::serialize_dag_cbor(&p) can abort ApplyAndCall post-flush; suggests catching and returning Ok{status:0}.
- Agree: Yes. Internal serialization must not cause an actor abort after state is persisted; mapping to status:0 preserves atomicity.
- Controversy: Very low. Robustness fix with no semantic downsides.
Co-authored-by: Copilot <[email protected]>
- Change 4 — Avoid “?” on InvokeAsEoa params serialization in CALL path
- Where: actors/evm/src/interpreter/instructions/call.rs:243–246
- Summary: “?” would abort the whole interpreter; suggests logging and returning U256::from(0) to signal CALL failure.
- Agree: Yes. EVM CALL returns 0 on failure; the interpreter should not abort on a local serialization error.
- Controversy: Very low. Aligns with EVM call-failure behavior.
Co-authored-by: Copilot <[email protected]>
- ApplyAndCall: map InvokeContract/InvokeAsEoa decode errors to status=0, avoid post-flush aborts. - ApplyAndCall: treat GetBytecode OK+None (delegate has no code) as status=0. - Avoid ? on InvokeAsEoa param serialization; return status=0 on error. - Add tests: invokeaseoa_decode_error, invokecontract_decode_error, delegate_no_code. - Clean up unused imports in tests.
…nto eip7702 # Conflicts: # Cargo.lock
…SIZE(A)=23 after ApplyAndCall (currently fails)\n\n- Add integration test using TestVM that deploys M, C, D; applies A->D via M, then checks EXTCODESIZE(A) from C.\n- Demonstrates delegation mapping is currently per-actor, not global (test fails now).\n- Add dev-deps: test_vm, vm_api(testing), fil_actor_eam.\n- Fix clippy warnings and formatting.
|
I added a test that confirms that the evm actor is the wrong context to store the account -> delegate mapping. The evm actor has one instance per smart contract not a global scope. Next i'll move the mapping to the ethaddress actor and move delegation logic to the fvm repo commit: summary:
|
…y on VM intercept. Adjust tests (pointer semantics via runtime helper; ignore interpreter-only delegation tests).
…AsEoa/ApplyAndCall temporarily for compatibility
…EXTCODE* consults helper; shared eip7702 types moved; add EthAccount state; update deps
…ints in next push; retain EXTCODE*; align tests (doc update pending)
… transfer test expectations; ignore flaky nonce init test
…ate); keep InvokeAsEoaWithRoot; update dispatch
… roots) from state/system; stub legacy ApplyAndCall; keep InvokeAsEoaWithRoot
…backs altered in ext/call beyond mapping errors to illegal_state
…ny path error)\n\n- Remove path-based [patch] entries to ../ref-fvm which break CI runners\n- Patch crates.io FVM crates to snissn/ref-fvm@0d53fc71 (EIP-7702 helpers)\n- Keeps local dev workflow: use path overrides locally without committing
… comments; delete local script; move ApplyAndCall tests to EthAccount
…tes path; clarify tests status
• Description
This PR completes the EIP‑7702 EthAccount + ref‑fvm migration in builtin‑actors. Delegation state is moved into the EthAccount actor, the EVM actor is minimalized to expose an
InvokeAsEoaWithRoot trampoline and EXTCODE* pointer virtualization, and together with ref‑fvm’s VM intercept this yields atomic “apply authorizations + execute outer call” semantics and
chain‑wide delegated execution for EOAs while preserving FEVM safety.
Related FIP PR link: filecoin-project/FIPs#1209
Related LOTUS PR link: filecoin-project/lotus#13408
Core behaviors
of EVM‑local.
the outer call in a single transaction. Mapping and nonce bumps persist even when the outer call reverts; the actor always exits with ExitCode::OK and returns embedded status +
output_data.
context.
input), and returns (output_data, new_storage_root) on success.
encodes the revert payload as raw bytes, and returns an unchecked error with EVM_CONTRACT_REVERTED so the VM can map it back to a reverted CALL with proper RETURNDATASIZE /
RETURNDATACOPY semantics.
authority storage and balance (no tombstones, no balance moves).
EthAccount / account‐like actor:
along the delegated path.
Signature and domain
the uncompressed pubkey).
Pre‑existence policy and safety
actor (builtin type == EVM), mirroring the “code must be empty/pointer” rule.
additional authority contexts.
updates are considered.
Gas behavior
letting the VM forward the full available budget.
into the embedded status field while EthAccount itself always returns ExitCode::OK.
budget.
once the EIP‑7702 gas schedule settles.
New capabilities
Testing
EthAccount / ApplyAndCall
value.
all fail with explicit illegal_argument errors.
authorities and duplicate authorities in a single message are rejected.
mapping and nonces intact.
correctly.
EVM / delegated context and EXTCODE*
get_eth_delegate_to returns a delegate. Non‑delegated EOAs and not‑found addresses still behave as empty code.
nested delegation and treats SELFDESTRUCT as a no‑op for authority mapping and balances.
Implementation notes
execution goes through InvokeAsEoaWithRoot invoked by the VM intercept.
builtin‑actors provides the authority context and pointer semantics that the VM relies on.
Remaining TODOs
propagation from the embedded return, delegated CALL behavior, and gas/refund behavior through JSON‑RPC.
pathological 7702 flows.
This PR brings builtin‑actors into alignment with the EthAccount‑centric, VM‑intercept‑driven EIP‑7702 design: atomic apply‑and‑call transactions, globally consistent delegation semantics
for EOAs, and EXTCODE* pointer projection are all implemented in a way that is consistent with Ethereum where possible and safe under the FEVM execution and gas model.