diff --git a/crates/pbs/src/constants.rs b/crates/pbs/src/constants.rs index 8dc3bd86..30914803 100644 --- a/crates/pbs/src/constants.rs +++ b/crates/pbs/src/constants.rs @@ -10,9 +10,12 @@ pub const TIMEOUT_ERROR_CODE_STR: &str = "555"; /// 20 MiB to cover edge cases for heavy blocks and also add a bit of slack for /// any Ethereum upgrades in the near future -pub const MAX_SIZE_SUBMIT_BLOCK: usize = 20 * 1024 * 1024; +pub const MAX_SIZE_SUBMIT_BLOCK_RESPONSE: usize = 20 * 1024 * 1024; + +/// 20 MiB, enough to process ~45000 registrations in one request +pub const MAX_SIZE_REGISTER_VALIDATOR_REQUEST: usize = 20 * 1024 * 1024; /// 10 KiB, headers are around 700 bytes + buffer for encoding -pub const MAX_SIZE_GET_HEADER: usize = 10 * 1024; +pub const MAX_SIZE_GET_HEADER_RESPONSE: usize = 10 * 1024; pub const MAX_SIZE_DEFAULT: usize = 1024; diff --git a/crates/pbs/src/mev_boost/get_header.rs b/crates/pbs/src/mev_boost/get_header.rs index 4423f249..e4922245 100644 --- a/crates/pbs/src/mev_boost/get_header.rs +++ b/crates/pbs/src/mev_boost/get_header.rs @@ -31,7 +31,8 @@ use url::Url; use crate::{ constants::{ - GET_HEADER_ENDPOINT_TAG, MAX_SIZE_GET_HEADER, TIMEOUT_ERROR_CODE, TIMEOUT_ERROR_CODE_STR, + GET_HEADER_ENDPOINT_TAG, MAX_SIZE_GET_HEADER_RESPONSE, TIMEOUT_ERROR_CODE, + TIMEOUT_ERROR_CODE_STR, }, metrics::{RELAY_HEADER_VALUE, RELAY_LAST_SLOT, RELAY_LATENCY, RELAY_STATUS_CODE}, state::{BuilderApiState, PbsState}, @@ -323,7 +324,7 @@ async fn send_one_get_header( let code = res.status(); RELAY_STATUS_CODE.with_label_values(&[code.as_str(), GET_HEADER_ENDPOINT_TAG, &relay.id]).inc(); - let response_bytes = read_chunked_body_with_max(res, MAX_SIZE_GET_HEADER).await?; + let response_bytes = read_chunked_body_with_max(res, MAX_SIZE_GET_HEADER_RESPONSE).await?; if !code.is_success() { return Err(PbsError::RelayResponse { error_msg: String::from_utf8_lossy(&response_bytes).into_owned(), diff --git a/crates/pbs/src/mev_boost/submit_block.rs b/crates/pbs/src/mev_boost/submit_block.rs index 16d098dd..abb9554f 100644 --- a/crates/pbs/src/mev_boost/submit_block.rs +++ b/crates/pbs/src/mev_boost/submit_block.rs @@ -16,7 +16,9 @@ use tracing::{debug, warn}; use url::Url; use crate::{ - constants::{MAX_SIZE_SUBMIT_BLOCK, SUBMIT_BLINDED_BLOCK_ENDPOINT_TAG, TIMEOUT_ERROR_CODE_STR}, + constants::{ + MAX_SIZE_SUBMIT_BLOCK_RESPONSE, SUBMIT_BLINDED_BLOCK_ENDPOINT_TAG, TIMEOUT_ERROR_CODE_STR, + }, metrics::{RELAY_LATENCY, RELAY_STATUS_CODE}, state::{BuilderApiState, PbsState}, utils::read_chunked_body_with_max, @@ -139,7 +141,7 @@ async fn send_submit_block( .with_label_values(&[code.as_str(), SUBMIT_BLINDED_BLOCK_ENDPOINT_TAG, &relay.id]) .inc(); - let response_bytes = read_chunked_body_with_max(res, MAX_SIZE_SUBMIT_BLOCK).await?; + let response_bytes = read_chunked_body_with_max(res, MAX_SIZE_SUBMIT_BLOCK_RESPONSE).await?; if !code.is_success() { let err = PbsError::RelayResponse { error_msg: String::from_utf8_lossy(&response_bytes).into_owned(), diff --git a/crates/pbs/src/routes/router.rs b/crates/pbs/src/routes/router.rs index e5a28de5..37095f27 100644 --- a/crates/pbs/src/routes/router.rs +++ b/crates/pbs/src/routes/router.rs @@ -1,5 +1,5 @@ use axum::{ - extract::{MatchedPath, Request}, + extract::{DefaultBodyLimit, MatchedPath, Request}, middleware::{self, Next}, response::Response, routing::{get, post}, @@ -20,16 +20,27 @@ use super::{ use crate::{ api::BuilderApi, state::{BuilderApiState, PbsStateGuard}, + MAX_SIZE_REGISTER_VALIDATOR_REQUEST, MAX_SIZE_SUBMIT_BLOCK_RESPONSE, }; pub fn create_app_router>(state: PbsStateGuard) -> Router { + // DefaultBodyLimit is 2Mib by default, so we only increase it for a few routes + // thay may need more + let builder_routes = Router::new() .route(GET_HEADER_PATH, get(handle_get_header::)) .route(GET_STATUS_PATH, get(handle_get_status::)) - .route(REGISTER_VALIDATOR_PATH, post(handle_register_validator::)) - .route(SUBMIT_BLOCK_PATH, post(handle_submit_block::)); + .route( + REGISTER_VALIDATOR_PATH, + post(handle_register_validator::) + .route_layer(DefaultBodyLimit::max(MAX_SIZE_REGISTER_VALIDATOR_REQUEST)), + ) + .route( + SUBMIT_BLOCK_PATH, + post(handle_submit_block::) + .route_layer(DefaultBodyLimit::max(MAX_SIZE_SUBMIT_BLOCK_RESPONSE)), + ); // header is smaller than the response but err on the safe side let reload_router = Router::new().route(RELOAD_PATH, post(handle_reload::)); - let builder_api = Router::new().nest(BUILDER_API_PATH, builder_routes).merge(reload_router); let app = if let Some(extra_routes) = A::extra_routes() { @@ -58,7 +69,7 @@ pub async fn tracing_middleware(req: Request, next: Next) -> Response { trace!( http.method = %req.method(), http.user_agent = req.headers().typed_get::().map(|ua| ua.to_string()).unwrap_or_default(), - http.content_type = req.headers().typed_get::().map(|ua| ua.to_string()).unwrap_or_default(), + http.content_type = req.headers().typed_get::().map(|ua| ua.to_string()).unwrap_or_default(), "start request"); let response = next.run(req).await; diff --git a/tests/src/mock_relay.rs b/tests/src/mock_relay.rs index 9974bae3..beedb5d7 100644 --- a/tests/src/mock_relay.rs +++ b/tests/src/mock_relay.rs @@ -25,7 +25,7 @@ use cb_common::{ types::Chain, utils::{blst_pubkey_to_alloy, timestamp_of_slot_start_sec}, }; -use cb_pbs::MAX_SIZE_SUBMIT_BLOCK; +use cb_pbs::MAX_SIZE_SUBMIT_BLOCK_RESPONSE; use tokio::net::TcpListener; use tracing::debug; use tree_hash::TreeHash; @@ -136,7 +136,7 @@ async fn handle_register_validator( async fn handle_submit_block(State(state): State>) -> Response { state.received_submit_block.fetch_add(1, Ordering::Relaxed); if state.large_body() { - (StatusCode::OK, Json(vec![1u8; 1 + MAX_SIZE_SUBMIT_BLOCK])).into_response() + (StatusCode::OK, Json(vec![1u8; 1 + MAX_SIZE_SUBMIT_BLOCK_RESPONSE])).into_response() } else { let response = SubmitBlindedBlockResponse::default(); (StatusCode::OK, Json(response)).into_response()