diff --git a/EIPS/eip-7928.md b/EIPS/eip-7928.md index d6f0b763bcb92d..f834f0004aa511 100644 --- a/EIPS/eip-7928.md +++ b/EIPS/eip-7928.md @@ -229,7 +229,7 @@ Record **post‑transaction** balances (`uint256`) for: For unaltered account balances: -If an account’s balance changes during a transaction, but its post-transaction balance is equal to its pre-transaction balance, then the change MUST NOT be recorded in `balance_changes`. The sender and recipient address MUST still be included in `AccountChanges`. +If an account's balance changes during a transaction, but its post-transaction balance is equal to its pre-transaction balance, then the change MUST NOT be recorded in `balance_changes`. The sender and recipient address MUST still be included in `AccountChanges`. The following special cases require addresses to be included with empty changes if no other state changes occur: @@ -569,22 +569,9 @@ Validating access lists and balance diffs adds validation overhead but is essent Increased block size impacts propagation but overhead (~70 KiB average) is reasonable for performance gains. -### Early Rejection of Malicious BALs +### Spurious Storage Reads -Since `storage_reads` entries are not mapped to specific transaction indices, their validity can only be confirmed after executing all transactions. A malicious proposer could exploit this by declaring phantom storage reads that are never accessed, forcing clients into unnecessary I/O prefetching and significant data download while the block remains unrejectable until completion. - -To mitigate this, clients SHOULD enforce a gas-budget feasibility check at transaction boundaries. Let: - -- `R_remaining` = number of declared storage reads not yet accessed -- `G_remaining` = remaining block gas - -The following invariant must hold: - -``` -G_remaining >= R_remaining * 2000 -``` - -Where 2000 is the minimum gas cost for a storage read (via [EIP-2930](./eip-2930.md) access lists: 1900 upfront + 100 warm read). If this check fails, the block can be rejected immediately as invalid, since insufficient gas remains to access the declared reads. This check SHOULD be performed periodically (e.g., every 8 transactions) to enable early rejection without impacting parallel execution. +Since `storage_reads` entries are not mapped to specific transaction indices, their validity can only be confirmed after executing all transactions. A malicious proposer could exploit this by declaring spurious storage reads that are never accessed, forcing clients into unnecessary I/O prefetching and data download while the block remains unrejectable until completion. The `bal_items` constraint bounds the number of such entries. Clients SHOULD additionally consider mechanisms to detect infeasible `storage_reads` during execution and reject the block before it completes. Any such mechanism MUST NOT reject a valid block; in particular, the storage reads performed by system calls are not paid for by block gas and cannot be bounded by it. ## Copyright