Skip to content

Commit e64b1b6

Browse files
feat(benchmark): add clz opcode test case (#1845)
* feat(benchmark): add clz benchmark with the same input * feat(benchmark): add clz benchmark with the diff input * refactor(benchmark): enhance clz benchmarks * refactor(benchmark): update clz test case for tx gas limit cap
1 parent be6aba4 commit e64b1b6

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

tests/benchmark/test_worst_compute.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
Block,
2323
BlockchainTestFiller,
2424
Bytecode,
25+
Environment,
2526
StateTestFiller,
2627
Transaction,
2728
add_kzg_version,
@@ -2723,3 +2724,97 @@ def test_worst_return_revert(
27232724
post={},
27242725
tx=tx,
27252726
)
2727+
2728+
2729+
@pytest.mark.valid_from("Osaka")
2730+
def test_worst_clz_same_input(
2731+
blockchain_test: BlockchainTestFiller,
2732+
pre: Alloc,
2733+
fork: Fork,
2734+
gas_benchmark_value: int,
2735+
env: Environment,
2736+
):
2737+
"""Test running a block with as many CLZ with same input as possible."""
2738+
tx_gas_limit = fork.transaction_gas_limit_cap() or env.gas_limit
2739+
2740+
magic_value = 248 # CLZ(248) = 248
2741+
2742+
calldata = Op.PUSH1(magic_value)
2743+
attack_block = Op.CLZ
2744+
code = code_loop_precompile_call(calldata, attack_block, fork)
2745+
assert len(code) <= fork.max_code_size()
2746+
2747+
code_address = pre.deploy_contract(code=code)
2748+
2749+
sender = pre.fund_eoa()
2750+
tx_count = gas_benchmark_value // tx_gas_limit
2751+
remainder_gas = gas_benchmark_value % tx_gas_limit
2752+
2753+
txs = [
2754+
Transaction(
2755+
to=code_address,
2756+
gas_limit=tx_gas_limit if i < tx_count else remainder_gas,
2757+
nonce=i,
2758+
sender=sender,
2759+
)
2760+
for i in range(tx_count + 1)
2761+
]
2762+
2763+
blockchain_test(
2764+
genesis_environment=env,
2765+
pre=pre,
2766+
post={},
2767+
blocks=[Block(txs=txs)],
2768+
)
2769+
2770+
2771+
@pytest.mark.valid_from("Osaka")
2772+
def test_worst_clz_diff_input(
2773+
blockchain_test: BlockchainTestFiller,
2774+
pre: Alloc,
2775+
fork: Fork,
2776+
gas_benchmark_value: int,
2777+
env: Environment,
2778+
):
2779+
"""Test running a block with as many CLZ with different input as possible."""
2780+
tx_gas_limit = fork.transaction_gas_limit_cap() or env.gas_limit
2781+
max_code_size = fork.max_code_size()
2782+
2783+
code_prefix = Op.JUMPDEST
2784+
code_suffix = Op.PUSH0 + Op.JUMP
2785+
2786+
available_code_size = max_code_size - len(code_prefix) - len(code_suffix)
2787+
2788+
code_seq = Bytecode()
2789+
2790+
for i in range(available_code_size):
2791+
value = (2**256 - 1) >> (i % 256)
2792+
clz_op = Op.CLZ(value) + Op.POP
2793+
if len(code_seq) + len(clz_op) > available_code_size:
2794+
break
2795+
code_seq += clz_op
2796+
2797+
attack_code = code_prefix + code_seq + code_suffix
2798+
assert len(attack_code) <= max_code_size
2799+
2800+
code_address = pre.deploy_contract(code=attack_code)
2801+
2802+
sender = pre.fund_eoa()
2803+
tx_count = gas_benchmark_value // tx_gas_limit
2804+
remainder_gas = gas_benchmark_value % tx_gas_limit
2805+
txs = [
2806+
Transaction(
2807+
to=code_address,
2808+
gas_limit=tx_gas_limit if i < tx_count else remainder_gas,
2809+
nonce=i,
2810+
sender=sender,
2811+
)
2812+
for i in range(tx_count + 1)
2813+
]
2814+
2815+
blockchain_test(
2816+
genesis_environment=env,
2817+
pre=pre,
2818+
post={},
2819+
blocks=[Block(txs=txs)],
2820+
)

0 commit comments

Comments
 (0)