Skip to content

Commit 2f74795

Browse files
refactor(benchmark): update worst bytecode scenario
1 parent 7706c82 commit 2f74795

File tree

1 file changed

+23
-43
lines changed

1 file changed

+23
-43
lines changed

tests/benchmark/test_worst_bytecode.py

Lines changed: 23 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,25 @@
99

1010
import pytest
1111

12+
from ethereum_test_benchmark.benchmark_code_generator import JumpLoopGenerator
1213
from ethereum_test_forks import Fork
1314
from ethereum_test_tools import (
1415
Account,
1516
Alloc,
17+
BenchmarkTestFiller,
1618
Block,
1719
BlockchainTestFiller,
1820
Bytecode,
21+
Bytes,
1922
Environment,
2023
Hash,
21-
StateTestFiller,
2224
Transaction,
2325
While,
2426
compute_create2_address,
2527
)
2628
from ethereum_test_types.helpers import compute_create_address
2729
from ethereum_test_vm import Opcodes as Op
2830

29-
from .helpers import code_loop_precompile_call
30-
3131
REFERENCE_SPEC_GIT_PATH = "TODO"
3232
REFERENCE_SPEC_VERSION = "TODO"
3333

@@ -245,7 +245,7 @@ def test_worst_bytecode_single_opcode(
245245
ids=lambda x: x.hex(),
246246
)
247247
def test_worst_initcode_jumpdest_analysis(
248-
state_test: StateTestFiller,
248+
benchmark_test: BenchmarkTestFiller,
249249
pre: Alloc,
250250
fork: Fork,
251251
pattern: Bytecode,
@@ -260,7 +260,6 @@ def test_worst_initcode_jumpdest_analysis(
260260
The initicode is modified by mixing-in the returned create address between CREATE invocations
261261
to prevent caching.
262262
"""
263-
max_code_size = fork.max_code_size()
264263
initcode_size = fork.max_initcode_size()
265264

266265
# Expand the initcode pattern to the transaction data so it can be used in CALLDATACOPY
@@ -290,32 +289,20 @@ def test_worst_initcode_jumpdest_analysis(
290289
# Make sure the last opcode in the initcode is JUMPDEST.
291290
code_prepare_initcode += Op.MSTORE(initcode_size - 32, Op.PUSH32[bytes(Op.JUMPDEST) * 32])
292291

293-
code_invoke_create = (
292+
attack_block = (
294293
Op.PUSH1[len(initcode_prefix)]
295294
+ Op.MSTORE
296295
+ Op.CREATE(value=Op.PUSH0, offset=Op.PUSH0, size=Op.MSIZE)
297296
)
298297

299-
initial_random = Op.PUSH0
300-
code_prefix = code_prepare_initcode + initial_random
301-
code_loop_header = Op.JUMPDEST
302-
code_loop_footer = Op.JUMP(len(code_prefix))
303-
code_loop_body_len = (
304-
max_code_size - len(code_prefix) - len(code_loop_header) - len(code_loop_footer)
305-
)
306-
307-
code_loop_body = (code_loop_body_len // len(code_invoke_create)) * bytes(code_invoke_create)
308-
code = code_prefix + code_loop_header + code_loop_body + code_loop_footer
309-
assert (max_code_size - len(code_invoke_create)) < len(code) <= max_code_size
298+
setup = code_prepare_initcode + Op.PUSH0
310299

311-
tx = Transaction(
312-
to=pre.deploy_contract(code=code),
313-
data=tx_data,
314-
gas_limit=gas_benchmark_value,
315-
sender=pre.fund_eoa(),
316-
)
300+
tx = JumpLoopGenerator(
301+
setup=setup, attack_block=attack_block, cleanup=Bytecode()
302+
).generate_transaction(pre, gas_benchmark_value, fork)
303+
tx.data = Bytes(tx_data)
317304

318-
state_test(
305+
benchmark_test(
319306
pre=pre,
320307
post={},
321308
tx=tx,
@@ -347,14 +334,13 @@ def test_worst_initcode_jumpdest_analysis(
347334
],
348335
)
349336
def test_worst_create(
350-
state_test: StateTestFiller,
337+
benchmark_test: BenchmarkTestFiller,
351338
pre: Alloc,
352339
fork: Fork,
353340
opcode: Op,
354341
max_code_size_ratio: float,
355342
non_zero_data: bool,
356343
value: int,
357-
gas_benchmark_value: int,
358344
):
359345
"""Test the CREATE and CREATE2 performance with different configurations."""
360346
max_code_size = fork.max_code_size()
@@ -388,7 +374,7 @@ def test_worst_create(
388374
# ...
389375
# JUMP(#)
390376
# ```
391-
code_prefix = (
377+
setup = (
392378
Op.PUSH3(code_size)
393379
+ Op.PUSH1(value)
394380
+ Op.EXTCODECOPY(
@@ -399,7 +385,7 @@ def test_worst_create(
399385

400386
if opcode == Op.CREATE2:
401387
# For CREATE2, we provide an initial salt.
402-
code_prefix = code_prefix + Op.PUSH1(42)
388+
setup += Op.PUSH1(42)
403389

404390
attack_block = (
405391
# For CREATE:
@@ -413,16 +399,18 @@ def test_worst_create(
413399
# - DUP3 is targeting the EXTCODESIZE value pushed in code_prefix.
414400
else Op.DUP3 + Op.PUSH0 + Op.DUP4 + Op.CREATE2
415401
)
416-
code = code_loop_precompile_call(code_prefix, attack_block, fork)
402+
403+
code = JumpLoopGenerator(setup=setup, attack_block=attack_block).generate_repeated_code(
404+
attack_block, Bytecode(), Bytecode(), fork
405+
)
417406

418407
tx = Transaction(
419408
# Set enough balance in the pre-alloc for `value > 0` configurations.
420409
to=pre.deploy_contract(code=code, balance=1_000_000_000 if value > 0 else 0),
421-
gas_limit=gas_benchmark_value,
422410
sender=pre.fund_eoa(),
423411
)
424412

425-
state_test(
413+
benchmark_test(
426414
pre=pre,
427415
post={},
428416
tx=tx,
@@ -437,7 +425,7 @@ def test_worst_create(
437425
],
438426
)
439427
def test_worst_creates_collisions(
440-
state_test: StateTestFiller,
428+
benchmark_test: BenchmarkTestFiller,
441429
pre: Alloc,
442430
fork: Fork,
443431
opcode: Op,
@@ -468,14 +456,12 @@ def test_worst_creates_collisions(
468456
# The CALL to the proxy contract needs at a minimum gas corresponding to the CREATE(2)
469457
# plus extra required PUSH0s for arguments.
470458
min_gas_required = gas_costs.G_CREATE + gas_costs.G_BASE * (3 if opcode == Op.CREATE else 4)
471-
code_prefix = Op.PUSH20(proxy_contract) + Op.PUSH3(min_gas_required)
459+
setup = Op.PUSH20(proxy_contract) + Op.PUSH3(min_gas_required)
472460
attack_block = Op.POP(
473461
# DUP7 refers to the PUSH3 above.
474462
# DUP7 refers to the proxy contract address.
475463
Op.CALL(gas=Op.DUP7, address=Op.DUP7)
476464
)
477-
code = code_loop_precompile_call(code_prefix, attack_block, fork)
478-
tx_target = pre.deploy_contract(code=code)
479465

480466
# (**) We deploy the contract that CREATE(2) will attempt to create so any attempt will fail.
481467
if opcode == Op.CREATE2:
@@ -488,14 +474,8 @@ def test_worst_creates_collisions(
488474
addr = compute_create_address(address=proxy_contract, nonce=nonce)
489475
pre.deploy_contract(address=addr, code=Op.INVALID)
490476

491-
tx = Transaction(
492-
to=tx_target,
493-
gas_limit=gas_benchmark_value,
494-
sender=pre.fund_eoa(),
495-
)
496-
497-
state_test(
477+
benchmark_test(
498478
pre=pre,
499479
post={},
500-
tx=tx,
480+
code_generator=JumpLoopGenerator(setup=setup, attack_block=attack_block),
501481
)

0 commit comments

Comments
 (0)