Kiln mev boost (#3062)

## Issue Addressed

MEV boost compatibility

## Proposed Changes

See #2987

## Additional Info

This is blocked on the stabilization of a couple specs, [here](https://github.com/ethereum/beacon-APIs/pull/194) and [here](https://github.com/flashbots/mev-boost/pull/20).

Additional TODO's and outstanding questions

- [ ] MEV boost JWT Auth
- [ ] Will `builder_proposeBlindedBlock` return the revealed payload for the BN to propogate
- [ ] Should we remove `private-tx-proposals` flag and communicate BN <> VC with blinded blocks by default once these endpoints enter the beacon-API's repo? This simplifies merge transition logic. 

Co-authored-by: realbigsean <seananderson33@gmail.com>
Co-authored-by: realbigsean <sean@sigmaprime.io>
This commit is contained in:
realbigsean
2022-03-31 07:52:23 +00:00
parent 83234ee4ce
commit ea783360d3
48 changed files with 1628 additions and 644 deletions

View File

@@ -87,9 +87,9 @@ pub enum VerifyBlockRoot {
/// re-calculating the root when it is already known. Note `block_root` should be equal to the
/// tree hash root of the block, NOT the signing root of the block. This function takes
/// care of mixing in the domain.
pub fn per_block_processing<T: EthSpec>(
pub fn per_block_processing<T: EthSpec, Payload: ExecPayload<T>>(
state: &mut BeaconState<T>,
signed_block: &SignedBeaconBlock<T>,
signed_block: &SignedBeaconBlock<T, Payload>,
block_root: Option<Hash256>,
block_signature_strategy: BlockSignatureStrategy,
verify_block_root: VerifyBlockRoot,
@@ -129,7 +129,12 @@ pub fn per_block_processing<T: EthSpec>(
BlockSignatureStrategy::VerifyRandao => VerifySignatures::False,
};
let proposer_index = process_block_header(state, block, verify_block_root, spec)?;
let proposer_index = process_block_header(
state,
block.temporary_block_header(),
verify_block_root,
spec,
)?;
if verify_signatures.is_true() {
verify_block_signature(state, signed_block, block_root, spec)?;
@@ -172,28 +177,28 @@ pub fn per_block_processing<T: EthSpec>(
/// Processes the block header, returning the proposer index.
pub fn process_block_header<T: EthSpec>(
state: &mut BeaconState<T>,
block: BeaconBlockRef<'_, T>,
block_header: BeaconBlockHeader,
verify_block_root: VerifyBlockRoot,
spec: &ChainSpec,
) -> Result<u64, BlockOperationError<HeaderInvalid>> {
// Verify that the slots match
verify!(
block.slot() == state.slot(),
block_header.slot == state.slot(),
HeaderInvalid::StateSlotMismatch
);
// Verify that the block is newer than the latest block header
verify!(
block.slot() > state.latest_block_header().slot,
block_header.slot > state.latest_block_header().slot,
HeaderInvalid::OlderThanLatestBlockHeader {
block_slot: block.slot(),
block_slot: block_header.slot,
latest_block_header_slot: state.latest_block_header().slot,
}
);
// Verify that proposer index is the correct index
let proposer_index = block.proposer_index() as usize;
let state_proposer_index = state.get_beacon_proposer_index(block.slot(), spec)?;
let proposer_index = block_header.proposer_index as usize;
let state_proposer_index = state.get_beacon_proposer_index(block_header.slot, spec)?;
verify!(
proposer_index == state_proposer_index,
HeaderInvalid::ProposerIndexMismatch {
@@ -205,15 +210,15 @@ pub fn process_block_header<T: EthSpec>(
if verify_block_root == VerifyBlockRoot::True {
let expected_previous_block_root = state.latest_block_header().tree_hash_root();
verify!(
block.parent_root() == expected_previous_block_root,
block_header.parent_root == expected_previous_block_root,
HeaderInvalid::ParentBlockRootMismatch {
state: expected_previous_block_root,
block: block.parent_root(),
block: block_header.parent_root,
}
);
}
*state.latest_block_header_mut() = block.temporary_block_header();
*state.latest_block_header_mut() = block_header;
// Verify proposer is not slashed
verify!(
@@ -221,15 +226,15 @@ pub fn process_block_header<T: EthSpec>(
HeaderInvalid::ProposerSlashed(proposer_index)
);
Ok(block.proposer_index())
Ok(proposer_index as u64)
}
/// Verifies the signature of a block.
///
/// Spec v0.12.1
pub fn verify_block_signature<T: EthSpec>(
pub fn verify_block_signature<T: EthSpec, Payload: ExecPayload<T>>(
state: &BeaconState<T>,
block: &SignedBeaconBlock<T>,
block: &SignedBeaconBlock<T, Payload>,
block_root: Option<Hash256>,
spec: &ChainSpec,
) -> Result<(), BlockOperationError<HeaderInvalid>> {
@@ -250,9 +255,9 @@ pub fn verify_block_signature<T: EthSpec>(
/// Verifies the `randao_reveal` against the block's proposer pubkey and updates
/// `state.latest_randao_mixes`.
pub fn process_randao<T: EthSpec>(
pub fn process_randao<T: EthSpec, Payload: ExecPayload<T>>(
state: &mut BeaconState<T>,
block: BeaconBlockRef<'_, T>,
block: BeaconBlockRef<'_, T, Payload>,
verify_signatures: VerifySignatures,
spec: &ChainSpec,
) -> Result<(), BlockProcessingError> {
@@ -314,34 +319,34 @@ pub fn get_new_eth1_data<T: EthSpec>(
/// Contains a partial set of checks from the `process_execution_payload` function:
///
/// https://github.com/ethereum/consensus-specs/blob/v1.1.5/specs/merge/beacon-chain.md#process_execution_payload
pub fn partially_verify_execution_payload<T: EthSpec>(
pub fn partially_verify_execution_payload<T: EthSpec, Payload: ExecPayload<T>>(
state: &BeaconState<T>,
payload: &ExecutionPayload<T>,
payload: &Payload,
spec: &ChainSpec,
) -> Result<(), BlockProcessingError> {
if is_merge_transition_complete(state) {
block_verify!(
payload.parent_hash == state.latest_execution_payload_header()?.block_hash,
payload.parent_hash() == state.latest_execution_payload_header()?.block_hash,
BlockProcessingError::ExecutionHashChainIncontiguous {
expected: state.latest_execution_payload_header()?.block_hash,
found: payload.parent_hash,
found: payload.parent_hash(),
}
);
}
block_verify!(
payload.prev_randao == *state.get_randao_mix(state.current_epoch())?,
payload.prev_randao() == *state.get_randao_mix(state.current_epoch())?,
BlockProcessingError::ExecutionRandaoMismatch {
expected: *state.get_randao_mix(state.current_epoch())?,
found: payload.prev_randao,
found: payload.prev_randao(),
}
);
let timestamp = compute_timestamp_at_slot(state, spec)?;
block_verify!(
payload.timestamp == timestamp,
payload.timestamp() == timestamp,
BlockProcessingError::ExecutionInvalidTimestamp {
expected: timestamp,
found: payload.timestamp,
found: payload.timestamp(),
}
);
@@ -355,29 +360,14 @@ pub fn partially_verify_execution_payload<T: EthSpec>(
/// Partially equivalent to the `process_execution_payload` function:
///
/// https://github.com/ethereum/consensus-specs/blob/v1.1.5/specs/merge/beacon-chain.md#process_execution_payload
pub fn process_execution_payload<T: EthSpec>(
pub fn process_execution_payload<T: EthSpec, Payload: ExecPayload<T>>(
state: &mut BeaconState<T>,
payload: &ExecutionPayload<T>,
payload: &Payload,
spec: &ChainSpec,
) -> Result<(), BlockProcessingError> {
partially_verify_execution_payload(state, payload, spec)?;
*state.latest_execution_payload_header_mut()? = ExecutionPayloadHeader {
parent_hash: payload.parent_hash,
fee_recipient: payload.fee_recipient,
state_root: payload.state_root,
receipts_root: payload.receipts_root,
logs_bloom: payload.logs_bloom.clone(),
prev_randao: payload.prev_randao,
block_number: payload.block_number,
gas_limit: payload.gas_limit,
gas_used: payload.gas_used,
timestamp: payload.timestamp,
extra_data: payload.extra_data.clone(),
base_fee_per_gas: payload.base_fee_per_gas,
block_hash: payload.block_hash,
transactions_root: payload.transactions.tree_hash_root(),
};
*state.latest_execution_payload_header_mut()? = payload.to_execution_payload_header();
Ok(())
}
@@ -394,24 +384,21 @@ pub fn is_merge_transition_complete<T: EthSpec>(state: &BeaconState<T>) -> bool
.unwrap_or(false)
}
/// https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/beacon-chain.md#is_merge_transition_block
pub fn is_merge_transition_block<T: EthSpec>(
pub fn is_merge_transition_block<T: EthSpec, Payload: ExecPayload<T>>(
state: &BeaconState<T>,
body: BeaconBlockBodyRef<T>,
body: BeaconBlockBodyRef<T, Payload>,
) -> bool {
body.execution_payload()
.map(|payload| {
!is_merge_transition_complete(state) && *payload != <ExecutionPayload<T>>::default()
})
.map(|payload| !is_merge_transition_complete(state) && *payload != Payload::default())
.unwrap_or(false)
}
/// https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/beacon-chain.md#is_execution_enabled
pub fn is_execution_enabled<T: EthSpec>(
pub fn is_execution_enabled<T: EthSpec, Payload: ExecPayload<T>>(
state: &BeaconState<T>,
body: BeaconBlockBodyRef<T>,
body: BeaconBlockBodyRef<T, Payload>,
) -> bool {
is_merge_transition_block(state, body) || is_merge_transition_complete(state)
}
/// https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/beacon-chain.md#compute_timestamp_at_slot
pub fn compute_timestamp_at_slot<T: EthSpec>(
state: &BeaconState<T>,