Skip to content

Commit

Permalink
Merge pull request #12 from gattaca-com/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
gd-0 authored Jan 30, 2024
2 parents 96fd863 + 014b64a commit 0166ecd
Show file tree
Hide file tree
Showing 34 changed files with 656 additions and 272 deletions.
237 changes: 167 additions & 70 deletions crates/api/src/builder/api.rs

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions crates/api/src/builder/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ pub enum BuilderApiError {

#[error("builder has been demoted. builder_pub_key: {builder_pub_key:?}")]
BuilderDemoted{builder_pub_key: BlsPublicKey},

#[error("builder not in proposer's trusted list: {proposer_trusted_builders:?}")]
BuilderNotInProposersTrustedList{proposer_trusted_builders: Vec<String>},

#[error("V2 submissions invalid if proposer censors")]
V2SubmissionsInvalidIfProposerCensors,
}

impl IntoResponse for BuilderApiError {
Expand Down Expand Up @@ -219,6 +225,12 @@ impl IntoResponse for BuilderApiError {
BuilderApiError::BuilderDemoted { builder_pub_key } => {
(StatusCode::BAD_REQUEST, format!("builder has been demoted. builder_pub_key: {builder_pub_key:?}")).into_response()
},
BuilderApiError::BuilderNotInProposersTrustedList { proposer_trusted_builders } => {
(StatusCode::BAD_REQUEST, format!("builder not in proposer's trusted list: {proposer_trusted_builders:?}")).into_response()
},
BuilderApiError::V2SubmissionsInvalidIfProposerCensors => {
(StatusCode::BAD_REQUEST, "V2 submissions invalid if proposer censors").into_response()
}
}
}
}
3 changes: 2 additions & 1 deletion crates/api/src/builder/simulator/mock_simulator.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use async_trait::async_trait;
use tokio::sync::mpsc::Sender;

use helix_common::simulator::BlockSimError;
use helix_common::{simulator::BlockSimError, BuilderInfo};
use uuid::Uuid;

use crate::builder::{DbInfo, traits::BlockSimulator, BlockSimRequest};
Expand All @@ -20,6 +20,7 @@ impl BlockSimulator for MockSimulator {
async fn process_request(
&self,
_request: BlockSimRequest,
_builder_info: &BuilderInfo,
_is_top_bid: bool,
_sim_result_saver_sender: Sender<DbInfo>,
_request_id: Uuid,
Expand Down
2 changes: 1 addition & 1 deletion crates/api/src/builder/simulator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::sync::Arc;
use ethereum_consensus::types::mainnet::ExecutionPayload;

use helix_common::bid_submission::{BidTrace, SignedBidSubmission, BidSubmission};
use helix_common::api::proposer_api::ValidatorPreferences;
use helix_common::ValidatorPreferences;
use ethereum_consensus::serde::as_str;
use ethereum_consensus::primitives::BlsSignature;

Expand Down
23 changes: 4 additions & 19 deletions crates/api/src/builder/simulator/optimistic_simulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl<A: Auctioneer + 'static, DB: DatabaseService + 'static> OptimisticSimulator
) -> Result<(), BlockSimError> {
if let Err(err) = self
.simulator
.process_request(request.clone(), is_top_bid, sim_result_saver_sender, request_id)
.process_request(request.clone(), &builder_info, is_top_bid, sim_result_saver_sender, request_id)
.await
{
if let BlockSimError::BlockValidationFailed(_) = err {
Expand Down Expand Up @@ -143,34 +143,18 @@ impl<A: Auctioneer + 'static, DB: DatabaseService + 'static> OptimisticSimulator
}
false
}

/// Fetch the builder's information. Default info is returned if fetching fails.
async fn fetch_builder_info(&self, request: &BlockSimRequest) -> BuilderInfo {
match self.auctioneer.get_builder_info(&request.message.builder_public_key).await {
Ok(info) => info,
Err(err) => {
warn!(
builder=%request.message.builder_public_key,
block_hash=%request.execution_payload.block_hash(),
err=%err,
"Failed to retrieve builder info"
);
BuilderInfo { collateral: U256::ZERO, is_optimistic: false }
}
}
}
}

#[async_trait]
impl<A: Auctioneer, DB: DatabaseService> BlockSimulator for OptimisticSimulator<A, DB> {
async fn process_request(
&self,
request: BlockSimRequest,
builder_info: &BuilderInfo,
is_top_bid: bool,
sim_result_saver_sender: Sender<DbInfo>,
request_id: Uuid,
) -> Result<bool, BlockSimError> {
let builder_info = self.fetch_builder_info(&request).await;

if self.should_process_optimistically(&request, &builder_info).await {
debug!(
Expand All @@ -180,6 +164,7 @@ impl<A: Auctioneer, DB: DatabaseService> BlockSimulator for OptimisticSimulator<
);

let cloned_self = self.clone_for_async();
let builder_info = builder_info.clone();
tokio::spawn(async move {
cloned_self
.handle_simulation(request, is_top_bid, sim_result_saver_sender, builder_info, request_id)
Expand All @@ -196,7 +181,7 @@ impl<A: Auctioneer, DB: DatabaseService> BlockSimulator for OptimisticSimulator<
request=?request.message,
"processing simulation request"
);
self.handle_simulation(request, is_top_bid, sim_result_saver_sender, builder_info, request_id)
self.handle_simulation(request, is_top_bid, sim_result_saver_sender, builder_info.clone(), request_id)
.await
.map(|_| false)
}
Expand Down
30 changes: 14 additions & 16 deletions crates/api/src/builder/simulator/optimistic_simulator_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,9 @@ mod simulator_tests {
use helix_database::MockDatabaseService;
use helix_datastore::MockAuctioneer;
use helix_common::{
bid_submission::{BidTrace, SignedBidSubmission, SignedBidSubmissionCapella},
simulator::BlockSimError,
BuilderInfo,
bid_submission::{BidTrace, SignedBidSubmission, SignedBidSubmissionCapella}, simulator::BlockSimError, BuilderInfo
};
use helix_common::api::proposer_api::ValidatorPreferences;
use helix_common::ValidatorPreferences;

// ++++ HELPERS ++++
fn get_optimistic_simulator(
Expand Down Expand Up @@ -97,11 +95,11 @@ mod simulator_tests {

let builder_demoted = Arc::new(AtomicBool::new(false));
let (sim_res_sender, _sim_res_receiver) = tokio::sync::mpsc::channel(100);
let builder_info = BuilderInfo { collateral: U256::from(100), is_optimistic: true };
let builder_info = BuilderInfo { collateral: U256::from(100), is_optimistic: true, builder_id: None };
let simulator =
get_optimistic_simulator(&server.url(), Some(builder_info), builder_demoted.clone());
get_optimistic_simulator(&server.url(), Some(builder_info.clone()), builder_demoted.clone());

let result = simulator.process_request(get_sim_req(), true, sim_res_sender, Uuid::new_v4()).await;
let result = simulator.process_request(get_sim_req(), &builder_info, true, sim_res_sender, Uuid::new_v4()).await;

// give the simulator time to process the request
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
Expand All @@ -122,11 +120,11 @@ mod simulator_tests {

let builder_demoted = Arc::new(AtomicBool::new(false));
let (sim_res_sender, _sim_res_receiver) = tokio::sync::mpsc::channel(100);
let builder_info = BuilderInfo { collateral: U256::from(100), is_optimistic: true };
let builder_info = BuilderInfo { collateral: U256::from(100), is_optimistic: true, builder_id: None };
let simulator =
get_optimistic_simulator(&server.url(), Some(builder_info), builder_demoted.clone());
get_optimistic_simulator(&server.url(), Some(builder_info.clone()), builder_demoted.clone());

let result = simulator.process_request(get_sim_req(), true, sim_res_sender, Uuid::new_v4()).await;
let result = simulator.process_request(get_sim_req(), &builder_info, true, sim_res_sender, Uuid::new_v4()).await;

// give the simulator time to process the request
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
Expand All @@ -147,11 +145,11 @@ mod simulator_tests {

let builder_demoted = Arc::new(AtomicBool::new(false));
let (sim_res_sender, _sim_res_receiver) = tokio::sync::mpsc::channel(100);
let builder_info = BuilderInfo { collateral: U256::from(100), is_optimistic: false };
let builder_info = BuilderInfo { collateral: U256::from(100), is_optimistic: false, builder_id: None };
let simulator =
get_optimistic_simulator(&server.url(), Some(builder_info), builder_demoted.clone());
get_optimistic_simulator(&server.url(), Some(builder_info.clone()), builder_demoted.clone());

let result = simulator.process_request(get_sim_req(), true, sim_res_sender, Uuid::new_v4()).await;
let result = simulator.process_request(get_sim_req(), &builder_info, true, sim_res_sender, Uuid::new_v4()).await;

// give the simulator time to process the request
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
Expand All @@ -172,11 +170,11 @@ mod simulator_tests {

let builder_demoted = Arc::new(AtomicBool::new(false));
let (sim_res_sender, _sim_res_receiver) = tokio::sync::mpsc::channel(100);
let builder_info = BuilderInfo { collateral: U256::from(100), is_optimistic: false };
let builder_info = BuilderInfo { collateral: U256::from(100), is_optimistic: false, builder_id: None };
let simulator =
get_optimistic_simulator(&server.url(), Some(builder_info), builder_demoted.clone());
get_optimistic_simulator(&server.url(), Some(builder_info.clone()), builder_demoted.clone());

let result = simulator.process_request(get_sim_req(), true, sim_res_sender, Uuid::new_v4()).await;
let result = simulator.process_request(get_sim_req(), &builder_info, true, sim_res_sender, Uuid::new_v4()).await;

// give the simulator time to process the request
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
Expand Down
2 changes: 2 additions & 0 deletions crates/api/src/builder/simulator/rpc_simulator.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use async_trait::async_trait;
use helix_common::BuilderInfo;
use hyper::StatusCode;
use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE};
use reqwest::{Client, Response};
Expand Down Expand Up @@ -80,6 +81,7 @@ impl BlockSimulator for RpcSimulator {
async fn process_request(
&self,
request: BlockSimRequest,
_builder_info: &BuilderInfo,
is_top_bid: bool,
sim_result_saver_sender: Sender<DbInfo>,
request_id: Uuid,
Expand Down
14 changes: 8 additions & 6 deletions crates/api/src/builder/simulator/simulator_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ mod simulator_tests {
use std::sync::Arc;
use ethereum_consensus::types::mainnet::ExecutionPayload;
use helix_common::{
bid_submission::{BidTrace, SignedBidSubmission, SignedBidSubmissionCapella},
simulator::BlockSimError,
bid_submission::{BidTrace, SignedBidSubmission, SignedBidSubmissionCapella}, simulator::BlockSimError, BuilderInfo
};
use helix_common::api::proposer_api::ValidatorPreferences;
use helix_common::ValidatorPreferences;

// ++++ HELPERS ++++
fn get_simulator(endpoint: &str) -> RpcSimulator {
Expand Down Expand Up @@ -67,7 +66,8 @@ mod simulator_tests {

let (sim_res_sender, mut sim_res_receiver) = tokio::sync::mpsc::channel(100);
let simulator = get_simulator(&server.url());
let result = simulator.process_request(get_sim_req(), true, sim_res_sender, Uuid::new_v4()).await;
let builder_info = BuilderInfo::default();
let result = simulator.process_request(get_sim_req(), &builder_info, true, sim_res_sender, Uuid::new_v4()).await;

mock.assert();
assert!(result.is_ok());
Expand Down Expand Up @@ -97,7 +97,8 @@ mod simulator_tests {

let (sim_res_sender, _sim_res_receiver) = tokio::sync::mpsc::channel(100);
let simulator = get_simulator(&server.url());
let result = simulator.process_request(get_sim_req(), true, sim_res_sender, Uuid::new_v4()).await;
let builder_info = BuilderInfo::default();
let result = simulator.process_request(get_sim_req(), &builder_info, true, sim_res_sender, Uuid::new_v4()).await;

mock.assert();
assert!(result.is_err());
Expand Down Expand Up @@ -126,7 +127,8 @@ mod simulator_tests {

let (sim_res_sender, _sim_res_receiver) = tokio::sync::mpsc::channel(100);
let simulator = get_simulator(&server.url());
let result = simulator.process_request(get_sim_req(), true, sim_res_sender, Uuid::new_v4()).await;
let builder_info = BuilderInfo::default();
let result = simulator.process_request(get_sim_req(), &builder_info, true, sim_res_sender, Uuid::new_v4()).await;

mock.assert();
assert!(result.is_err());
Expand Down
3 changes: 2 additions & 1 deletion crates/api/src/builder/simulator/traits.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use async_trait::async_trait;
use helix_common::simulator::BlockSimError;
use helix_common::{simulator::BlockSimError, BuilderInfo};
use tokio::sync::mpsc::Sender;
use uuid::Uuid;

Expand All @@ -11,6 +11,7 @@ pub trait BlockSimulator: Send + Sync + Clone {
async fn process_request(
&self,
request: BlockSimRequest,
builder_info: &BuilderInfo,
is_top_bid: bool,
sim_result_saver_sender: Sender<DbInfo>,
request_id: Uuid,
Expand Down
2 changes: 1 addition & 1 deletion crates/api/src/builder/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ mod tests {
api::builder_api::{BuilderGetValidatorsResponseEntry, BuilderGetValidatorsResponse}, bid_submission::{SignedBidSubmission, v2::header_submission::{SignedHeaderSubmission, SignedHeaderSubmissionCapella, SignedHeaderSubmissionDeneb}, BidSubmission}, SubmissionTrace, HeaderSubmissionTrace,
};
use helix_common::api::proposer_api::ValidatorRegistrationInfo;
use helix_common::api::proposer_api::ValidatorPreferences;
use helix_common::ValidatorPreferences;
use helix_housekeeper::{ChainUpdate, PayloadAttributesUpdate, SlotUpdate};
use helix_utils::request_encoding::Encoding;
use tokio::sync::{
Expand Down
9 changes: 3 additions & 6 deletions crates/api/src/proposer/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ use helix_common::{
proposer_api::{
ValidatorRegistrationInfo,
GetPayloadResponse,
ValidatorPreferences,
},
},
ValidatorPreferences,
chain_info::{ChainInfo, Network},
try_execution_header_from_payload, BidRequest, GetHeaderTrace, GetPayloadTrace,
RegisterValidatorsTrace, signed_proposal::VersionedSignedProposal, versioned_payload::PayloadAndBlobs,
Expand Down Expand Up @@ -987,11 +987,8 @@ where
&self,
public_key: &BlsPublicKey,
) -> Result<bool, ProposerApiError> {
Ok(self
.auctioneer
.get_trusted_proposers()
.await?
.map_or(false, |whitelist| whitelist.contains(public_key)))
let is_trusted_proposer = self.auctioneer.is_trusted_proposer(public_key).await?;
Ok(is_trusted_proposer)
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/api/src/proposer/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ mod proposer_api_tests {
use tokio::time::{sleep};
use crate::proposer::PATH_REGISTER_VALIDATORS;
use crate::proposer::tests::gen_signed_vr;
use helix_common::api::proposer_api::ValidatorPreferences;
use helix_common::ValidatorPreferences;
use helix_common::api::proposer_api::ValidatorRegistrationInfo;

// +++ HELPER VARIABLES +++
Expand Down
21 changes: 9 additions & 12 deletions crates/api/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,16 @@ impl ApiService {
NetworkConfig::Holesky => ChainInfo::for_holesky(),
});

// Housekeeper should only be run on one instance.
if config.run_housekeeper {
let housekeeper =
Housekeeper::new(db.clone(), multi_beacon_client.clone(), auctioneer.clone());
tokio::task::spawn(async move {
loop {
if let Err(err) = housekeeper.start().await {
tracing::error!("Housekeeper error: {}", err);
sleep(Duration::from_secs(5)).await;
}
let housekeeper =
Housekeeper::new(db.clone(), multi_beacon_client.clone(), auctioneer.clone());
tokio::spawn(async move {
loop {
if let Err(err) = housekeeper.start().await {
tracing::error!("Housekeeper error: {}", err);
sleep(Duration::from_secs(5)).await;
}
});
}
}
});

// Initialise relay signing context
let signing_key_str = env::var("RELAY_KEY").expect("could not find RELAY_KEY in env");
Expand Down
2 changes: 1 addition & 1 deletion crates/api/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use helix_database::MockDatabaseService;
use helix_datastore::MockAuctioneer;
use helix_common::signing::RelaySigningContext;
use helix_housekeeper::ChainUpdate;
use helix_common::api::proposer_api::ValidatorPreferences;
use helix_common::ValidatorPreferences;

use crate::{
builder::{
Expand Down
2 changes: 1 addition & 1 deletion crates/common/src/api/builder_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use ethereum_consensus::{
};
use serde::{Deserialize, Serialize};

use super::proposer_api::{ValidatorPreferences, ValidatorRegistrationInfo};
use crate::{ValidatorPreferences, api::proposer_api::ValidatorRegistrationInfo};

#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct BuilderGetValidatorsResponseEntry {
Expand Down
6 changes: 1 addition & 5 deletions crates/common/src/api/proposer_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use ethereum_consensus::{
Fork, builder::SignedValidatorRegistration,
};

use crate::versioned_payload::PayloadAndBlobs;
use crate::{validator_preferences::ValidatorPreferences, versioned_payload::PayloadAndBlobs};


#[derive(Debug, serde::Serialize)]
Expand Down Expand Up @@ -54,10 +54,6 @@ impl<'de> serde::Deserialize<'de> for GetPayloadResponse {
}
}

#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ValidatorPreferences {
pub censoring: bool,
}

#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ValidatorRegistrationInfo {
Expand Down
1 change: 1 addition & 0 deletions crates/common/src/builder_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ pub struct BuilderInfo {
#[serde(with = "as_str")]
pub collateral: U256,
pub is_optimistic: bool,
pub builder_id: Option<String>,
}
Loading

0 comments on commit 0166ecd

Please sign in to comment.