Skip to content
Merged
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
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Test fixtures for use by clients are available for each release on the [Github r
- ✨ New EIP-7702 test cases added ([#1974](https://github.com/ethereum/execution-specs/pull/1974)).
- ✨ Add missing benchmark configurations / opcode to benchmark tests for repricing analysis([#2006](https://github.com/ethereum/execution-specs/pull/2006)).
- ✨ Port STATICCALL to CALL tests with zero and non-zero value transfer from `tests/static`, extending coverage with `pytest.mark.with_all_precompiles` ([#1960](https://github.com/ethereum/execution-specs/pull/1960)).
- ✨ Add BAL tests that dequeue EIP-7251 consolidation requests. ([#2076](https://github.com/ethereum/execution-specs/pull/2076)).

## [v5.4.0](https://github.com/ethereum/execution-spec-tests/releases/tag/v5.4.0) - 2025-12-07

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
"""Tests for the effects of EIP-7251 beacon roots on EIP-7928."""

from typing import List

import pytest
from execution_testing import (
Address,
Alloc,
BalAccountExpectation,
BalStorageChange,
BalStorageSlot,
Block,
BlockAccessListExpectation,
BlockchainTestFiller,
Environment,
)

from tests.prague.eip7251_consolidations.helpers import (
ConsolidationRequest,
ConsolidationRequestTransaction,
)
from tests.prague.eip7251_consolidations.spec import Spec, ref_spec_7251

REFERENCE_SPEC_GIT_PATH = ref_spec_7251.git_path
REFERENCE_SPEC_VERSION = ref_spec_7251.version

pytestmark = pytest.mark.valid_from("Amsterdam")

CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS = (
Spec.CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS
)
CONSOLIDATION_REQUEST_COUNT_STORAGE_SLOT = (
Spec.CONSOLIDATION_REQUEST_COUNT_STORAGE_SLOT
)
CONSOLIDATION_REQUEST_QUEUE_HEAD_STORAGE_SLOT = (
Spec.CONSOLIDATION_REQUEST_QUEUE_HEAD_STORAGE_SLOT
)
CONSOLIDATION_REQUEST_QUEUE_TAIL_STORAGE_SLOT = (
Spec.CONSOLIDATION_REQUEST_QUEUE_TAIL_STORAGE_SLOT
)
MAX_CONSOLIDATION_REQUESTS_PER_BLOCK = (
Spec.MAX_CONSOLIDATION_REQUESTS_PER_BLOCK
)
SYSTEM_ADDRESS = Address(Spec.SYSTEM_ADDRESS)


@pytest.mark.parametrize(
"blocks_consolidation_requests",
[
pytest.param(
[
ConsolidationRequestTransaction(
requests=[
ConsolidationRequest(
source_pubkey=0x01,
target_pubkey=0x02,
fee=Spec.get_fee(0),
)
],
)
],
id="single_block_single_consolidation_request_from_eoa",
),
pytest.param(
[
ConsolidationRequestTransaction(
requests=[
ConsolidationRequest(
source_pubkey=i * 2 + 1,
target_pubkey=i * 2 + 2,
fee=Spec.get_fee(0),
)
],
)
for i in range(MAX_CONSOLIDATION_REQUESTS_PER_BLOCK)
],
id="single_block_max_consolidation_per_block",
),
pytest.param(
[
ConsolidationRequestTransaction(
requests=[
ConsolidationRequest(
source_pubkey=i * 2 + 1,
target_pubkey=i * 2 + 2,
fee=Spec.get_fee(0),
)
],
)
for i in range(MAX_CONSOLIDATION_REQUESTS_PER_BLOCK + 1)
],
id="single_block_max_consolidation_per_block_plus1",
),
],
)
@pytest.mark.pre_alloc_group(
"consolidation_requests",
reason="Tests standard consolidation request functionality",
)
def test_bal_system_dequeue_consolidations_eip7251(
blockchain_test: BlockchainTestFiller,
pre: Alloc,
blocks_consolidation_requests: List[ConsolidationRequestTransaction],
) -> None:
"""Test making a consolidation request to the beacon chain."""
txs = []

for request in blocks_consolidation_requests:
request.update_pre(pre=pre)
txs += request.transactions()

num = len(txs)

count_slot_changes = []
head_slot_changes = []
tail_slot_changes = []

for idx, _ in enumerate(txs):
count_slot_changes.append(
BalStorageChange(block_access_index=idx + 1, post_value=idx + 1)
)

tail_slot_changes.append(
BalStorageChange(block_access_index=idx + 1, post_value=idx + 1)
)

# Count slot is always reset to zero after request processing
count_slot_changes.append(
BalStorageChange(block_access_index=num + 1, post_value=0)
)

if num > MAX_CONSOLIDATION_REQUESTS_PER_BLOCK:
head_slot_changes.append(
BalStorageChange(
block_access_index=num + 1,
post_value=MAX_CONSOLIDATION_REQUESTS_PER_BLOCK,
)
)
else:
tail_slot_changes.append(
BalStorageChange(block_access_index=num + 1, post_value=0)
)

storage_changes = []
if any(count_slot_changes):
storage_changes.append(
BalStorageSlot(
slot=CONSOLIDATION_REQUEST_COUNT_STORAGE_SLOT,
slot_changes=count_slot_changes,
)
)

if any(head_slot_changes):
storage_changes.append(
BalStorageSlot(
slot=CONSOLIDATION_REQUEST_QUEUE_HEAD_STORAGE_SLOT,
slot_changes=head_slot_changes,
)
)

if any(tail_slot_changes):
storage_changes.append(
BalStorageSlot(
slot=CONSOLIDATION_REQUEST_QUEUE_TAIL_STORAGE_SLOT,
slot_changes=tail_slot_changes,
)
)

block = Block(
txs=txs,
expected_block_access_list=BlockAccessListExpectation(
account_expectations={
CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS: (
BalAccountExpectation(storage_changes=storage_changes)
)
}
),
)

blockchain_test(
genesis_environment=Environment(),
pre=pre,
post={},
blocks=[block],
)
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
| `test_bal_noop_storage_write` | Ensure BAL includes storage read but not write for no-op writes where pre-state equals post-state | Contract with pre-existing storage value `0x42` in slot `0x01`; transaction executes `SSTORE(0x01, 0x42)` (writing same value) | BAL **MUST** include the contract address with `storage_reads` for slot `0x01` since it was accessed, but **MUST NOT** include it in `storage_changes` (no actual state change). | ✅ Completed |
| `test_bal_fully_unmutated_account` | Ensure BAL captures account that has zero net mutations | Alice sends 0 wei to `Oracle` which writes same pre-existing value to storage | BAL MUST include Alice with `nonce_changes` and balance changes (gas), `Oracle` with `storage_reads` for accessed slot but empty `storage_changes`. | ✅ Completed |
| `test_bal_net_zero_balance_transfer` | BAL includes accounts with net-zero balance change but excludes them from balance changes | Contract receives and sends same amount to recipient using CALL or SELFDESTRUCT | BAL **MUST** include contract in `account_changes` without `balance_changes` (net zero). BAL **MUST** record non-zero `balance_changes` for recipient. | ✅ Completed |
| `test_bal_system_dequeue_consolidations_eip7251` | BAL tracks post-exec system dequeues for consolidations | Pre-populate EIP-7251 consolidation requests; produce a block where dequeues occur | BAL MUST include the 7251 system contract with `storage_changes` (queue slots 0–3) using `block_access_index = len(txs)`. | 🟡 Planned |
| `test_bal_system_dequeue_consolidations_eip7251` | BAL tracks post-exec system dequeues for consolidations | Pre-populate EIP-7251 consolidation requests; produce a block where dequeues occur | BAL MUST include the 7251 system contract with `storage_changes` (queue slots 0–3) using `block_access_index = len(txs)`. | ✅ Completed |
| `test_bal_aborted_storage_access` | Ensure BAL captures storage access in aborted transactions correctly | Alice calls contract that reads storage slot `0x01`, writes to slot `0x02`, then aborts with `REVERT`/`INVALID` | BAL MUST include storage_reads for slots `0x01` and `0x02` (aborted writes become reads), empty storage_changes. Only nonce changes for Alice. | ✅ Completed |
| `test_bal_aborted_account_access` | Ensure BAL captures account access in aborted transactions for all account accessing opcodes | Alice calls `AbortContract` that performs account access operations (`BALANCE`, `EXTCODESIZE`, `EXTCODECOPY`, `EXTCODEHASH`, `CALL`, `CALLCODE`, `DELEGATECALL`, `STATICCALL`) on `TargetContract` and aborts via `REVERT`/`INVALID` | BAL MUST include Alice, `TargetContract`, and `AbortContract` in account_changes and nonce changes for Alice. | ✅ Completed |
| `test_bal_pure_contract_call` | Ensure BAL captures contract access for pure computation calls | Alice calls `PureContract` that performs pure arithmetic (ADD operation) without storage or balance changes | BAL MUST include Alice and `PureContract` in `account_changes`, and `nonce_changes` for Alice. | ✅ Completed |
Expand Down
Loading