27
27
REFERENCE_SPEC_VERSION = "TODO"
28
28
29
29
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
33
30
34
31
XOR_TABLE_SIZE = 256
35
32
XOR_TABLE = [Hash (i ).sha256 () for i in range (XOR_TABLE_SIZE )]
41
38
Op .EXTCODESIZE ,
42
39
],
43
40
)
41
+ @pytest .mark .parametrize (
42
+ "attack_gas_limit" ,
43
+ [
44
+ Environment ().gas_limit ,
45
+ ],
46
+ )
47
+ @pytest .mark .slow ()
44
48
@pytest .mark .valid_from ("Cancun" )
45
49
def test_worst_bytecode_single_opcode (
46
50
blockchain_test : BlockchainTestFiller ,
47
51
pre : Alloc ,
48
52
fork : Fork ,
49
53
opcode : Op ,
54
+ attack_gas_limit : int ,
50
55
):
51
56
"""
52
57
Test a block execution where a single opcode execution maxes out the gas limit,
@@ -60,7 +65,9 @@ def test_worst_bytecode_single_opcode(
60
65
The test is performed in the last block of the test, and the entire block gas limit is
61
66
consumed by repeated opcode executions.
62
67
"""
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 )
64
71
65
72
# The initcode will take its address as a starting point to the input to the keccak
66
73
# hash function.
@@ -126,19 +133,19 @@ def test_worst_bytecode_single_opcode(
126
133
)
127
134
max_number_of_contract_calls = (
128
135
# 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
130
137
) // loop_cost
131
138
132
139
total_contracts_to_deploy = max_number_of_contract_calls
133
140
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
135
142
136
143
deploy_txs = []
137
144
138
145
def generate_deploy_tx (contracts_to_deploy : int ):
139
146
return Transaction (
140
147
to = factory_caller_address ,
141
- gas_limit = BLOCK_GAS_LIMIT ,
148
+ gas_limit = env . gas_limit ,
142
149
gas_price = 10 ** 9 , # Bump required due to the amount of full blocks
143
150
data = Hash (contracts_deployed_per_tx ),
144
151
sender = pre .fund_eoa (),
@@ -171,8 +178,7 @@ def generate_deploy_tx(contracts_to_deploy: int):
171
178
+ Op .MSTORE (64 , initcode .keccak256 ())
172
179
# Main loop
173
180
+ 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 )),
176
182
)
177
183
)
178
184
@@ -185,7 +191,7 @@ def generate_deploy_tx(contracts_to_deploy: int):
185
191
opcode_address = pre .deploy_contract (code = opcode_code )
186
192
opcode_tx = Transaction (
187
193
to = opcode_address ,
188
- gas_limit = OPCODE_GAS_LIMIT ,
194
+ gas_limit = attack_gas_limit ,
189
195
gas_price = 10 ** 9 , # Bump required due to the amount of full blocks
190
196
sender = pre .fund_eoa (),
191
197
)
@@ -198,4 +204,5 @@ def generate_deploy_tx(contracts_to_deploy: int):
198
204
* [Block (txs = [deploy_tx ]) for deploy_tx in deploy_txs ],
199
205
Block (txs = [opcode_tx ]),
200
206
],
207
+ exclude_full_post_state_in_output = True ,
201
208
)
0 commit comments