|
1 | 1 | """Test the pre_alloc_group marker functionality."""
|
2 | 2 |
|
| 3 | +import textwrap |
| 4 | +from pathlib import Path |
| 5 | +from typing import List |
3 | 6 | from unittest.mock import Mock
|
4 | 7 |
|
| 8 | +import pytest |
| 9 | + |
| 10 | +from ethereum_clis import TransitionTool |
5 | 11 | from ethereum_test_forks import Fork, Prague
|
6 | 12 | from ethereum_test_specs.base import BaseTest
|
7 | 13 | from ethereum_test_types import Alloc, Environment
|
8 | 14 |
|
| 15 | +from ..filler import default_output_directory |
| 16 | + |
9 | 17 |
|
10 | 18 | class MockTest(BaseTest):
|
11 | 19 | """Mock test class for testing."""
|
@@ -193,3 +201,152 @@ def test_pre_alloc_group_with_reason():
|
193 | 201 |
|
194 | 202 | # Hashes should be the same - reason doesn't affect grouping
|
195 | 203 | assert hash1 == hash2
|
| 204 | + |
| 205 | + |
| 206 | +state_test_diff_envs = textwrap.dedent( |
| 207 | + """\ |
| 208 | + import pytest |
| 209 | +
|
| 210 | + from ethereum_test_tools import ( |
| 211 | + Account, |
| 212 | + Alloc, |
| 213 | + Environment, |
| 214 | + StateTestFiller, |
| 215 | + Transaction |
| 216 | + ) |
| 217 | + from ethereum_test_tools.vm.opcode import Opcodes as Op |
| 218 | +
|
| 219 | +
|
| 220 | + @pytest.mark.valid_from("Istanbul") |
| 221 | + def test_chainid(state_test: StateTestFiller, pre: Alloc): |
| 222 | + contract_address = pre.deploy_contract(Op.SSTORE(1, Op.CHAINID) + Op.STOP) |
| 223 | + sender = pre.fund_eoa() |
| 224 | +
|
| 225 | + tx = Transaction( |
| 226 | + ty=0x0, |
| 227 | + chain_id=0x01, |
| 228 | + to=contract_address, |
| 229 | + gas_limit=100_000, |
| 230 | + sender=sender, |
| 231 | + ) |
| 232 | +
|
| 233 | + post = {{ |
| 234 | + contract_address: Account(storage={{"0x01": "0x01"}}), |
| 235 | + }} |
| 236 | +
|
| 237 | + state_test(env={env}, pre=pre, post=post, tx=tx) |
| 238 | + """ |
| 239 | +) |
| 240 | + |
| 241 | + |
| 242 | +@pytest.mark.parametrize( |
| 243 | + "environment_definitions,expected_different_pre_alloc_groups", |
| 244 | + [ |
| 245 | + # Environment fields not affecting the pre-alloc groups |
| 246 | + pytest.param( |
| 247 | + [ |
| 248 | + "Environment(fee_recipient=pre.fund_eoa(amount=0))", |
| 249 | + "Environment(fee_recipient=1)", |
| 250 | + "Environment(fee_recipient=2)", |
| 251 | + ], |
| 252 | + 1, |
| 253 | + id="different_fee_recipients", |
| 254 | + ), |
| 255 | + pytest.param( |
| 256 | + [ |
| 257 | + "Environment(prev_randao=1)", |
| 258 | + "Environment(prev_randao=2)", |
| 259 | + ], |
| 260 | + 1, |
| 261 | + id="different_prev_randaos", |
| 262 | + ), |
| 263 | + pytest.param( |
| 264 | + [ |
| 265 | + "Environment(timestamp=1)", |
| 266 | + "Environment(timestamp=2)", |
| 267 | + ], |
| 268 | + 1, |
| 269 | + id="different_timestamps", |
| 270 | + ), |
| 271 | + pytest.param( |
| 272 | + [ |
| 273 | + "Environment(extra_data='0x01')", |
| 274 | + "Environment(extra_data='0x02')", |
| 275 | + ], |
| 276 | + 1, |
| 277 | + id="different_extra_data", |
| 278 | + ), |
| 279 | + # Environment fields affecting the pre-alloc groups |
| 280 | + pytest.param( |
| 281 | + [ |
| 282 | + "Environment(gas_limit=100_000_000)", |
| 283 | + "Environment(gas_limit=200_000_000)", |
| 284 | + ], |
| 285 | + 2, |
| 286 | + id="different_gas_limits", |
| 287 | + ), |
| 288 | + pytest.param( |
| 289 | + [ |
| 290 | + "Environment(number=10)", |
| 291 | + "Environment(number=20)", |
| 292 | + ], |
| 293 | + 2, |
| 294 | + id="different_block_numbers", |
| 295 | + ), |
| 296 | + pytest.param( |
| 297 | + [ |
| 298 | + "Environment(base_fee_per_gas=10)", |
| 299 | + "Environment(base_fee_per_gas=20)", |
| 300 | + ], |
| 301 | + 2, |
| 302 | + id="different_base_fee", |
| 303 | + ), |
| 304 | + pytest.param( |
| 305 | + [ |
| 306 | + "Environment(excess_blob_gas=10)", |
| 307 | + "Environment(excess_blob_gas=20)", |
| 308 | + ], |
| 309 | + 2, |
| 310 | + id="different_excess_blob_gas", |
| 311 | + ), |
| 312 | + ], |
| 313 | +) |
| 314 | +def test_state_tests_pre_alloc_grouping( |
| 315 | + pytester: pytest.Pytester, |
| 316 | + default_t8n: TransitionTool, |
| 317 | + environment_definitions: List[str], |
| 318 | + expected_different_pre_alloc_groups: int, |
| 319 | +): |
| 320 | + """Test pre-alloc grouping when filling state tests, and the effect of the `state_test.env`.""" |
| 321 | + tests_dir = Path(pytester.mkdir("tests")) |
| 322 | + for i, env in enumerate(environment_definitions): |
| 323 | + test_module = tests_dir / f"test_state_test_{i}.py" |
| 324 | + test_module.write_text(state_test_diff_envs.format(env=env)) |
| 325 | + pytester.copy_example(name="src/cli/pytest_commands/pytest_ini_files/pytest-fill.ini") |
| 326 | + args = [ |
| 327 | + "-c", |
| 328 | + "pytest-fill.ini", |
| 329 | + "--generate-pre-alloc-groups", |
| 330 | + "--fork=Cancun", |
| 331 | + "--t8n-server-url", |
| 332 | + ] |
| 333 | + assert default_t8n.server_url is not None |
| 334 | + args.append(default_t8n.server_url) |
| 335 | + result = pytester.runpytest(*args) |
| 336 | + result.assert_outcomes( |
| 337 | + passed=len(environment_definitions), |
| 338 | + failed=0, |
| 339 | + skipped=0, |
| 340 | + errors=0, |
| 341 | + ) |
| 342 | + |
| 343 | + output_dir = ( |
| 344 | + Path(default_output_directory()).absolute() / "blockchain_tests_engine_x" / "pre_alloc" |
| 345 | + ) |
| 346 | + assert output_dir.exists() |
| 347 | + |
| 348 | + # All different environments should only generate a single genesis pre-alloc |
| 349 | + assert ( |
| 350 | + len([f for f in output_dir.iterdir() if f.name.endswith(".json")]) |
| 351 | + == expected_different_pre_alloc_groups |
| 352 | + ) |
0 commit comments