diff --git a/Cargo.lock b/Cargo.lock index fc7c61ac..116bd4f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1711,7 +1711,7 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cb-bench-micro" -version = "0.9.6" +version = "0.10.0-rc2" dependencies = [ "alloy", "axum 0.8.9", @@ -1724,7 +1724,7 @@ dependencies = [ [[package]] name = "cb-bench-pbs" -version = "0.9.6" +version = "0.10.0-rc2" dependencies = [ "alloy", "cb-common", @@ -1741,7 +1741,7 @@ dependencies = [ [[package]] name = "cb-cli" -version = "0.9.6" +version = "0.10.0-rc2" dependencies = [ "cb-common", "clap", @@ -1755,7 +1755,7 @@ dependencies = [ [[package]] name = "cb-common" -version = "0.9.6" +version = "0.10.0-rc2" dependencies = [ "aes", "alloy", @@ -1807,7 +1807,7 @@ dependencies = [ [[package]] name = "cb-metrics" -version = "0.9.6" +version = "0.10.0-rc2" dependencies = [ "axum 0.8.9", "cb-common", @@ -1820,7 +1820,7 @@ dependencies = [ [[package]] name = "cb-pbs" -version = "0.9.6" +version = "0.10.0-rc2" dependencies = [ "alloy", "async-trait", @@ -1847,7 +1847,7 @@ dependencies = [ [[package]] name = "cb-signer" -version = "0.9.6" +version = "0.10.0-rc2" dependencies = [ "alloy", "axum 0.8.9", @@ -1878,7 +1878,7 @@ dependencies = [ [[package]] name = "cb-tests" -version = "0.9.6" +version = "0.10.0-rc2" dependencies = [ "alloy", "axum 0.8.9", @@ -2097,7 +2097,7 @@ dependencies = [ [[package]] name = "commit-boost" -version = "0.9.6" +version = "0.10.0-rc2" dependencies = [ "assert_cmd", "cb-cli", @@ -2396,7 +2396,7 @@ dependencies = [ [[package]] name = "da_commit" -version = "0.9.6" +version = "0.10.0-rc2" dependencies = [ "alloy", "color-eyre", @@ -6381,7 +6381,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "status_api" -version = "0.9.6" +version = "0.10.0-rc2" dependencies = [ "async-trait", "axum 0.8.9", diff --git a/Cargo.toml b/Cargo.toml index 0adabb6c..a9954328 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ resolver = "2" [workspace.package] edition = "2024" rust-version = "1.91" -version = "0.9.6" +version = "0.10.0-rc2" [workspace.dependencies] aes = "0.8" diff --git a/crates/common/src/interop/ssv/utils.rs b/crates/common/src/interop/ssv/utils.rs index 4a262d69..e875619b 100644 --- a/crates/common/src/interop/ssv/utils.rs +++ b/crates/common/src/interop/ssv/utils.rs @@ -16,8 +16,13 @@ pub async fn request_ssv_pubkeys_from_ssv_node( http_timeout: Duration, ) -> eyre::Result { let client = reqwest::ClientBuilder::new().timeout(http_timeout).build()?; + // The SSV node API expects operator IDs as numeric (uint64) values. Serializing + // the U256 directly emits a JSON string, which the node rejects with a 400, + // so narrow it to a u64 first. + let operator_id = u64::try_from(node_operator_id) + .map_err(|e| eyre::eyre!("SSV node operator ID does not fit in u64: {e}"))?; let body = json!({ - "operators": [node_operator_id] + "operators": [operator_id] }); let response = client.get(url).json(&body).send().await.map_err(|e| { if e.is_timeout() { @@ -50,3 +55,25 @@ pub async fn request_ssv_pubkeys_from_public_api( serde_json::from_slice::(&body_bytes) .wrap_err("failed to parse SSV response") } + +#[cfg(test)] +mod tests { + use alloy::primitives::U256; + use serde_json::json; + + #[test] + fn ssv_node_request_serializes_operator_as_number() { + let node_operator_id = U256::from(100u64); + + // Regression guard: serializing the U256 directly emits a (hex) JSON string, + // which the SSV node rejects ("cannot unmarshal string into ... + // uint64"). + let stringy = serde_json::to_string(&json!({ "operators": [node_operator_id] })).unwrap(); + assert_eq!(stringy, r#"{"operators":["0x64"]}"#); + + // The fix narrows to u64 so the operator ID is emitted as a numeric value. + let operator_id = u64::try_from(node_operator_id).unwrap(); + let numeric = serde_json::to_string(&json!({ "operators": [operator_id] })).unwrap(); + assert_eq!(numeric, r#"{"operators":[100]}"#); + } +}