9
9
10
10
import pytest
11
11
12
+ from ethereum_test_benchmark .benchmark_code_generator import JumpLoopGenerator
12
13
from ethereum_test_forks import Fork
13
14
from ethereum_test_tools import (
14
15
Account ,
15
16
Alloc ,
17
+ BenchmarkTestFiller ,
16
18
Block ,
17
19
BlockchainTestFiller ,
18
20
Bytecode ,
21
+ Bytes ,
19
22
Environment ,
20
23
Hash ,
21
- StateTestFiller ,
22
24
Transaction ,
23
25
While ,
24
26
compute_create2_address ,
25
27
)
26
28
from ethereum_test_types .helpers import compute_create_address
27
29
from ethereum_test_vm import Opcodes as Op
28
30
29
- from .helpers import code_loop_precompile_call
30
-
31
31
REFERENCE_SPEC_GIT_PATH = "TODO"
32
32
REFERENCE_SPEC_VERSION = "TODO"
33
33
@@ -245,7 +245,7 @@ def test_worst_bytecode_single_opcode(
245
245
ids = lambda x : x .hex (),
246
246
)
247
247
def test_worst_initcode_jumpdest_analysis (
248
- state_test : StateTestFiller ,
248
+ benchmark_test : BenchmarkTestFiller ,
249
249
pre : Alloc ,
250
250
fork : Fork ,
251
251
pattern : Bytecode ,
@@ -260,7 +260,6 @@ def test_worst_initcode_jumpdest_analysis(
260
260
The initicode is modified by mixing-in the returned create address between CREATE invocations
261
261
to prevent caching.
262
262
"""
263
- max_code_size = fork .max_code_size ()
264
263
initcode_size = fork .max_initcode_size ()
265
264
266
265
# 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(
290
289
# Make sure the last opcode in the initcode is JUMPDEST.
291
290
code_prepare_initcode += Op .MSTORE (initcode_size - 32 , Op .PUSH32 [bytes (Op .JUMPDEST ) * 32 ])
292
291
293
- code_invoke_create = (
292
+ attack_block = (
294
293
Op .PUSH1 [len (initcode_prefix )]
295
294
+ Op .MSTORE
296
295
+ Op .CREATE (value = Op .PUSH0 , offset = Op .PUSH0 , size = Op .MSIZE )
297
296
)
298
297
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
310
299
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 )
317
304
318
- state_test (
305
+ benchmark_test (
319
306
pre = pre ,
320
307
post = {},
321
308
tx = tx ,
@@ -347,14 +334,13 @@ def test_worst_initcode_jumpdest_analysis(
347
334
],
348
335
)
349
336
def test_worst_create (
350
- state_test : StateTestFiller ,
337
+ benchmark_test : BenchmarkTestFiller ,
351
338
pre : Alloc ,
352
339
fork : Fork ,
353
340
opcode : Op ,
354
341
max_code_size_ratio : float ,
355
342
non_zero_data : bool ,
356
343
value : int ,
357
- gas_benchmark_value : int ,
358
344
):
359
345
"""Test the CREATE and CREATE2 performance with different configurations."""
360
346
max_code_size = fork .max_code_size ()
@@ -388,7 +374,7 @@ def test_worst_create(
388
374
# ...
389
375
# JUMP(#)
390
376
# ```
391
- code_prefix = (
377
+ setup = (
392
378
Op .PUSH3 (code_size )
393
379
+ Op .PUSH1 (value )
394
380
+ Op .EXTCODECOPY (
@@ -399,7 +385,7 @@ def test_worst_create(
399
385
400
386
if opcode == Op .CREATE2 :
401
387
# For CREATE2, we provide an initial salt.
402
- code_prefix = code_prefix + Op .PUSH1 (42 )
388
+ setup += Op .PUSH1 (42 )
403
389
404
390
attack_block = (
405
391
# For CREATE:
@@ -413,16 +399,18 @@ def test_worst_create(
413
399
# - DUP3 is targeting the EXTCODESIZE value pushed in code_prefix.
414
400
else Op .DUP3 + Op .PUSH0 + Op .DUP4 + Op .CREATE2
415
401
)
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
+ )
417
406
418
407
tx = Transaction (
419
408
# Set enough balance in the pre-alloc for `value > 0` configurations.
420
409
to = pre .deploy_contract (code = code , balance = 1_000_000_000 if value > 0 else 0 ),
421
- gas_limit = gas_benchmark_value ,
422
410
sender = pre .fund_eoa (),
423
411
)
424
412
425
- state_test (
413
+ benchmark_test (
426
414
pre = pre ,
427
415
post = {},
428
416
tx = tx ,
@@ -437,7 +425,7 @@ def test_worst_create(
437
425
],
438
426
)
439
427
def test_worst_creates_collisions (
440
- state_test : StateTestFiller ,
428
+ benchmark_test : BenchmarkTestFiller ,
441
429
pre : Alloc ,
442
430
fork : Fork ,
443
431
opcode : Op ,
@@ -468,14 +456,12 @@ def test_worst_creates_collisions(
468
456
# The CALL to the proxy contract needs at a minimum gas corresponding to the CREATE(2)
469
457
# plus extra required PUSH0s for arguments.
470
458
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 )
472
460
attack_block = Op .POP (
473
461
# DUP7 refers to the PUSH3 above.
474
462
# DUP7 refers to the proxy contract address.
475
463
Op .CALL (gas = Op .DUP7 , address = Op .DUP7 )
476
464
)
477
- code = code_loop_precompile_call (code_prefix , attack_block , fork )
478
- tx_target = pre .deploy_contract (code = code )
479
465
480
466
# (**) We deploy the contract that CREATE(2) will attempt to create so any attempt will fail.
481
467
if opcode == Op .CREATE2 :
@@ -488,14 +474,8 @@ def test_worst_creates_collisions(
488
474
addr = compute_create_address (address = proxy_contract , nonce = nonce )
489
475
pre .deploy_contract (address = addr , code = Op .INVALID )
490
476
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 (
498
478
pre = pre ,
499
479
post = {},
500
- tx = tx ,
480
+ code_generator = JumpLoopGenerator ( setup = setup , attack_block = attack_block ) ,
501
481
)
0 commit comments