Commit 77e95ef
feat(spec-specs,test-tests): update the EIP-2780 implementation (ethereum#3126)
* feat(spec-specs): EIP-2780 charge state-dependent tx costs at the top frame
Move every state-dependent charge out of the transaction intrinsic --
which over-charged and then refunded -- and into the top frame, charged
lazily against the transaction's pre-state. The intrinsic keeps only
state-independent costs and remains the sole validity input: contract
creation no longer adds NEW_ACCOUNT, and each authorization adds only
REGULAR_PER_AUTH_BASE_COST.
At depth 0, process_message now:
- Applies the EIP-7702 authorizations via set_delegation, charging per
authorization: NEW_ACCOUNT when the authority's leaf does not exist;
ACCOUNT_WRITE on the transaction's first write to the authority (the
written set is seeded with the sender, so a self-sponsored authority
pays nothing and repeated authorizations pay once); and AUTH_BASE
once per authority for a net-new delegation indicator, never
credited back.
- Folds the authorization state gas into the frame baseline
(Evm.auth_state_gas_used, rebased state_gas_reservoir) so a dispatch
revert or halt cannot refill it -- the delegations, nonce bumps, and
authority leaves persist per EIP-7702's dispatch-failure rule. A
preparation-phase out-of-gas instead rolls the delegations back,
undoes the fold, and halts consuming all gas without dispatching.
- Charges the remaining dispatch costs in prepare_dispatch, which must
not mutate transaction state: the recipient's or creation target's
NEW_ACCOUNT keyed on pre-transaction aliveness (still refillable,
since that state rolls back with the frame), and delegation
resolution at WARM_ACCESS or COLD_ACCOUNT_ACCESS by target warmth.
set_delegation is thereby the last transaction-state mutation before
dispatch, so the execution snapshot brackets exactly the state the
folded gas paid for.
Remove the superseded over-charge/refund plumbing: the intrinsic
NEW_ACCOUNT refund paths in fork.py and the vestigial
MessageCallOutput state_refund / created_target_alive fields.
validate_authorization returns just the authority address.
* feat(amsterdam): model EIP-2780 top-frame gas in the test framework
Teach execution_testing the EIP-2780 split between intrinsic and
top-frame charges:
- Intrinsic calculators charge only the state-independent costs:
REGULAR_PER_AUTH_BASE_COST per authorization and no NEW_ACCOUNT for
contract creation. AUTH_BASE (EIP-8037) and
REGULAR_PER_AUTH_BASE_COST (EIP-8038) become named gas costs.
- The top-frame calculators (transaction_top_frame_gas_calculator,
transaction_top_frame_state_gas) price the per-authorization
NEW_ACCOUNT / ACCOUNT_WRITE / AUTH_BASE from the authorizations list
threaded into them, the recipient's or creation target's
NEW_ACCOUNT, and delegation-target resolution as warm or cold via
delegation_warm.
- AuthorizationTuple carries creates_account / writes_delegation /
first_write annotations (excluded from serialization) so each tuple
declares its pre-state effect; ACCOUNT_WRITE keys on first_write --
the transaction's first write to the authority -- rather than leaf
creation. The AuthorizationGasInfo structural Protocol lets forks
read the annotations without importing test_types.
- EIP2780.refund_types() drops AUTHORIZATION_EXISTING_AUTHORITY:
Amsterdam charges authorizations by pre-state instead of
over-charging and refunding, while Prague's refund coverage keeps
the shared enum member.
* test(amsterdam): cover the EIP-2780 top-frame charges
Pin the EIP-2780 top-frame model end to end in the EIP-2780 suite:
- test_authorization_charges.py (new): per-authorization billing keyed
on the authority's pre-transaction state -- NEW_ACCOUNT for new
leaves; ACCOUNT_WRITE on the transaction's first write (existing
authorities pay it, the sender and repeated authorizations do not,
tx.to as authority does); AUTH_BASE only for a net-new delegation,
at most once per authority, never credited back (pre-tx-delegated
re-set and clear-then-set, multiple sets, set/clear cycles).
- test_authorization_oog.py (new): charge-by-charge out-of-gas points
across the preparation phase -- a prep out-of-gas rolls back every
applied delegation and halts without dispatching, while applied
authorization state gas survives a dispatch revert or halt
(balance-, header-, and reservoir-level pins), with guards that the
recipient's NEW_ACCOUNT and in-frame SSTORE state gas still refill
when their state rolls back.
- test_calldata_floor.py / test_intrinsic_gas_boundary.py: a
data-heavy transfer whose EIP-7623/7976 floor (built on the lowered
TX_BASE) dominates the decomposed intrinsic, one-below-floor
rejection, and the contract-creation boundary on the regular-only
intrinsic. The floor-dominating calldata size comes from the shared
find_floor_cost_threshold search rather than a hardcoded value.
- Migrations: the value-moving tests adopt the top-frame NEW_ACCOUNT
for the creation target (charged on success, refilled when the init
code reverts), the delegation variants annotate self-sponsored
tuples with first_write, the warmth invariants adopt warm/cold
delegation-target access, and helpers.py's authorization actions
declare the creates_account / writes_delegation / first_write
annotations the framework calculators consume.
* test(amsterdam): migrate remaining suites to the EIP-2780 top-frame model
EIP-2780 moved the contract-creation NEW_ACCOUNT and every
state-dependent authorization cost out of the intrinsic and into the
top frame, with no over-charge refunds. Migrate the suites that pinned
the old model:
- eip8037 test_state_gas_set_code.py: authorization tests bill by the
declared pre-state annotations; receipts are plain sums with the
first-write ACCOUNT_WRITE included, headers are
max(block_regular, block_state), and authorization state gas
persists on the block's state dimension through every
dispatch-failure mode (no refill on revert, halt, or out-of-gas).
- eip8037 create cluster (test_state_gas_create.py,
test_state_gas_reservoir.py, test_state_gas_pricing.py): gas limits
cover the top-frame NEW_ACCOUNT; reject-below-intrinsic keys off the
regular-only intrinsic; NEW_ACCOUNT refills on init-code failure and
is never charged on collision; AUTH_BASE is measured via
transaction_top_frame_state_gas; an existing-authority authorization
credits nothing to the reservoir.
- eip8038 (test_create_gas.py, test_selfdestruct_gas.py,
test_set_code_auth_gas.py, test_set_code_auth_refunds.py,
test_fork_transition.py): the same top-frame NEW_ACCOUNT treatment
for creates, the reduced refund-free per-authorization charges, and
the authorization intrinsic drop across the BPO2->Amsterdam
transition.
- eip7778 / eip7976: drop the AUTHORIZATION_EXISTING_AUTHORITY refund
path (Amsterdam no longer has that refund type) and add the
top-frame regular charge to expected receipts.
- eip7954 test_max_code_size.py: add the top-frame state gas back into
the exact-fit deposit-gas limit so it still lands precisely on the
code-deposit boundary.
* test(amsterdam): cover BAL inclusion at the top-frame delegation charge
The delegation target of a delegated tx.to must enter the block
access list only when the EIP-2780 top-frame access charge succeeds.
Pin the charge-before-access order of the top-frame dispatch: on
out-of-gas the target stays out of the BAL, on success it appears
with an empty change set.
* feat(amsterdam): EIP-2780 exempt value-bearing recipient authority from ACCOUNT_WRITE
When a transaction moves value to its recipient and that recipient is
also an authority, seed the recipient into `set_delegation`'s
written-set: the value transfer already pays to write the recipient, so
applying the authorization is not the transaction's first write to it
and no `ACCOUNT_WRITE` is charged.
Adopt the framework top-frame calculators in the EIP-2780 authorization
charge and value-moving tests (driving the charges through the
`first_write` / `writes_delegation` / `creates_account` annotations
instead of hand-summed gas constants), and refresh the now
value-dependent `ACCOUNT_WRITE` docstrings.
* refactor(specs,tests): Remove intrinsic state gas concept
* refactor(specs): Remove intrinsic state gas concept
* refactor(test-forks): Remove intrinsic state gas
* fix(tests): Fix intrinsic state gas usages
* fix(tests): correct inert authorization flags in delegation-pointer tests
The two migrated delegation-pointer tests re-target an authority that
already has a delegation and whose account nonce (1, from the delegation
setup) no longer matches the authorization's nonce=0, so the
authorization is invalid and charges no top-frame state gas. Setting
writes_delegation/first_write to True added a phantom AUTH_BASE to
state_gas_reservoir that was silently refunded, contradicting the
AuthorizationTuple.first_write contract (False for invalid
authorizations) and the spec's AUTH_BASE gate (not delegated_before_tx).
Set both flags to False so the reserved state gas matches what the top
frame actually charges, and reuse the single authorization object in
test_delegation_pointer_new_account_state_gas instead of building a
second inline tuple.
* fix(test-forks): drop deleted transaction_intrinsic_state_gas call
The execute plugin's _compute_deploy_gas_limit still called the removed
transaction_intrinsic_state_gas, which failed mypy (and CI static).
On every concrete fork that value was zero (BaseFork default, or forced
to zero once EIP-2780 moves the created account's NEW_ACCOUNT to the top
frame), and the intrinsic calculator already returns the regular-only
cost, so the back-out was a no-op. Remove it, keeping the deploy gas
limit unchanged.
---------
Co-authored-by: Guruprasad Kamath <guru241987@gmail.com>
* test(amsterdam): reconcile floor-pinned expectations with header gas accounting
After the top-frame decomposition, the calldata floor exceeds the
create intrinsic for tiny initcode. The floor pins only the amount
billed (receipt cumulative gas); the block header counts pre-refund,
pre-floor regular consumption. Build expectations from the pre-floor
intrinsic, apply the floor once to the receipt only, and verify the
header and receipt separately where they diverge.
* fix(spec-specs, tests): exclude unloaded recipient from the BAL
* fix(spec-specs, tests): exclude unloaded recipient from the BAL
(cherry picked from commit 89d15f3)
* refactor(spec-specs): represent unresolved top-frame code as None
* test(amsterdam): pin reservoir settlement at each top-frame failure point
A transaction whose gas limit exceeds the EIP-7825 cap forms a
state-gas reservoir, and how much of it returns depends on where the
transaction fails. Two tests drive one many-authorization transaction
shape to every failure point:
- a preparation out-of-gas (inside set_delegation or at the dispatch
charge) rolls everything back and returns the reservoir whole: the
sender pays exactly TX_MAX_GAS_LIMIT, however much extra was sent;
- an execution failure keeps the applied delegations and their state
gas consumed, so the reservoir is preserved only down to the
post-authorization baseline -- an exceptional halt burns the full
gas limit when the auth state gas exceeds the reservoir, while a
revert pays exact usage.
The value-bearing variant targets the bn254 pairing precompile (the
one empty recipient that executes) so both state-charge classes ride
one transaction: the halt scenario sizes the reservoir above the auth
state gas to make the recipient NEW_ACCOUNT refill observable in the
settlement, pinning gas_used == cap + auth state gas exactly.
Also corrects the module docstring, which claimed a preparation-phase
OOG consumes the full gas limit -- only true with a zero reservoir.
* post review updates
* fix(tests): Ported static failing tests
---------
Co-authored-by: Toni Wahrstätter <info@toniwahrstaetter.com>
Co-authored-by: Mario Vega <marioevz@gmail.com>
Co-authored-by: spencer <spencer.tb@ethereum.org>1 parent a9abd46 commit 77e95ef
42 files changed
Lines changed: 4838 additions & 1943 deletions
File tree
- packages/testing/src/execution_testing
- cli/pytest_commands/plugins/execute
- forks
- forks/eips/amsterdam
- test_types
- src/ethereum/forks/amsterdam
- utils
- vm
- tests
- amsterdam
- eip2780_reduce_intrinsic_tx_gas
- eip7778_block_gas_accounting_without_refunds
- eip7928_block_level_access_lists
- eip7954_increase_max_contract_size
- eip7976_increase_calldata_floor_cost
- eip8037_state_creation_gas_cost_increase
- eip8038_state_access_gas_cost_increase
- osaka/eip7825_transaction_gas_limit_cap
- ported_static
- stCreateTest
- stEIP3607
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 5 additions & 9 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
250 | 250 | | |
251 | 251 | | |
252 | 252 | | |
253 | | - | |
254 | | - | |
255 | | - | |
256 | | - | |
257 | | - | |
258 | | - | |
259 | | - | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
260 | 257 | | |
261 | 258 | | |
262 | 259 | | |
| |||
291 | 288 | | |
292 | 289 | | |
293 | 290 | | |
294 | | - | |
295 | | - | |
| 291 | + | |
296 | 292 | | |
297 | 293 | | |
298 | 294 | | |
| |||
Lines changed: 28 additions & 16 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
| |||
152 | 153 | | |
153 | 154 | | |
154 | 155 | | |
155 | | - | |
156 | | - | |
157 | | - | |
158 | | - | |
| 156 | + | |
| 157 | + | |
159 | 158 | | |
160 | 159 | | |
161 | 160 | | |
162 | 161 | | |
163 | 162 | | |
164 | 163 | | |
165 | 164 | | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
166 | 178 | | |
167 | 179 | | |
168 | 180 | | |
| |||
185 | 197 | | |
186 | 198 | | |
187 | 199 | | |
| 200 | + | |
| 201 | + | |
188 | 202 | | |
189 | 203 | | |
190 | 204 | | |
| |||
199 | 213 | | |
200 | 214 | | |
201 | 215 | | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
202 | 221 | | |
203 | 222 | | |
204 | 223 | | |
| |||
758 | 777 | | |
759 | 778 | | |
760 | 779 | | |
761 | | - | |
762 | | - | |
763 | | - | |
764 | | - | |
765 | | - | |
766 | | - | |
767 | | - | |
768 | | - | |
769 | | - | |
770 | | - | |
771 | | - | |
772 | 780 | | |
773 | 781 | | |
774 | 782 | | |
| |||
787 | 795 | | |
788 | 796 | | |
789 | 797 | | |
| 798 | + | |
| 799 | + | |
790 | 800 | | |
791 | 801 | | |
| 802 | + | |
792 | 803 | | |
793 | 804 | | |
794 | 805 | | |
| |||
800 | 811 | | |
801 | 812 | | |
802 | 813 | | |
| 814 | + | |
803 | 815 | | |
804 | 816 | | |
805 | 817 | | |
| |||
811 | 823 | | |
812 | 824 | | |
813 | 825 | | |
814 | | - | |
| 826 | + | |
815 | 827 | | |
816 | 828 | | |
817 | 829 | | |
| |||
Lines changed: 79 additions & 13 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
19 | 20 | | |
| 21 | + | |
20 | 22 | | |
21 | 23 | | |
22 | 24 | | |
| |||
112 | 114 | | |
113 | 115 | | |
114 | 116 | | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
115 | 130 | | |
116 | 131 | | |
117 | 132 | | |
118 | 133 | | |
119 | | - | |
| 134 | + | |
120 | 135 | | |
121 | 136 | | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
122 | 140 | | |
123 | 141 | | |
124 | 142 | | |
125 | 143 | | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
126 | 150 | | |
127 | 151 | | |
128 | 152 | | |
| |||
160 | 184 | | |
161 | 185 | | |
162 | 186 | | |
163 | | - | |
164 | | - | |
165 | | - | |
166 | | - | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
167 | 195 | | |
168 | 196 | | |
169 | 197 | | |
| |||
172 | 200 | | |
173 | 201 | | |
174 | 202 | | |
| 203 | + | |
| 204 | + | |
175 | 205 | | |
176 | 206 | | |
177 | 207 | | |
178 | 208 | | |
179 | 209 | | |
| 210 | + | |
180 | 211 | | |
181 | | - | |
182 | | - | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
183 | 221 | | |
184 | 222 | | |
185 | 223 | | |
| |||
190 | 228 | | |
191 | 229 | | |
192 | 230 | | |
| 231 | + | |
193 | 232 | | |
194 | 233 | | |
195 | 234 | | |
196 | | - | |
197 | | - | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
198 | 242 | | |
199 | 243 | | |
200 | 244 | | |
201 | | - | |
202 | | - | |
203 | 245 | | |
204 | | - | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
Lines changed: 1 addition & 24 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
92 | 92 | | |
93 | 93 | | |
94 | 94 | | |
| 95 | + | |
95 | 96 | | |
96 | 97 | | |
97 | 98 | | |
| |||
231 | 232 | | |
232 | 233 | | |
233 | 234 | | |
234 | | - | |
235 | | - | |
236 | | - | |
237 | | - | |
238 | | - | |
239 | | - | |
240 | | - | |
241 | | - | |
242 | | - | |
243 | | - | |
244 | | - | |
245 | | - | |
246 | | - | |
247 | | - | |
248 | | - | |
249 | | - | |
250 | | - | |
251 | | - | |
252 | | - | |
253 | | - | |
254 | | - | |
255 | | - | |
256 | | - | |
257 | | - | |
258 | 235 | | |
259 | 236 | | |
260 | 237 | | |
| |||
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
74 | 74 | | |
75 | 75 | | |
76 | 76 | | |
| 77 | + | |
77 | 78 | | |
78 | 79 | | |
79 | 80 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
50 | 56 | | |
51 | 57 | | |
52 | 58 | | |
| |||
Lines changed: 7 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
120 | 120 | | |
121 | 121 | | |
122 | 122 | | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
123 | 130 | | |
124 | 131 | | |
125 | 132 | | |
| |||
0 commit comments