|
32 | 32 | TransactionException, |
33 | 33 | TransactionReceipt, |
34 | 34 | ) |
| 35 | +from execution_testing import ( |
| 36 | + Macros as Om, |
| 37 | +) |
35 | 38 | from execution_testing.checklists import EIPChecklist |
36 | 39 |
|
37 | 40 | from .spec import ref_spec_8037 |
@@ -1113,26 +1116,6 @@ def test_top_level_failure_propagated_state_gas( |
1113 | 1116 | state_test(pre=pre, post={child: Account(storage={})}, tx=tx) |
1114 | 1117 |
|
1115 | 1118 |
|
1116 | | -def _store_data_in_memory(data: bytes, dest_offset: int = 0) -> Bytecode: |
1117 | | - """Place `data` in memory starting at `dest_offset` via 32-byte MSTOREs.""" |
1118 | | - code = Bytecode() |
1119 | | - chunk_size = 32 |
1120 | | - n = len(data) |
1121 | | - |
1122 | | - if n == 0: |
1123 | | - return code |
1124 | | - |
1125 | | - # Pad to a multiple of 32 with trailing zeros (CREATE size= |
1126 | | - # bounds the read). |
1127 | | - padded = data + b"\x00" * ((-n) % chunk_size) |
1128 | | - |
1129 | | - for i in range(0, len(padded), chunk_size): |
1130 | | - chunk = padded[i : i + chunk_size] |
1131 | | - code += Op.MSTORE(dest_offset + i, Op.PUSH32(chunk)) |
1132 | | - |
1133 | | - return code |
1134 | | - |
1135 | | - |
1136 | 1119 | def _build_call_chain( |
1137 | 1120 | pre: Alloc, |
1138 | 1121 | frame_bodies: list[Bytecode], |
@@ -1160,26 +1143,6 @@ def _build_call_chain( |
1160 | 1143 | return inner_addr, frame_codes |
1161 | 1144 |
|
1162 | 1145 |
|
1163 | | -def _create_chain_extra_regular_gas(frame_codes: list[Bytecode]) -> int: |
1164 | | - """ |
1165 | | - Extra regular gas not captured by `Bytecode.regular_cost(fork)` for a |
1166 | | - CREATE chain: MSTORE memory expansion to hold the next-level |
1167 | | - initcode + CREATE's `init_code_cost`. Both are dynamic costs that |
1168 | | - depend on the inner initcode size, so the static opcode calculator |
1169 | | - doesn't account for them. |
1170 | | - """ |
1171 | | - initcode_word_cost = 2 |
1172 | | - extra = 0 |
1173 | | - for i in range(len(frame_codes) - 1): |
1174 | | - inner_size = len(bytes(frame_codes[i + 1])) |
1175 | | - words = (inner_size + 31) // 32 |
1176 | | - # CREATE's init_code_cost (EIP-3860). |
1177 | | - extra += initcode_word_cost * words |
1178 | | - # Memory expansion from MSTOREs storing the next initcode. |
1179 | | - extra += 3 * words + (words * words) // 512 |
1180 | | - return extra |
1181 | | - |
1182 | | - |
1183 | 1146 | def _build_create_chain( |
1184 | 1147 | pre: Alloc, |
1185 | 1148 | frame_bodies: list[Bytecode], |
@@ -1207,10 +1170,21 @@ def _build_create_chain( |
1207 | 1170 | for i in range(n - 2, -1, -1): |
1208 | 1171 | inner_bytes = bytes(inner_initcode) |
1209 | 1172 | inner_size = len(inner_bytes) |
| 1173 | + # Pad to 32-byte alignment so Om.MSTORE uses the cheap |
| 1174 | + # PUSH32+MSTORE path on the trailing chunk; CREATE reads |
| 1175 | + # only `size` bytes so the trailing zeros are ignored. |
| 1176 | + padded = inner_bytes + b"\x00" * ((-inner_size) % 32) |
1210 | 1177 | code = ( |
1211 | 1178 | frame_bodies[i] |
1212 | | - + _store_data_in_memory(inner_bytes) |
1213 | | - + Op.POP(Op.CREATE(value=0, offset=0, size=inner_size)) |
| 1179 | + + Om.MSTORE(padded, 0) |
| 1180 | + + Op.POP( |
| 1181 | + Op.CREATE( |
| 1182 | + value=0, |
| 1183 | + offset=0, |
| 1184 | + size=inner_size, |
| 1185 | + init_code_size=inner_size, |
| 1186 | + ) |
| 1187 | + ) |
1214 | 1188 | + terminator |
1215 | 1189 | ) |
1216 | 1190 | frame_codes.insert(0, code) |
@@ -1398,10 +1372,6 @@ def test_nested_failure_resets_to_tx_reservoir( |
1398 | 1372 | non_top_burns = non_top_body_refund_burn + non_top_create_credit_burn |
1399 | 1373 |
|
1400 | 1374 | sum_regular = sum(code.regular_cost(fork) for code in frame_codes) |
1401 | | - if frame_op == "create": |
1402 | | - # Static calculator misses CREATE's memory expansion + |
1403 | | - # init_code_cost. Add them back to recover runtime regular gas. |
1404 | | - sum_regular += _create_chain_extra_regular_gas(frame_codes) |
1405 | 1375 | spill = max(0, total_state_charges - reservoir) |
1406 | 1376 | if failure_mode == "halt": |
1407 | 1377 | # Policy A (updated EIP): all state-gas — body charges, spilled |
|
0 commit comments