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

feat(mev-relay): validate bid request #125

Closed
wants to merge 5 commits into from
Closed
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
20 changes: 19 additions & 1 deletion mev-boost-rs/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use ethereum_consensus::{
bellatrix::mainnet as bellatrix,
builder::{SignedValidatorRegistration, ValidatorRegistration},
capella::mainnet as capella,
clock::{convert_timestamp_to_slot, get_current_unix_time_in_secs},
crypto::SecretKey,
phase0::mainnet::{compute_domain, Validator},
primitives::{DomainType, ExecutionAddress, Hash32, Root},
Expand Down Expand Up @@ -180,18 +181,35 @@ async fn propose_block(
genesis_validators_root: &Root,
) {
let fork = if shuffling_index == 0 { Forks::Bellatrix } else { Forks::Capella };
let current_slot = match fork {
let _current_slot = match fork {
Forks::Bellatrix => 32 + context.bellatrix_fork_epoch * context.slots_per_epoch,
Forks::Capella => 32 + context.capella_fork_epoch * context.slots_per_epoch,
_ => unimplemented!(),
};
let timestamp = get_current_unix_time_in_secs();
let current_slot =
convert_timestamp_to_slot(timestamp, context.min_genesis_time, context.seconds_per_slot)
.unwrap();
let parent_hash = Hash32::try_from([shuffling_index as u8; 32].as_ref()).unwrap();

let request = BidRequest {
slot: current_slot,
parent_hash: parent_hash.clone(),
public_key: proposer.validator.public_key.clone(),
};

// register validator
let mut registration = ValidatorRegistration {
fee_recipient: proposer.fee_recipient.clone(),
gas_limit: 30_000_000,
timestamp,
public_key: proposer.validator.public_key.clone(),
};
let signature =
sign_builder_message(&mut registration, &proposer.signing_key, context).unwrap();
let signed_registration = [SignedValidatorRegistration { message: registration, signature }];
let _ = beacon_node.register_validators(&signed_registration).await;

let signed_bid = beacon_node.fetch_best_bid(&request).await.unwrap();
let bid_parent_hash = signed_bid.parent_hash();
assert_eq!(bid_parent_hash, &parent_hash);
Expand Down
33 changes: 25 additions & 8 deletions mev-relay-rs/src/relay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use async_trait::async_trait;
use beacon_api_client::mainnet::Client;
use ethereum_consensus::{
builder::ValidatorRegistration,
clock::get_current_unix_time_in_secs,
clock::{convert_timestamp_to_slot, get_current_unix_time_in_secs},
crypto::SecretKey,
primitives::{BlsPublicKey, Root, Slot, U256},
state_transition::Context,
Expand All @@ -26,14 +26,31 @@ use std::{collections::HashMap, ops::Deref, sync::Arc};
// TODO likely drop this feature...
const PROPOSAL_TOLERANCE_DELAY: Slot = 1;

fn validate_bid_request(_bid_request: &BidRequest) -> Result<(), Error> {
// TODO validations

// verify slot is timely
fn validate_bid_request(
bid_request: &BidRequest,
context: &Context,
validator_registry: &ValidatorRegistry,
) -> Result<(), Error> {
let timestamp = get_current_unix_time_in_secs();
let current_slot =
chirag-bgh marked this conversation as resolved.
Show resolved Hide resolved
convert_timestamp_to_slot(timestamp, context.min_genesis_time, context.seconds_per_slot)
.unwrap();
// check if slot is timely
if bid_request.slot + PROPOSAL_TOLERANCE_DELAY < current_slot {
return Err(Error::InvalidSlot)
}

// verify parent_hash is on a chain tip
// Check if the parent_hash is on a chain tip
let chain_tip = &context.terminal_block_hash;
if bid_request.parent_hash != *chain_tip {
return Err(Error::InvalidParentHash)
}

// verify public_key is one of the possible proposers
// Check if public_key is one of the possible proposers
let validator_index = validator_registry.get_validator_index(&bid_request.public_key);
if validator_index.is_some() {
return Err(Error::ValidatorNotRegistered(bid_request.public_key.clone()))
}

Ok(())
}
Expand Down Expand Up @@ -165,7 +182,7 @@ impl BlindedBlockProvider for Relay {
}

async fn fetch_best_bid(&self, bid_request: &BidRequest) -> Result<SignedBuilderBid, Error> {
validate_bid_request(bid_request)?;
validate_bid_request(bid_request, &self.context, &self.validator_registry)?;

let public_key = &bid_request.public_key;
let preferences = self
Expand Down
4 changes: 4 additions & 0 deletions mev-rs/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ pub enum Error {
#[cfg(feature = "engine-proxy")]
#[error("{0}")]
EngineApi(#[from] crate::engine_api_proxy::Error),
#[error("invalid slot")]
InvalidSlot,
#[error("invalid parent hash")]
InvalidParentHash,
}

#[cfg(feature = "api")]
Expand Down
Loading