10
10
import pytest
11
11
12
12
from ethereum_test_forks import Fork
13
- from ethereum_test_tools import (
14
- Account ,
15
- Alloc ,
16
- Block ,
17
- BlockchainTestFiller ,
18
- Environment ,
19
- Hash ,
20
- Transaction ,
21
- While ,
22
- compute_create2_address ,
23
- )
13
+ from ethereum_test_tools import (Account , Alloc , Block , BlockchainTestFiller ,
14
+ Environment , Hash , Transaction , While ,
15
+ compute_create2_address )
24
16
from ethereum_test_tools .vm .opcode import Opcodes as Op
25
17
26
18
REFERENCE_SPEC_GIT_PATH = "TODO"
27
19
REFERENCE_SPEC_VERSION = "TODO"
28
20
29
21
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
22
34
23
XOR_TABLE_SIZE = 256
35
24
XOR_TABLE = [Hash (i ).sha256 () for i in range (XOR_TABLE_SIZE )]
41
30
Op .EXTCODESIZE ,
42
31
],
43
32
)
33
+ @pytest .mark .parametrize (
34
+ "attack_gas_limit" ,
35
+ [
36
+ Environment ().gas_limit ,
37
+ ],
38
+ )
44
39
@pytest .mark .valid_from ("Cancun" )
45
40
def test_worst_bytecode_single_opcode (
46
41
blockchain_test : BlockchainTestFiller ,
47
42
pre : Alloc ,
48
43
fork : Fork ,
49
44
opcode : Op ,
45
+ attack_gas_limit : int ,
50
46
):
51
47
"""
52
48
Test a block execution where a single opcode execution maxes out the gas limit,
@@ -60,7 +56,9 @@ def test_worst_bytecode_single_opcode(
60
56
The test is performed in the last block of the test, and the entire block gas limit is
61
57
consumed by repeated opcode executions.
62
58
"""
63
- env = Environment (gas_limit = BLOCK_GAS_LIMIT )
59
+ # We use 100G gas limit to be able to deploy a large number of contracts in a single block,
60
+ # avoiding bloating the number of preparing blocks in the test.
61
+ env = Environment (gas_limit = 100_000_000_000 )
64
62
65
63
# The initcode will take its address as a starting point to the input to the keccak
66
64
# hash function.
@@ -126,7 +124,7 @@ def test_worst_bytecode_single_opcode(
126
124
)
127
125
max_number_of_contract_calls = (
128
126
# Base available gas = GAS_LIMIT - intrinsic - (out of loop MSTOREs)
129
- OPCODE_GAS_LIMIT - intrinsic_gas_cost_calc () - gas_costs .G_VERY_LOW * 4
127
+ attack_gas_limit - intrinsic_gas_cost_calc () - gas_costs .G_VERY_LOW * 4
130
128
) // loop_cost
131
129
132
130
total_contracts_to_deploy = max_number_of_contract_calls
@@ -171,8 +169,7 @@ def generate_deploy_tx(contracts_to_deploy: int):
171
169
+ Op .MSTORE (64 , initcode .keccak256 ())
172
170
# Main loop
173
171
+ While (
174
- body = Op .POP (Op .EXTCODESIZE (Op .SHA3 (32 - 20 - 1 , 85 )))
175
- + Op .MSTORE (32 , Op .ADD (Op .MLOAD (32 ), 1 )),
172
+ body = Op .POP (opcode (Op .SHA3 (32 - 20 - 1 , 85 ))) + Op .MSTORE (32 , Op .ADD (Op .MLOAD (32 ), 1 )),
176
173
)
177
174
)
178
175
@@ -185,7 +182,7 @@ def generate_deploy_tx(contracts_to_deploy: int):
185
182
opcode_address = pre .deploy_contract (code = opcode_code )
186
183
opcode_tx = Transaction (
187
184
to = opcode_address ,
188
- gas_limit = OPCODE_GAS_LIMIT ,
185
+ gas_limit = attack_gas_limit ,
189
186
gas_price = 10 ** 9 , # Bump required due to the amount of full blocks
190
187
sender = pre .fund_eoa (),
191
188
)
@@ -198,4 +195,5 @@ def generate_deploy_tx(contracts_to_deploy: int):
198
195
* [Block (txs = [deploy_tx ]) for deploy_tx in deploy_txs ],
199
196
Block (txs = [opcode_tx ]),
200
197
],
198
+ exclude_full_post_state_in_output = True ,
201
199
)
0 commit comments