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

Changes for Slot auctions #15

Open
wants to merge 1 commit into
base: epbs_cl_repo
Choose a base branch
from
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
56 changes: 3 additions & 53 deletions specs/_features/eip7732/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@ class BeaconBlockBody(Container):
class ExecutionPayloadHeader(Container):
parent_block_hash: Hash32
parent_block_root: Root
block_hash: Hash32
gas_limit: uint64
builder_index: ValidatorIndex
slot: Slot
Expand Down Expand Up @@ -330,15 +329,6 @@ def is_valid_indexed_payload_attestation(
return bls.FastAggregateVerify(pubkeys, signing_root, indexed_payload_attestation.signature)
```

#### `is_parent_block_full`

This function returns true if the last committed payload header was fulfilled with a payload, this can only happen when both beacon block and payload were present. This function must be called on a beacon state before processing the execution payload header in the block.

```python
def is_parent_block_full(state: BeaconState) -> bool:
return state.latest_execution_payload_header.block_hash == state.latest_block_hash
```

### Beacon State accessors

#### `get_ptc`
Expand Down Expand Up @@ -426,52 +416,14 @@ The post-state corresponding to a pre-state `state` and a signed execution paylo
```python
def process_block(state: BeaconState, block: BeaconBlock) -> None:
process_block_header(state, block)
process_withdrawals(state) # [Modified in EIP-7732]
# Removed process_withdrawals(state) in EIP-7732
process_execution_payload_header(state, block) # [Modified in EIP-7732, removed process_execution_payload]
process_randao(state, block.body)
process_eth1_data(state, block.body)
process_operations(state, block.body) # [Modified in EIP-7732]
process_sync_aggregate(state, block.body.sync_aggregate)
```

#### Withdrawals

##### Modified `process_withdrawals`

**Note:** This is modified to take only the `state` as parameter. Withdrawals are deterministic given the beacon state, any execution payload that has the corresponding block as parent beacon block is required to honor these withdrawals in the execution layer. This function must be called before `process_execution_payload_header` as this latter function affects validator balances.

```python
def process_withdrawals(state: BeaconState) -> None:
# return early if the parent block was empty
if not is_parent_block_full(state):
return

withdrawals, partial_withdrawals_count = get_expected_withdrawals(state)
withdrawals_list = List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD](withdrawals)
state.latest_withdrawals_root = hash_tree_root(withdrawals_list)
for withdrawal in withdrawals:
decrease_balance(state, withdrawal.validator_index, withdrawal.amount)

# Update pending partial withdrawals
state.pending_partial_withdrawals = state.pending_partial_withdrawals[partial_withdrawals_count:]

# Update the next withdrawal index if this block contained withdrawals
if len(withdrawals) != 0:
latest_withdrawal = withdrawals[-1]
state.next_withdrawal_index = WithdrawalIndex(latest_withdrawal.index + 1)

# Update the next validator index to start the next withdrawal sweep
if len(withdrawals) == MAX_WITHDRAWALS_PER_PAYLOAD:
# Next sweep starts after the latest withdrawal's validator index
next_validator_index = ValidatorIndex((withdrawals[-1].validator_index + 1) % len(state.validators))
state.next_withdrawal_validator_index = next_validator_index
else:
# Advance sweep by the max length of the sweep if there was not a full set of withdrawals
next_index = state.next_withdrawal_validator_index + MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP
next_validator_index = ValidatorIndex(next_index % len(state.validators))
state.next_withdrawal_validator_index = next_validator_index
```

#### Execution payload header

##### New `verify_execution_payload_header_signature`
Expand Down Expand Up @@ -629,13 +581,9 @@ def process_execution_payload(state: BeaconState,
assert committed_header.blob_kzg_commitments_root == hash_tree_root(envelope.blob_kzg_commitments)

if not envelope.payload_withheld:
# Verify the withdrawals root
assert hash_tree_root(payload.withdrawals) == state.latest_withdrawals_root

# Verify the gas_limit
assert committed_header.gas_limit == payload.gas_limit

assert committed_header.block_hash == payload.block_hash
# Verify consistency of the parent hash with respect to the previous execution payload
assert payload.parent_hash == state.latest_block_hash
# Verify prev_randao
Expand All @@ -655,6 +603,8 @@ def process_execution_payload(state: BeaconState,
)
)

# Process withdrawals
process_withdrawals(state, payload)
# Process Electra operations
def for_ops(operations: Sequence[Any], fn: Callable[[BeaconState, Any], None]) -> None:
for operation in operations:
Expand Down
13 changes: 6 additions & 7 deletions specs/_features/eip7732/builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,11 @@ Builders can broadcast a payload bid for the current or the next slot's proposer
1. Set `header.parent_block_hash` to the current head of the execution chain (this can be obtained from the beacon state as `state.last_block_hash`).
2. Set `header.parent_block_root` to be the head of the consensus chain (this can be obtained from the beacon state as `hash_tree_root(state.latest_block_header)`. The `parent_block_root` and `parent_block_hash` must be compatible, in the sense that they both should come from the same `state` by the method described in this and the previous point.
3. Construct an execution payload. This can be performed with an external execution engine with a call to `engine_getPayloadV4`.
4. Set `header.block_hash` to be the block hash of the constructed payload, that is `payload.block_hash`.
5. Set `header.gas_limit` to be the gas limit of the constructed payload, that is `payload.gas_limit`.
6. Set `header.builder_index` to be the validator index of the builder performing these actions.
7. Set `header.slot` to be the slot for which this bid is aimed. This slot **MUST** be either the current slot or the next slot.
8. Set `header.value` to be the value that the builder will pay the proposer if the bid is accepted. The builder **MUST** have balance enough to fulfill this bid.
9. Set `header.kzg_commitments_root` to be the `hash_tree_root` of the `blobsbundle.commitments` field returned by `engine_getPayloadV4`.
4. Set `header.gas_limit` to be the gas limit of the constructed payload, that is `payload.gas_limit`.
5. Set `header.builder_index` to be the validator index of the builder performing these actions.
6. Set `header.slot` to be the slot for which this bid is aimed. This slot **MUST** be either the current slot or the next slot.
7. Set `header.value` to be the value that the builder will pay the proposer if the bid is accepted. The builder **MUST** have balance enough to fulfill this bid.
8. Set `header.kzg_commitments_root` to be the `hash_tree_root` of the `blobsbundle.commitments` field returned by `engine_getPayloadV4`.

After building the `header`, the builder obtains a `signature` of the header by using

Expand Down Expand Up @@ -104,7 +103,7 @@ When the proposer publishes a valid `SignedBeaconBlock` containing a signed comm

To construct the `execution_payload_envelope` the builder must perform the following steps, we alias `header` to be the committed `ExecutionPayloadHeader` in the beacon block.

1. Set the `payload` field to be the `ExecutionPayload` constructed when creating the corresponding bid. This payload **MUST** have the same block hash as `header.block_hash`.
1. Set the `payload` field to be the `ExecutionPayload` constructed when creating the corresponding bid.
2. Set the `builder_index` field to be the validator index of the builder performing these steps. This field **MUST** be `header.builder_index`.
3. Set `beacon_block_root` to be the `hash_tree_root` of the corresponding beacon block.
4. Set `blob_kzg_commitments` to be the `commitments` field of the blobs bundle constructed when constructing the bid. This field **MUST** have a `hash_tree_root` equal to `header.blob_kzg_commitments_root`.
Expand Down
5 changes: 1 addition & 4 deletions specs/_features/eip7732/fork-choice.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,7 @@ def is_payload_present(store: Store, beacon_block_root: Root) -> bool:

```python
def is_parent_node_full(store: Store, block: BeaconBlock) -> bool:
parent = store.blocks[block.parent_root]
parent_block_hash = block.body.signed_execution_payload_header.message.parent_block_hash
message_block_hash = parent.body.signed_execution_payload_header.message.block_hash
return parent_block_hash == message_block_hash
return block.parent_root in store.execution_payload_states
```

### Modified `get_ancestor`
Expand Down
2 changes: 0 additions & 2 deletions specs/_features/eip7732/p2p-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,6 @@ Let `block` be the block with `envelope.beacon_block_root`.
Let `header` alias `block.body.signed_execution_payload_header.message` (notice that this can be obtained from the `state.signed_execution_payload_header`)
- _[REJECT]_ `block` passes validation.
- _[REJECT]_ `envelope.builder_index == header.builder_index`
- if `envelope.payload_withheld == False` then
- _[REJECT]_ `payload.block_hash == header.block_hash`
- _[REJECT]_ The builder signature, `signed_execution_payload_envelope.signature`, is valid with respect to the builder's public key.

###### `payload_attestation_message`
Expand Down
Loading