|
22 | 22 | Block,
|
23 | 23 | BlockchainTestFiller,
|
24 | 24 | Bytecode,
|
| 25 | + Environment, |
25 | 26 | StateTestFiller,
|
26 | 27 | Transaction,
|
27 | 28 | add_kzg_version,
|
@@ -2723,3 +2724,97 @@ def test_worst_return_revert(
|
2723 | 2724 | post={},
|
2724 | 2725 | tx=tx,
|
2725 | 2726 | )
|
| 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