Skip to content

execution: system calls do not touch SystemAddress, drop its BAL filter - #24503

Closed
chfast wants to merge 2 commits into
erigontech:mainfrom
chfast:chfast/bal-system-address
Closed

chfast wants to merge 2 commits into
erigontech:mainfrom
chfast:chfast/bal-system-address

Conversation

@chfast

@chfast chfast commented Oct 2, 2026

Copy link
Copy Markdown
Member

Every zero-value system call touched its caller, which put SystemAddress
into the block access list, and AsBlockAccessList then dropped it unless a
user tx had a non-revertable access to it. That heuristic also dropped real
accesses: a zero-amount withdrawal to SystemAddress and a delegation to it.

By the EIP-7928 spec, being the caller of a system call is not a state
access, so a system call no longer touches its caller (AuRa keeps the touch
for its empty system account) and SystemAddress follows the same BAL rules
as any other address.

IntraBlockState.SubBalance still turns a zero debit of SystemAddress into a
touch on every chain. Block execution never debits SystemAddress (every
caller passes a recovered sender or a contract address), so only RPC calls
from 0xff..fe (eth_call, eth_simulateV1, trace_call) reach it; it is left as
is and its comment corrected.

Open question (Gnosis): AuRa keeps the system-call touch of SystemAddress while the BAL filter is gone, so an AuRa chain activating Amsterdam would carry SystemAddress as an access-only entry in every BAL. No AuRa chain has Amsterdam scheduled; whether Gnosis BALs should include it needs to be agreed with Nethermind.

chfast added 2 commits October 2, 2026 11:43
A zero-amount withdrawal to SystemAddress and a call to an EOA delegated
(EIP-7702) to SystemAddress are state accesses, so by the EIP-7928 spec
SystemAddress must be in the block access list. Both are omitted today.
Every zero-value system call touched its caller, which put SystemAddress
into the block access list, and AsBlockAccessList then dropped it unless a
user tx had a non-revertable access to it. That heuristic also dropped real
accesses: a zero-amount withdrawal to SystemAddress and a delegation to it.

By the EIP-7928 spec, being the caller of a system call is not a state
access, so a system call no longer touches its caller (AuRa keeps the touch
for its empty system account) and SystemAddress follows the same BAL rules
as any other address.

IntraBlockState.SubBalance still turns a zero debit of SystemAddress into a
touch on every chain. Block execution never debits SystemAddress (every
caller passes a recovered sender or a contract address), so only RPC calls
from 0xff..fe (eth_call, eth_simulateV1, trace_call) reach it; it is left as
is and its comment corrected.
@yperbasis
yperbasis requested review from taratorio and a balanced review from Copilot October 2, 2026 09:57
@yperbasis yperbasis added this to the 3.8.0 milestone Oct 2, 2026
@chfast

chfast commented Oct 2, 2026

Copy link
Copy Markdown
Member Author

Superseded by #24504 (same commits, branch in this repo).

@chfast chfast closed this Oct 2, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

The consensus-visible AuRa and Amsterdam BAL behavior remains unresolved, alongside the identified witness and cleanup issues.

Review effort: Balanced
Findings: 2 Medium severity · 1 Low severity

Open (3)
What changed in this PR

Updates system-call handling so SystemAddress follows standard EIP-7928 BAL rules while preserving AuRa behavior.

Changes:

  • Avoids touching system-call callers outside AuRa.
  • Removes the special SystemAddress BAL filter.
  • Adds withdrawal, delegation, and AuRa regression coverage.
File Description
rpc/​jsonrpc/​eth_call.go Updates witness rationale.
execution/​vm/​runtime/​runtime_test.go Tests system-call behavior on standard and AuRa chains.
execution/​vm/​instructions.go Updates BALANCE documentation.
execution/​vm/​evm.go Restricts caller touching to AuRa system calls.
execution/​state/​versionedio.go Removes special BAL filtering.
execution/​state/​versionedio_test.go Tests ordinary BAL treatment of SystemAddress.
execution/​state/​intra_block_state.go Clarifies AuRa touch behavior.
execution/​engineapi/​engine_api_bal_test.go Adds withdrawal and delegation BAL regressions.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

func TestSystemCallZeroValueTouchesCallerOnAura(t *testing.T) {
t.Parallel()

statedb, _, balChanges := runZeroValueSystemCall(t, true)
Comment thread rpc/jsonrpc/eth_call.go
Comment on lines +741 to 745
// On AuRa the stateless verifier navigates the system address (system-call msg.sender),
// so its path must be in the witness.
// collectAccessedState drops it per EIP-7928 — a witness-content rule for the
// debug_executionWitness format that does not apply to this op-stream witness.
accessed.Addresses[common.Address(params.SystemAddress.Value())] = struct{}{}

isUserTx := txIndex >= 0
for addr, opts := range io.ReadSet(txIndex).access {
for addr := range io.ReadSet(txIndex).access {
@yperbasis yperbasis removed this from the 3.8.0 milestone Oct 2, 2026
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.

3 participants