Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure EL block hash is updated when beacon parent root is overridden #3881

Merged
merged 5 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
28 changes: 24 additions & 4 deletions tests/core/pyspec/eth2spec/test/helpers/execution_payload.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,18 +204,20 @@ def get_consolidation_request_rlp_bytes(consolidation_request):
return b"\x02" + encode(values, sedes)


def compute_el_block_hash(spec, payload, pre_state):
def compute_el_block_hash_with_parent_root(spec, payload, parent_beacon_block_root):
if payload == spec.ExecutionPayload():
return spec.Hash32()

transactions_trie_root = compute_trie_root_from_indexed_data(payload.transactions)

withdrawals_trie_root = None
parent_beacon_block_root = None
requests_trie_root = None

if is_post_capella(spec):
withdrawals_encoded = [get_withdrawal_rlp(withdrawal) for withdrawal in payload.withdrawals]
withdrawals_trie_root = compute_trie_root_from_indexed_data(withdrawals_encoded)
if is_post_deneb(spec):
parent_beacon_block_root = pre_state.latest_block_header.hash_tree_root()
if not is_post_deneb(spec):
parent_beacon_block_root = None
if is_post_electra(spec):
requests_encoded = []
requests_encoded += [get_deposit_request_rlp_bytes(request) for request in payload.deposit_requests]
Expand All @@ -236,6 +238,24 @@ def compute_el_block_hash(spec, payload, pre_state):
)


def compute_el_block_hash(spec, payload, pre_state):
parent_beacon_block_root = None

if is_post_deneb(spec):
previous_block_header = pre_state.latest_block_header.copy()
if previous_block_header.state_root == spec.Root():
previous_block_header.state_root = pre_state.hash_tree_root()
parent_beacon_block_root = previous_block_header.hash_tree_root()

return compute_el_block_hash_with_parent_root(
spec, payload, parent_beacon_block_root)


def compute_el_block_hash_for_block(spec, block):
return compute_el_block_hash_with_parent_root(
spec, block.body.execution_payload, block.parent_root)


def build_empty_post_eip7732_execution_payload_header(spec, state):
if not is_post_eip7732(spec):
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from eth2spec.test.context import spec_state_test, expect_assertion_error, with_all_phases
from eth2spec.test.helpers.block import build_empty_block_for_next_slot
from eth2spec.test.helpers.execution_payload import compute_el_block_hash_for_block
from eth2spec.test.helpers.forks import is_post_bellatrix
from eth2spec.test.helpers.state import next_slot


Expand Down Expand Up @@ -65,6 +67,8 @@ def test_invalid_proposer_index(spec, state):
def test_invalid_parent_root(spec, state):
block = build_empty_block_for_next_slot(spec, state)
block.parent_root = b'\12' * 32 # invalid prev root
if is_post_bellatrix(spec):
block.body.execution_payload.block_hash = compute_el_block_hash_for_block(spec, block)

yield from run_block_header_processing(spec, state, block, valid=False)

Expand All @@ -81,6 +85,8 @@ def test_invalid_multiple_blocks_single_slot(spec, state):

child_block = block.copy()
child_block.parent_root = block.hash_tree_root()
if is_post_bellatrix(spec):
child_block.body.execution_payload.block_hash = compute_el_block_hash_for_block(spec, child_block)

yield from run_block_header_processing(spec, state, child_block, prepare_state=False, valid=False)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
transition_unsigned_block,
sign_block,
)
from eth2spec.test.helpers.execution_payload import (
compute_el_block_hash_for_block,
)
from eth2spec.test.helpers.fork_choice import (
get_genesis_forkchoice_store_and_block,
on_tick_and_append_step,
Expand All @@ -28,6 +31,9 @@
is_ready_to_justify,
find_next_justifying_slot,
)
from eth2spec.test.helpers.forks import (
is_post_bellatrix,
)
from eth2spec.test.helpers.state import (
next_epoch,
next_slots,
Expand Down Expand Up @@ -152,6 +158,8 @@ def test_on_block_bad_parent_root(spec, state):
block.state_root = state.hash_tree_root()

block.parent_root = b'\x45' * 32
if is_post_bellatrix(spec):
block.body.execution_payload.block_hash = compute_el_block_hash_for_block(spec, block)

signed_block = sign_block(spec, state, block)

Expand Down
13 changes: 9 additions & 4 deletions tests/core/pyspec/eth2spec/test/phase0/sanity/test_blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
from eth2spec.test.helpers.proposer_slashings import get_valid_proposer_slashing, check_proposer_slashing_effect
from eth2spec.test.helpers.attestations import get_valid_attestation
from eth2spec.test.helpers.deposits import prepare_state_and_deposit
from eth2spec.test.helpers.execution_payload import build_empty_execution_payload
from eth2spec.test.helpers.execution_payload import (
build_empty_execution_payload,
compute_el_block_hash_for_block,
)
from eth2spec.test.helpers.voluntary_exits import prepare_signed_exits
from eth2spec.test.helpers.multi_operations import (
run_slash_and_exit,
Expand Down Expand Up @@ -158,7 +161,7 @@ def process_and_sign_block_without_header_validations(spec, state, block):
if is_post_altair(spec):
spec.process_sync_aggregate(state, block.body.sync_aggregate)

# Insert post-state rot
# Insert post-state root
block.state_root = state.hash_tree_root()

# Sign block
Expand Down Expand Up @@ -197,11 +200,13 @@ def test_invalid_parent_from_same_slot(spec, state):
signed_parent_block = state_transition_and_sign_block(spec, state, parent_block)

child_block = parent_block.copy()
child_block.parent_root = state.latest_block_header.hash_tree_root()

if is_post_bellatrix(spec):
child_block.body.execution_payload = build_empty_execution_payload(spec, state)

child_block.parent_root = state.latest_block_header.hash_tree_root()
if is_post_bellatrix(spec):
child_block.body.execution_payload.block_hash = compute_el_block_hash_for_block(spec, child_block)

# Show that normal path through transition fails
failed_state = state.copy()
expect_assertion_error(
Expand Down
Loading