Skip to content
Open
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
27 changes: 0 additions & 27 deletions .cargo/audit.toml

This file was deleted.

5 changes: 3 additions & 2 deletions .github/workflows/security-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions-rs/audit-check@v1.2.0
- uses: taiki-e/install-action@43aecc8d72668fbcfe75c31400bc4f890f1c5853 # v2.83.2
with:
token: ${{ secrets.GITHUB_TOKEN }}
tool: cargo-audit
- run: cargo audit
26 changes: 18 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions crates/common/src/pbs/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ pub enum PbsError {
#[error("json decode error: {err:?}, raw: {raw}")]
JsonDecode { err: serde_json::Error, raw: String },

#[error("json encode error: {0:?}")]
JsonEncode(serde_json::Error),

#[error("ssz decode error: {err:?}, fork: {fork}")]
SSZDecode { err: String, fork: ForkName },

Expand Down Expand Up @@ -116,6 +119,9 @@ pub enum ValidationError {

#[error("unsupported fork")]
UnsupportedFork,

#[error("fork mismatch: request is {expected} but relay response is {got}")]
ForkMismatch { expected: ForkName, got: ForkName },
}

#[derive(Debug, Error, PartialEq, Eq)]
Expand Down
18 changes: 15 additions & 3 deletions crates/common/src/wire.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,10 @@ pub fn get_accept_types(
return Err(AcceptedEncodingsError::UnsupportedAcceptType)
}

// No accept header (or only q=0 rejections): fall back to the request
// Content-Type, which mirrors the historical behavior.
Ok(AcceptedEncodings::single(get_content_type(req_headers)))
// No Accept header (or only q=0 rejections): per the Builder API a missing
// Accept means JSON, and request/response encodings are independent — so do
// NOT inherit the request Content-Type (an SSZ request still gets JSON).
Ok(AcceptedEncodings::single(NO_PREFERENCE_DEFAULT))
}

fn essence_encoding(mt: &MediaType) -> Option<EncodingType> {
Expand Down Expand Up @@ -468,6 +469,17 @@ mod test {
assert_eq!(result, AcceptedEncodings::single(EncodingType::Json));
}

/// A missing Accept header defaults to JSON even when the request body is
/// SSZ: request and response encodings are independent, so the response
/// encoding MUST NOT inherit the request Content-Type.
#[test]
fn test_missing_accept_header_ignores_ssz_content_type() {
let mut headers = HeaderMap::new();
headers.append(CONTENT_TYPE, HeaderValue::from_str(APPLICATION_OCTET_STREAM).unwrap());
let result = get_accept_types(&headers).unwrap();
assert_eq!(result, AcceptedEncodings::single(EncodingType::Json));
}

/// Test accepting JSON
#[test]
fn test_accept_header_json() {
Expand Down
24 changes: 24 additions & 0 deletions crates/pbs/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ impl PbsClientError {
PbsClientError::NoResponse => StatusCode::BAD_GATEWAY,
PbsClientError::NoPayload => StatusCode::BAD_GATEWAY,
PbsClientError::Internal => StatusCode::INTERNAL_SERVER_ERROR,
PbsClientError::DecodeError(BodyDeserializeError::UnsupportedMediaType) => {
StatusCode::UNSUPPORTED_MEDIA_TYPE
}
PbsClientError::DecodeError(_) => StatusCode::BAD_REQUEST,
PbsClientError::HeaderError(_) => StatusCode::NOT_ACCEPTABLE,
}
Expand All @@ -45,3 +48,24 @@ impl IntoResponse for PbsClientError {
(self.status_code(), msg).into_response()
}
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn unsupported_media_type_maps_to_415() {
assert_eq!(
PbsClientError::DecodeError(BodyDeserializeError::UnsupportedMediaType).status_code(),
StatusCode::UNSUPPORTED_MEDIA_TYPE,
);
}

#[test]
fn other_decode_errors_map_to_400() {
assert_eq!(
PbsClientError::DecodeError(BodyDeserializeError::MissingVersionHeader).status_code(),
StatusCode::BAD_REQUEST,
);
}
}
11 changes: 11 additions & 0 deletions crates/pbs/src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,15 @@ lazy_static! {
&["http_status_code", "endpoint"],
PBS_METRICS_REGISTRY
).unwrap();

/// Count of v2 submit_block requests that could not be served because the
/// relay returned 404 on the v2 endpoint. A non-zero value means the relay
/// fleet has not been upgraded to support submitBlindedBlockV2 and those
/// blocks were not submitted.
pub static ref RELAY_V2_UNSUPPORTED: IntCounterVec = register_int_counter_vec_with_registry!(
"pbs_submit_block_v2_unsupported_total",
"Count of v2 submit_block requests a relay could not serve because it does not support v2",
&["relay_id"],
PBS_METRICS_REGISTRY
).unwrap();
}
Loading
Loading