Skip to content

Commit 3be4d6f

Browse files
authored
tests(zkvm): allow using entire gas in bytecode attack (#1575)
* zkvm: full bytecode attack enabling Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com> * set gas limit in ci Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com> * add slow mark Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com> --------- Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
1 parent cc9a56a commit 3be4d6f

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

.github/configs/feature.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ static:
1313
solc: 0.8.21
1414
zkevm:
1515
evm-type: zkevm
16-
fill-params: --from=Cancun --until=Prague -m zkevm ./tests
16+
fill-params: --from=Cancun --until=Prague --block-gas-limit 36000000 -m zkevm ./tests
1717
solc: 0.8.21
1818
feature_only: true
1919
eip7692:
2020
evm-type: eip7692
2121
fill-params: --fork=EOFv1 ./tests/unscheduled
2222
solc: 0.8.21
2323
eofwrap: true
24-
feature_only: true
24+
feature_only: true

tests/zkevm/test_worst_bytecode.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@
2727
REFERENCE_SPEC_VERSION = "TODO"
2828

2929
MAX_CONTRACT_SIZE = 24 * 1024 # TODO: This could be a fork property
30-
BLOCK_GAS_LIMIT = 36_000_000 # TODO: Parametrize using the (yet to be implemented) block gas limit
31-
# OPCODE_GAS_LIMIT = BLOCK_GAS_LIMIT # TODO: Reduced in order to run the test in a reasonable time
32-
OPCODE_GAS_LIMIT = 100_000
3330

3431
XOR_TABLE_SIZE = 256
3532
XOR_TABLE = [Hash(i).sha256() for i in range(XOR_TABLE_SIZE)]
@@ -41,12 +38,20 @@
4138
Op.EXTCODESIZE,
4239
],
4340
)
41+
@pytest.mark.parametrize(
42+
"attack_gas_limit",
43+
[
44+
Environment().gas_limit,
45+
],
46+
)
47+
@pytest.mark.slow()
4448
@pytest.mark.valid_from("Cancun")
4549
def test_worst_bytecode_single_opcode(
4650
blockchain_test: BlockchainTestFiller,
4751
pre: Alloc,
4852
fork: Fork,
4953
opcode: Op,
54+
attack_gas_limit: int,
5055
):
5156
"""
5257
Test a block execution where a single opcode execution maxes out the gas limit,
@@ -60,7 +65,9 @@ def test_worst_bytecode_single_opcode(
6065
The test is performed in the last block of the test, and the entire block gas limit is
6166
consumed by repeated opcode executions.
6267
"""
63-
env = Environment(gas_limit=BLOCK_GAS_LIMIT)
68+
# We use 100G gas limit to be able to deploy a large number of contracts in a single block,
69+
# avoiding bloating the number of preparing blocks in the test.
70+
env = Environment(gas_limit=100_000_000_000)
6471

6572
# The initcode will take its address as a starting point to the input to the keccak
6673
# hash function.
@@ -126,19 +133,19 @@ def test_worst_bytecode_single_opcode(
126133
)
127134
max_number_of_contract_calls = (
128135
# Base available gas = GAS_LIMIT - intrinsic - (out of loop MSTOREs)
129-
OPCODE_GAS_LIMIT - intrinsic_gas_cost_calc() - gas_costs.G_VERY_LOW * 4
136+
attack_gas_limit - intrinsic_gas_cost_calc() - gas_costs.G_VERY_LOW * 4
130137
) // loop_cost
131138

132139
total_contracts_to_deploy = max_number_of_contract_calls
133140
approximate_gas_per_deployment = 4_970_000 # Obtained from evm tracing
134-
contracts_deployed_per_tx = BLOCK_GAS_LIMIT // approximate_gas_per_deployment
141+
contracts_deployed_per_tx = env.gas_limit // approximate_gas_per_deployment
135142

136143
deploy_txs = []
137144

138145
def generate_deploy_tx(contracts_to_deploy: int):
139146
return Transaction(
140147
to=factory_caller_address,
141-
gas_limit=BLOCK_GAS_LIMIT,
148+
gas_limit=env.gas_limit,
142149
gas_price=10**9, # Bump required due to the amount of full blocks
143150
data=Hash(contracts_deployed_per_tx),
144151
sender=pre.fund_eoa(),
@@ -171,8 +178,7 @@ def generate_deploy_tx(contracts_to_deploy: int):
171178
+ Op.MSTORE(64, initcode.keccak256())
172179
# Main loop
173180
+ While(
174-
body=Op.POP(Op.EXTCODESIZE(Op.SHA3(32 - 20 - 1, 85)))
175-
+ Op.MSTORE(32, Op.ADD(Op.MLOAD(32), 1)),
181+
body=Op.POP(opcode(Op.SHA3(32 - 20 - 1, 85))) + Op.MSTORE(32, Op.ADD(Op.MLOAD(32), 1)),
176182
)
177183
)
178184

@@ -185,7 +191,7 @@ def generate_deploy_tx(contracts_to_deploy: int):
185191
opcode_address = pre.deploy_contract(code=opcode_code)
186192
opcode_tx = Transaction(
187193
to=opcode_address,
188-
gas_limit=OPCODE_GAS_LIMIT,
194+
gas_limit=attack_gas_limit,
189195
gas_price=10**9, # Bump required due to the amount of full blocks
190196
sender=pre.fund_eoa(),
191197
)
@@ -198,4 +204,5 @@ def generate_deploy_tx(contracts_to_deploy: int):
198204
*[Block(txs=[deploy_tx]) for deploy_tx in deploy_txs],
199205
Block(txs=[opcode_tx]),
200206
],
207+
exclude_full_post_state_in_output=True,
201208
)

0 commit comments

Comments
 (0)