Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,33 @@ def _process_with_marker_args(self) -> Set[Fork]:
return resulting_set


class ValidForBlobForks(
ValidityMarker, marker_name="valid_for_blob_forks", flag=True
):
"""
Marker to specify that a test is only valid for forks that support blobs.

```python
import pytest

@pytest.mark.valid_for_blob_forks()
def test_blob_feature(state_test):
pass
```
"""

def _process_with_marker_args(self) -> Set[Fork]:
"""Exclude blobless forks when the marker is present."""
if self.mark is None:
return set()
resulting_set: Set[Fork] = set()
for fork in ALL_FORKS:
if not fork.supports_blobs():
resulting_set.add(fork)
resulting_set |= transition_fork_to(fork)
return resulting_set


def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
"""Pytest hook used to dynamically generate test cases."""
test_name = metafunc.function.__name__
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,24 @@ def test_case(state_test):
{"passed": 1, "failed": 0, "skipped": 0, "errors": 0},
id="valid_at_transition_to_from_fork_until_later_fork",
),
pytest.param(
generate_test(
valid_from='"Cancun"',
valid_for_blob_forks="",
),
["--fork=Prague"],
{"passed": 1, "failed": 0, "skipped": 0, "errors": 0},
id="valid_for_blob_forks_prague",
),
pytest.param(
generate_test(
valid_from='"Cancun"',
valid_for_blob_forks="",
),
["--fork=MONAD_EIGHT"],
{"passed": 0, "failed": 0, "skipped": 0, "errors": 0},
id="valid_for_blob_forks_monad_eight",
),
pytest.param(
generate_test(
valid_at_transition_to='"BPO1"',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ def pytest_configure(config: pytest.Config) -> None:
"markers",
"valid_for_bpo_forks: Marks a test as valid for BPO forks",
)
config.addinivalue_line(
"markers",
"valid_for_blob_forks: Marks a test as valid only for forks that support blobs",
)
config.addinivalue_line(
"markers",
"mainnet: Specialty tests crafted for running on mainnet and sanity checking.",
Expand Down
74 changes: 74 additions & 0 deletions packages/testing/src/execution_testing/forks/forks/forks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2348,6 +2348,80 @@ def blob_base_cost(
class MONAD_EIGHT(Prague, solc_name="cancun"):
"""MONAD_EIGHT fork."""

@classmethod
def header_excess_blob_gas_required(
cls, *, block_number: int = 0, timestamp: int = 0
) -> bool:
"""
MONAD_EIGHT does not include blob header fields.

Monad keeps the point-evaluation precompile but does not support blob
transactions or blob gas accounting.
"""
del block_number, timestamp
return False

@classmethod
def header_blob_gas_used_required(
cls, *, block_number: int = 0, timestamp: int = 0
) -> bool:
"""MONAD_EIGHT does not include blob header fields."""
del block_number, timestamp
return False

@classmethod
def supports_blobs(
cls, *, block_number: int = 0, timestamp: int = 0
) -> bool:
"""MONAD_EIGHT does not support blob transactions."""
del block_number, timestamp
return False

@classmethod
def tx_types(
cls, *, block_number: int = 0, timestamp: int = 0
) -> List[int]:
"""Return Prague transaction types without blob transactions."""
return [
tx_type
for tx_type in super(MONAD_EIGHT, cls).tx_types(
block_number=block_number, timestamp=timestamp
)
if tx_type != 3
]

@classmethod
def full_blob_tx_wrapper_version(
cls, *, block_number: int = 0, timestamp: int = 0
) -> int | None:
"""MONAD_EIGHT does not wrap full blob transactions."""
del block_number, timestamp
return None

@classmethod
def blob_schedule(
cls, *, block_number: int = 0, timestamp: int = 0
) -> BlobSchedule | None:
"""MONAD_EIGHT does not advertise a blob schedule."""
del block_number, timestamp
return None

@classmethod
def engine_get_blobs_version(
cls, *, block_number: int = 0, timestamp: int = 0
) -> Optional[int]:
"""MONAD_EIGHT does not expose blob retrieval over the engine API."""
del block_number, timestamp
return None

@classmethod
def engine_new_payload_blob_hashes(
cls, *, block_number: int = 0, timestamp: int = 0
) -> bool:
"""MONAD_EIGHT payloads do not include blob hashes."""
del block_number, timestamp
return False

@classmethod
def precompiles(
cls, *, block_number: int = 0, timestamp: int = 0
Expand Down
13 changes: 13 additions & 0 deletions packages/testing/src/execution_testing/forks/tests/test_forks.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
Homestead,
Istanbul,
London,
MONAD_EIGHT,
Osaka,
Paris,
Prague,
Expand Down Expand Up @@ -394,6 +395,18 @@ def test_tx_types() -> None: # noqa: D103
Cancun.tx_types() == list(range(4)) # noqa: B015


def test_monad_eight_disables_blob_support() -> None:
"""MONAD_EIGHT keeps the KZG precompile but does not support blob txs."""
assert MONAD_EIGHT.supports_blobs() is False
assert MONAD_EIGHT.header_excess_blob_gas_required() is False
assert MONAD_EIGHT.header_blob_gas_used_required() is False
assert MONAD_EIGHT.blob_schedule() is None
assert MONAD_EIGHT.engine_get_blobs_version() is None
assert MONAD_EIGHT.engine_new_payload_blob_hashes() is False
assert MONAD_EIGHT.full_blob_tx_wrapper_version() is None
assert 3 not in MONAD_EIGHT.tx_types()


@pytest.mark.parametrize(
"fork",
[
Expand Down
4 changes: 4 additions & 0 deletions packages/testing/src/execution_testing/specs/blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,7 @@ def make_hive_fixture(
!= BlockchainEngineXFixture,
)
alloc: Alloc | LazyAlloc = pre
senders_authorities: dict[int, list[Address]] = {}
state_root = genesis.header.state_root
env = environment_from_parent_header(genesis.header)
head_hash = genesis.header.block_hash
Expand All @@ -898,13 +899,15 @@ def make_hive_fixture(
block=block,
previous_env=env,
previous_alloc=alloc,
previous_senders_authorities=senders_authorities,
last_block=i == len(self.blocks) - 1,
)
fixture_payloads.append(
built_block.get_fixture_engine_new_payload()
)
if block.exception is None:
alloc = built_block.alloc
senders_authorities = built_block.senders_authorities
state_root = built_block.state_root
env = apply_new_parent(built_block.env, built_block.header)
head_hash = built_block.header.block_hash
Expand Down Expand Up @@ -980,6 +983,7 @@ def make_hive_fixture(
block=Block(),
previous_env=env,
previous_alloc=alloc,
previous_senders_authorities=senders_authorities,
last_block=False,
)
fixture_data.update(
Expand Down
2 changes: 2 additions & 0 deletions packages/testing/src/execution_testing/specs/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ def verify_modified_gas_limit(
modified_tool_output = t8n.evaluate(
transition_tool_data=TransitionTool.TransitionToolData(
alloc=pre_alloc,
senders_authorities={},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% sure, but if you switch target to forks/monad_nine, these diffs should be gone.

txs=[new_tx],
env=env,
fork=fork,
Expand Down Expand Up @@ -352,6 +353,7 @@ def make_state_test_fixture(
transition_tool_output = t8n.evaluate(
transition_tool_data=TransitionTool.TransitionToolData(
alloc=pre_alloc,
senders_authorities={},
txs=[tx],
env=env,
fork=fork,
Expand Down
2 changes: 2 additions & 0 deletions tests/cancun/eip4844_blobs/test_blob_txs.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
REFERENCE_SPEC_GIT_PATH = ref_spec_4844.git_path
REFERENCE_SPEC_VERSION = ref_spec_4844.version

pytestmark = pytest.mark.valid_for_blob_forks()


@pytest.fixture
def destination_account_code() -> Bytecode | None:
Expand Down
2 changes: 2 additions & 0 deletions tests/cancun/eip4844_blobs/test_blob_txs_full.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
REFERENCE_SPEC_GIT_PATH = ref_spec_4844.git_path
REFERENCE_SPEC_VERSION = ref_spec_4844.version

pytestmark = pytest.mark.valid_for_blob_forks()


@pytest.fixture
def destination_account() -> Address:
Expand Down
5 changes: 4 additions & 1 deletion tests/cancun/eip4844_blobs/test_blobhash_opcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@
REFERENCE_SPEC_GIT_PATH = ref_spec_4844.git_path
REFERENCE_SPEC_VERSION = ref_spec_4844.version

pytestmark = pytest.mark.valid_from("Cancun")
pytestmark = [
pytest.mark.valid_from("Cancun"),
pytest.mark.valid_for_blob_forks(),
]


# Blobhash index values for test_blobhash_gas_cost
Expand Down
5 changes: 4 additions & 1 deletion tests/cancun/eip4844_blobs/test_blobhash_opcode_contexts.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@
REFERENCE_SPEC_GIT_PATH = ref_spec_4844.git_path
REFERENCE_SPEC_VERSION = ref_spec_4844.version

pytestmark = pytest.mark.valid_from("Cancun")
pytestmark = [
pytest.mark.valid_from("Cancun"),
pytest.mark.valid_for_blob_forks(),
]


class BlobhashContext(Enum):
Expand Down
6 changes: 4 additions & 2 deletions tests/cancun/eip4844_blobs/test_excess_blob_gas.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@
REFERENCE_SPEC_GIT_PATH = ref_spec_4844.git_path
REFERENCE_SPEC_VERSION = ref_spec_4844.version

# All tests run from Cancun fork
pytestmark = pytest.mark.valid_from("Cancun")
pytestmark = [
pytest.mark.valid_for_blob_forks(),
pytest.mark.valid_from("Cancun"),
]


@pytest.fixture
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
REFERENCE_SPEC_GIT_PATH = ref_spec_4844.git_path
REFERENCE_SPEC_VERSION = ref_spec_4844.version

pytestmark = pytest.mark.valid_for_blob_forks()

# Timestamp of the fork
FORK_TIMESTAMP = 15_000
BASE_FEE_MAX_CHANGE_DENOMINATOR = 8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
REFERENCE_SPEC_GIT_PATH = ref_spec_4844.git_path
REFERENCE_SPEC_VERSION = ref_spec_4844.version

pytestmark = pytest.mark.valid_for_blob_forks()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KZG precompile tests incorrectly excluded from MONAD_EIGHT

The valid_for_blob_forks() marker here will suppress all tests in this file when running against MONAD_EIGHT, but the tests don't require blob transactions — they only call the KZG point-evaluation precompile via regular state transactions.

Since MONAD_EIGHT explicitly retains the KZG precompile (documented in forks.py line 2358: "Monad keeps the point-evaluation precompile"), these tests should remain valid for that fork.

Same issue in: tests/cancun/eip4844_blobs/test_point_evaluation_precompile_gas.py (line 31)

Recommendation: Either remove the valid_for_blob_forks() marker from both files, or introduce a narrower marker (e.g. valid_for_blob_txs) that distinguishes "requires blob transactions" from "requires blob infrastructure".

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bot has a point here (and next file too)



class Result(str, Enum):
"""Result of the point evaluation precompile."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
REFERENCE_SPEC_GIT_PATH = ref_spec_4844.git_path
REFERENCE_SPEC_VERSION = ref_spec_4844.version

pytestmark = pytest.mark.valid_for_blob_forks()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KZG precompile gas tests incorrectly excluded from MONAD_EIGHT

Same issue as in test_point_evaluation_precompile.py: This file only uses StateTestFiller with regular (non-blob) transactions to call the point-evaluation precompile. Since MONAD_EIGHT retains the KZG precompile, the valid_for_blob_forks() marker here silently drops gas-cost coverage for that fork without functional justification.

See also: tests/cancun/eip4844_blobs/test_point_evaluation_precompile.py (line 63)



@pytest.fixture
def precompile_input(proof: Literal["correct", "incorrect"]) -> bytes:
Expand Down