Skip to content
Merged
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 @@ -10,6 +10,7 @@
activate_builders,
build_signed_bid,
get_blocks_meta,
record_block_in_store,
record_head_payload,
setup_store_advanced_for_bid,
setup_store_finalized_with_pending_payment,
Expand Down Expand Up @@ -2464,6 +2465,147 @@ def _run_bid_gas_limit_scenario(
yield "messages", "meta", messages


@with_gloas_and_later
@spec_state_test_with_matching_config
def test_gossip_execution_payload_bid__valid_gas_limit_after_empty_parent(spec, state):
"""A bid after an empty head uses its execution parent's gas limit."""
anchor_state = state.copy()
yield "topic", "meta", "execution_payload_bid"

store, blocks, _ = setup_store_advanced_for_bid(spec, state)

parent_gas_limit = spec.Uint64(30_000_000)
payload_block_hash = spec.Hash32(b"\xaa" * 32)
payload_block = build_empty_block_for_next_slot(spec, state)
payload_bid = payload_block.body.signed_execution_payload_bid.message
payload_bid.block_hash = payload_block_hash
payload_bid.gas_limit = parent_gas_limit
signed_payload_block = state_transition_and_sign_block(spec, state, payload_block)
payload_root = record_block_in_store(spec, store, signed_payload_block, state.copy())
blocks.append(signed_payload_block)

payload_state = state.copy()
signed_envelope = build_signed_execution_payload_envelope(
spec, payload_state, payload_root, signed_payload_block
)
store.payloads[payload_root] = signed_envelope.message

# Leave the next block's payload unreceived so it becomes the empty head.
empty_parent_gas_limit = spec.Uint64(30_029_295)
empty_parent = build_empty_block_for_next_slot(spec, state)
empty_parent_bid = empty_parent.body.signed_execution_payload_bid.message
empty_parent_bid.parent_block_hash = payload_block_hash
empty_parent_bid.gas_limit = empty_parent_gas_limit
signed_empty_parent = state_transition_and_sign_block(spec, state, empty_parent)
parent_root = record_block_in_store(spec, store, signed_empty_parent, state.copy())
blocks.append(signed_empty_parent)

finalized_checkpoint_meta = activate_builders(spec, state, store, blocks)
yield "state", anchor_state
for signed in blocks:
yield get_filename(signed), signed
yield get_filename(signed_envelope), signed_envelope
blocks_meta = get_blocks_meta(blocks)
blocks_meta[-2]["payload"] = get_filename(signed_envelope)
yield "blocks", "meta", blocks_meta
yield "finalized_checkpoint", "meta", finalized_checkpoint_meta

seen = get_seen(spec)
time_ms = spec.compute_time_at_slot_ms(store, state.slot)
yield "current_time_ms", "meta", int(time_ms)
messages = []
common_fee = spec.ExecutionAddress(b"\x11" * 20)

proposal_slot, validator_index = find_upcoming_proposal_slot(spec, state)
time_ms += 50
signed_prefs = build_signed_proposer_preferences(
spec,
state,
proposal_slot=proposal_slot,
validator_index=validator_index,
fee_recipient=common_fee,
target_gas_limit=spec.Uint64(60_000_000),
)
yield get_filename(signed_prefs), signed_prefs
result, reason = run_validate_gossip(
spec,
seen=seen,
store=store,
signed_proposer_preferences=signed_prefs,
current_time_ms=time_ms,
)
assert result == "valid"
assert reason is None
messages.append(
{
"current_time_ms": int(time_ms),
"message": get_filename(signed_prefs),
"expected": result,
}
)

time_ms += 10
result, reason = run_validate_gossip(
spec,
seen=seen,
store=store,
signed_execution_payload_envelope=signed_envelope,
)
assert result == "valid"
assert reason is None
messages.append(
{
"current_time_ms": int(time_ms),
"message": get_filename(signed_envelope),
"expected": result,
}
)

signed_bid = build_signed_bid(
spec,
state,
builder_index=spec.BuilderIndex(0),
slot=proposal_slot,
parent_block_hash=payload_block_hash,
parent_block_root=parent_root,
fee_recipient=common_fee,
gas_limit=empty_parent_gas_limit,
value=spec.Gwei(1),
)
yield get_filename(signed_bid), signed_bid

assert spec.is_gas_limit_target_compatible(
parent_gas_limit,
signed_bid.message.gas_limit,
signed_prefs.message.target_gas_limit,
)
assert not spec.is_gas_limit_target_compatible(
empty_parent_gas_limit,
signed_bid.message.gas_limit,
signed_prefs.message.target_gas_limit,
)

time_ms += 40
result, reason = run_validate_gossip(
spec,
seen=seen,
store=store,
signed_execution_payload_bid=signed_bid,
current_time_ms=time_ms,
)
assert result == "valid"
assert reason is None
messages.append(
{
"current_time_ms": int(time_ms),
"message": get_filename(signed_bid),
"expected": result,
}
)

yield "messages", "meta", messages


@with_gloas_and_later
@spec_state_test_with_matching_config
def test_gossip_execution_payload_bid__valid_gas_limit_increase_within_limit(spec, state):
Expand Down