diff --git a/specs/gloas/builder.md b/specs/gloas/builder.md index 36dcb0f1315..7a82153a371 100644 --- a/specs/gloas/builder.md +++ b/specs/gloas/builder.md @@ -120,11 +120,13 @@ to include. They produce a `SignedExecutionPayloadBid` as follows. 05. Set `bid.prev_randao` to be the previous RANDAO of the constructed payload, that is `payload.prev_randao`. 06. Set `bid.fee_recipient` to be an execution address to receive the payment. - The proposer's preferred fee recipient can be obtained from the - `SignedProposerPreferences` associated with `bid.slot`. -07. Set `bid.gas_limit` to be the gas limit of the constructed payload. The - proposer's preferred gas limit can be obtained from the - `SignedProposerPreferences` associated with `bid.slot`. + The proposer's preferred fee recipient is obtained from the + `SignedProposerPreferences` whose `message.proposal_slot` matches `bid.slot` + and whose `message.checkpoint_root` matches + `get_checkpoint_block(store, bid.parent_block_root, compute_epoch_at_slot(bid.slot) - 1)`. +07. Set `bid.gas_limit` to be the gas limit of the constructed payload, which + must match the `gas_limit` in the `SignedProposerPreferences` referenced in + step 6. 08. Set `bid.builder_index` to be the index of the builder performing these actions. 09. Set `bid.slot` to be the slot for which this bid is aimed. This slot diff --git a/specs/gloas/p2p-interface.md b/specs/gloas/p2p-interface.md index 83ea77dce94..adce973fa3f 100644 --- a/specs/gloas/p2p-interface.md +++ b/specs/gloas/p2p-interface.md @@ -108,6 +108,7 @@ class PartialDataColumnGroupID(Container): ```python class ProposerPreferences(Container): + checkpoint_root: Root proposal_slot: Slot validator_index: ValidatorIndex fee_recipient: ExecutionAddress @@ -355,18 +356,19 @@ This topic is used to propagate signed bids as `SignedExecutionPayloadBid`. The following validations MUST pass before forwarding the `signed_execution_payload_bid` on the network, assuming the alias -`bid = signed_execution_payload_bid.message`: +`bid = signed_execution_payload_bid.message`, the alias +`signed_proposer_preferences` for the validated `SignedProposerPreferences` +whose `message.proposal_slot` is `bid.slot` and `message.checkpoint_root` is +`get_checkpoint_block(store, bid.parent_block_root, compute_epoch_at_slot(bid.slot) - 1)`, +and the alias `proposer_preferences = signed_proposer_preferences.message`: - _[IGNORE]_ `bid.slot` is the current slot or the next slot. -- _[IGNORE]_ the `SignedProposerPreferences` where `preferences.proposal_slot` - is equal to `bid.slot` has been seen. +- _[IGNORE]_ The matching `signed_proposer_preferences` has been seen. - _[REJECT]_ `bid.builder_index` is a valid/active builder index -- i.e. `is_active_builder(state, bid.builder_index)` returns `True`. -- _[REJECT]_ `bid.execution_payment` is zero. -- _[REJECT]_ `bid.fee_recipient` matches the `fee_recipient` from the proposer's - `SignedProposerPreferences` associated with `bid.slot`. -- _[REJECT]_ `bid.gas_limit` matches the `gas_limit` from the proposer's - `SignedProposerPreferences` associated with `bid.slot`. +- _[REJECT]_ `bid.execution_payment == 0`. +- _[REJECT]_ `bid.fee_recipient == proposer_preferences.fee_recipient`. +- _[REJECT]_ `bid.gas_limit == proposer_preferences.gas_limit`. - _[REJECT]_ The length of KZG commitments is less than or equal to the limitation defined in the consensus layer -- i.e. validate that `len(bid.blob_kzg_commitments) <= get_blob_parameters(compute_epoch_at_slot(bid.slot)).max_blobs_per_block`. @@ -403,15 +405,19 @@ The following validations MUST pass before forwarding the - _[IGNORE]_ `preferences.proposal_slot` is in the current or next epoch -- i.e. `compute_epoch_at_slot(preferences.proposal_slot)` is in - `[get_current_epoch(state), get_current_epoch(state) + 1]`. + `[compute_epoch_at_slot(current_slot), compute_epoch_at_slot(current_slot) + 1]`. - _[IGNORE]_ `preferences.proposal_slot` has not already passed -- i.e. - `preferences.proposal_slot > state.slot`. -- _[IGNORE]_ `preferences.validator_index` is present at the correct slot in the - current or next epoch's portion of `state.proposer_lookahead` -- i.e. - `is_valid_proposal_slot(state, preferences)` returns `True`. -- _[IGNORE]_ The `signed_proposer_preferences` is the first valid message - received from the validator with index `preferences.validator_index` and the - given slot `preferences.proposal_slot`. + `preferences.proposal_slot <= current_slot`. +- _[IGNORE]_ The block with root `preferences.checkpoint_root` has been seen + (via gossip or non-gossip sources) (a client MAY queue the message for + re-processing once the block is retrieved). +- _[REJECT]_ `is_valid_proposal_slot(state, preferences)` returns `True`, where + `state` is the checkpoint state at the epoch + `compute_epoch_at_slot(preferences.proposal_slot) - 1` and the root + `preferences.checkpoint_root`. +- _[IGNORE]_ The `signed_proposer_preferences` is the first valid message seen + for the tuple + `(preferences.checkpoint_root, preferences.proposal_slot, preferences.validator_index)`. - _[REJECT]_ `signed_proposer_preferences.signature` is valid with respect to the validator's public key. diff --git a/specs/gloas/validator.md b/specs/gloas/validator.md index 77fa2c265af..5b64c865c58 100644 --- a/specs/gloas/validator.md +++ b/specs/gloas/validator.md @@ -153,15 +153,18 @@ def get_upcoming_proposal_slots( To construct each `SignedProposerPreferences`: 1. Instantiate a new `ProposerPreferences` object as `preferences`. -2. Set `preferences.proposal_slot` to `upcoming_proposal_slots[i]`. -3. Set `preferences.validator_index` to the validator's index. -4. Set `preferences.fee_recipient` to the execution address where the validator +2. Set `preferences.checkpoint_root` to + `get_checkpoint_block(store, head_root, compute_epoch_at_slot(preferences.proposal_slot) - 1)`, + where `head_root` is the proposer's current head. +3. Set `preferences.proposal_slot` to `upcoming_proposal_slots[i]`. +4. Set `preferences.validator_index` to the validator's index. +5. Set `preferences.fee_recipient` to the execution address where the validator wishes to receive the builder payment. -5. Set `preferences.gas_limit` to the validator's preferred gas limit for this +6. Set `preferences.gas_limit` to the validator's preferred gas limit for this execution payload. -6. Instantiate a new `SignedProposerPreferences` object as `signed_preferences`. -7. Set `signed_preferences.message` to `preferences`. -8. Set `signed_preferences.signature` to the result of +7. Instantiate a new `SignedProposerPreferences` object as `signed_preferences`. +8. Set `signed_preferences.message` to `preferences`. +9. Set `signed_preferences.signature` to the result of `get_proposer_preferences_signature(state, preferences, privkey)`. ```python