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
8 changes: 2 additions & 6 deletions specs/gloas/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -1001,9 +1001,7 @@ def process_parent_execution_payload(state: BeaconState, block: BeaconBlock) ->
parent_bid = state.latest_execution_payload_bid
requests = block.body.parent_execution_requests

is_genesis_block = parent_bid.block_hash == Hash32()
is_parent_block_empty = bid.parent_block_hash != parent_bid.block_hash
if is_genesis_block or is_parent_block_empty:
if bid.parent_block_hash != parent_bid.block_hash:
# Parent was EMPTY -- no execution requests expected
assert requests == ExecutionRequests()
return
Expand Down Expand Up @@ -1212,9 +1210,7 @@ def process_withdrawals(
) -> None:
# [New in Gloas:EIP7732]
# Return early if the parent block is empty
is_genesis_block = state.latest_block_hash == Hash32()
is_parent_block_empty = state.latest_block_hash != state.latest_execution_payload_bid.block_hash
if is_genesis_block or is_parent_block_empty:
if state.latest_block_hash != state.latest_execution_payload_bid.block_hash:
return

# Get expected withdrawals
Expand Down
5 changes: 0 additions & 5 deletions specs/gloas/fork-choice.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,11 +287,6 @@ def get_parent_payload_status(store: Store, block: BeaconBlock) -> PayloadStatus
parent = store.blocks[block.parent_root]
parent_block_hash = block.body.signed_execution_payload_bid.message.parent_block_hash
message_block_hash = parent.body.signed_execution_payload_bid.message.block_hash

# Check for uninitialized genesis block hash
if message_block_hash == Hash32():
return PAYLOAD_STATUS_EMPTY

return PAYLOAD_STATUS_FULL if parent_block_hash == message_block_hash else PAYLOAD_STATUS_EMPTY
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,9 @@ def test_process_parent_execution_payload__empty_parent_requires_empty_requests(
@spec_state_test
def test_process_parent_execution_payload_genesis(spec, state):
"""
Verify that process_parent_execution_payload does not update
latest_block_hash when both hashes are Hash32().
Verify that process_parent_execution_payload does not update in genesis.
"""
state.latest_block_hash = spec.Hash32()
state.latest_execution_payload_bid.block_hash = spec.Hash32()

block = build_empty_block_for_next_slot(spec, state)
block.body.signed_execution_payload_bid.message.parent_block_hash = spec.Hash32()

pre_latest_block_hash = state.latest_block_hash

spec.process_slots(state, block.slot)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1117,12 +1117,8 @@ def test_full_builder_payload_reserves_sweep_slot(spec, state):
@spec_state_test
def test_zero_hash_genesis_skips_withdrawals(spec, state):
"""
Verify that process_withdrawals does not advance withdrawal indices
when both hashes are Hash32().
Verify that process_withdrawals does not advance withdrawal indices in genesis.
"""
state.latest_block_hash = spec.Hash32()
state.latest_execution_payload_bid.block_hash = spec.Hash32()

pre_state = state.copy()
yield from run_gloas_withdrawals_processing(spec, state)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
build_empty_block_for_next_slot,
)
from eth_consensus_specs.test.helpers.fork_choice import (
get_anchor_root,
get_genesis_forkchoice_store_and_block,
on_tick_and_append_step,
tick_and_add_block,
Expand All @@ -20,15 +19,11 @@
@spec_state_test
def test_get_parent_payload_status__genesis_empty_block_hash(spec, state):
"""
Verify that get_parent_payload_status returns EMPTY when the parent
block's bid has Hash32().
Verify that get_parent_payload_status returns EMPTY on genesis.
"""
test_steps = []

store, anchor_block = get_genesis_forkchoice_store_and_block(spec, state)
anchor_root = get_anchor_root(spec, state)

store.blocks[anchor_root].body.signed_execution_payload_bid.message.block_hash = spec.Hash32()

yield "anchor_state", state
yield "anchor_block", anchor_block
Expand All @@ -38,7 +33,6 @@ def test_get_parent_payload_status__genesis_empty_block_hash(spec, state):

# Add a block on top of genesis
block = build_empty_block_for_next_slot(spec, state)
block.body.signed_execution_payload_bid.message.parent_block_hash = spec.Hash32()
signed_block = state_transition_and_sign_block(spec, state, block)
yield from tick_and_add_block(spec, store, signed_block, test_steps)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,9 @@ def test_builder_payment_after_missed_epochs(spec, state):
bid.execution_requests_root = spec.hash_tree_root(spec.ExecutionRequests())

# Chain onto the previous bid so both block_1 and block_2 see a FULL parent
bid.parent_block_hash = state.latest_execution_payload_bid.block_hash
bid.block_hash = state.latest_execution_payload_bid.block_hash
# TODO(jtraglia): make this less hacky

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is this a thing we're fixing now? or are we merging this todo?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I intend to merge this todo & deal with it later. The fix wouldn't be simple.

bid.parent_block_hash = state.latest_block_hash
bid.block_hash = state.latest_block_hash

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't understand how this can ever happen

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah I hate this. This is unrealistic but that's how the test worked before. This test format does not yet support payload sidecars. See: https://github.com/ethereum/consensus-specs/blob/master/tests/formats/sanity/blocks.md


# Sign the bid with the builder's private key
signature = spec.get_execution_payload_bid_signature(
Expand Down
4 changes: 4 additions & 0 deletions tests/core/pyspec/eth_consensus_specs/test/helpers/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ def build_empty_block(spec, state, slot=None, proposer_index=None):

if is_post_gloas(spec):
signed_bid = build_empty_signed_execution_payload_bid(spec, state)
signed_bid.message.block_hash = spec.Hash32()
signed_bid.message.parent_block_hash = spec.Hash32(state.latest_block_hash)
empty_requests_root = spec.hash_tree_root(spec.ExecutionRequests())
signed_bid.message.execution_requests_root = empty_requests_root
empty_block.body.signed_execution_payload_bid = signed_bid
return empty_block

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,11 @@ def get_genesis_forkchoice_store_and_block(spec, genesis_state):
# Match the genesis block body bid to what ``genesis.py`` set on the
# state's committed bid; this keeps ``genesis_block`` consistent with
# ``genesis_state.latest_block_header`` (body_root).
genesis_block.body.signed_execution_payload_bid.message.block_hash = (
genesis_state.latest_execution_payload_bid.block_hash
)
genesis_block.body.signed_execution_payload_bid.message.execution_requests_root = (
genesis_state.latest_execution_payload_bid.execution_requests_root
genesis_block.body.signed_execution_payload_bid.message = spec.ExecutionPayloadBid(
# The genesis bid's block hash is the empty hash
block_hash=spec.Hash32(),
parent_block_hash=spec.Hash32(genesis_state.latest_block_hash),
execution_requests_root=spec.hash_tree_root(spec.ExecutionRequests()),
)
store = spec.get_forkchoice_store(genesis_state, genesis_block)
return store, genesis_block
Expand Down
25 changes: 9 additions & 16 deletions tests/core/pyspec/eth_consensus_specs/test/helpers/genesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,6 @@ def create_genesis_state(spec, validator_balances, activation_threshold):
previous_version = get_previous_fork_version(spec, spec.fork)
current_version = get_fork_version(spec, spec.fork)

genesis_block_body = spec.BeaconBlockBody()

state = spec.BeaconState(
genesis_time=0,
eth1_deposit_index=len(validator_balances),
Expand All @@ -144,7 +142,7 @@ def create_genesis_state(spec, validator_balances, activation_threshold):
epoch=spec.GENESIS_EPOCH,
),
latest_block_header=spec.BeaconBlockHeader(
body_root=spec.hash_tree_root(genesis_block_body)
body_root=spec.hash_tree_root(spec.BeaconBlockBody())
),
randao_mixes=[eth1_block_hash] * spec.EPOCHS_PER_HISTORICAL_VECTOR,
)
Expand Down Expand Up @@ -177,21 +175,16 @@ def create_genesis_state(spec, validator_balances, activation_threshold):
state.next_sync_committee = spec.get_next_sync_committee(state)

if is_post_gloas(spec):
# Initialize the latest_execution_payload_bid (match fork upgrade in fork.md).
# Genesis payload is EMPTY: ``latest_block_hash`` stays at default zero while
# ``bid.block_hash`` is set to the eth1 block hash, so the parent of any
# first post-genesis block is (correctly) treated as empty.
state.latest_block_hash = spec.Hash32()
empty_requests_root = spec.hash_tree_root(spec.ExecutionRequests())
state.latest_block_hash = spec.Hash32(eth1_block_hash)
state.latest_execution_payload_bid = spec.ExecutionPayloadBid(
block_hash=spec.Hash32(eth1_block_hash),
execution_requests_root=empty_requests_root,
)
genesis_block_body.signed_execution_payload_bid.message.block_hash = eth1_block_hash
genesis_block_body.signed_execution_payload_bid.message.execution_requests_root = (
empty_requests_root
# The genesis bid's block hash is the empty hash
block_hash=spec.Hash32(),
parent_block_hash=spec.Hash32(eth1_block_hash),
execution_requests_root=spec.hash_tree_root(spec.ExecutionRequests()),
)
# Recompute body_root after modifying the genesis block body
# Use realistic body root in the latest block header
genesis_block_body = spec.BeaconBlockBody()
genesis_block_body.signed_execution_payload_bid.message = state.latest_execution_payload_bid
state.latest_block_header = spec.BeaconBlockHeader(
body_root=spec.hash_tree_root(genesis_block_body)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -443,11 +443,8 @@ def test_discard_equivocations_slashed_validator_censoring(spec, state):
# Generate an anchor block with correct state root
anchor_block = spec.BeaconBlock(state_root=anchor_state.hash_tree_root())
if is_post_gloas(spec):
anchor_block.body.signed_execution_payload_bid.message.block_hash = (
anchor_state.latest_execution_payload_bid.block_hash
)
anchor_block.body.signed_execution_payload_bid.message.execution_requests_root = (
anchor_state.latest_execution_payload_bid.execution_requests_root
anchor_block.body.signed_execution_payload_bid.message = (
anchor_state.latest_execution_payload_bid
)
yield "anchor_state", anchor_state
yield "anchor_block", anchor_block
Expand Down