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
37 changes: 26 additions & 11 deletions crates/key-server/src/aggregator/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ const REFRESH_INTERVAL_SECS: u64 = 30;
/// Default SDK version requirement.
fn default_ts_sdk_version_requirement() -> VersionReq {
// TODO: Update on first aggregator compatible SDK release.
VersionReq::parse(">=1000.0.0").expect("Failed to parse default SDK version requirement")
VersionReq::parse(">=1000.0.0").expect("Failed to parse default ts SDK version requirement")
}

/// Default SDK version requirement.
fn default_rust_sdk_version_requirement() -> VersionReq {
VersionReq::parse(">=0.0.0").expect("Failed to parse default rust SDK version requirement")
}

/// Default key server version requirement.
Expand Down Expand Up @@ -88,6 +93,10 @@ struct AggregatorOptions {
#[serde(default = "default_ts_sdk_version_requirement")]
ts_sdk_version_requirement: VersionReq,

/// The minimum version of the SDK that is required to use this aggregator.
#[serde(default = "default_rust_sdk_version_requirement")]
rust_sdk_version_requirement: VersionReq,

/// The minimum version of the key server that is required by this aggregator.
#[serde(default = "default_key_server_version_requirement")]
key_server_version_requirement: VersionReq,
Expand Down Expand Up @@ -123,19 +132,21 @@ impl AppState {
fn validate_sdk_version(
&self,
version: &str,
sdk_type: Option<&HeaderValue>,
sdk_type: ClientSdkType,
) -> Result<(), InternalError> {
let version = Version::parse(version).map_err(|_| InvalidSDKVersion)?;
let sdk_type = ClientSdkType::from_header(sdk_type.and_then(|v| v.to_str().ok()));

match sdk_type {
ClientSdkType::TypeScript => {
if !self.options.ts_sdk_version_requirement.matches(&version) {
return Err(DeprecatedSDKVersion);
}
}
_ => {
// TODO: Add support for other SDK types.
ClientSdkType::Rust => {
if !self.options.rust_sdk_version_requirement.matches(&version) {
return Err(DeprecatedSDKVersion);
}
}
ClientSdkType::Aggregator | ClientSdkType::Other => {
return Err(InvalidSDKType);
}
}
Expand Down Expand Up @@ -246,7 +257,8 @@ async fn handle_fetch_key(

// Extract headers and validate version.
let version = headers.get(HEADER_CLIENT_SDK_VERSION);
let sdk_type = headers.get(HEADER_CLIENT_SDK_TYPE);
let sdk_type_header = headers.get(HEADER_CLIENT_SDK_TYPE);
let sdk_type = ClientSdkType::from_header(sdk_type_header.and_then(|t| t.to_str().ok()))?;

let version_str = version
.ok_or_else(|| {
Expand Down Expand Up @@ -278,18 +290,16 @@ async fn handle_fetch_key(
})?;

// Track client SDK version by type
let sdk_type_enum = ClientSdkType::from_header(sdk_type.and_then(|v| v.to_str().ok()));
let sdk_type_str = sdk_type_enum.to_string();
state
.aggregator_metrics
.client_sdk_version
.with_label_values(&[&sdk_type_str, version_str])
.with_label_values(&[&sdk_type.to_string(), version_str])
.inc();

// Log incoming request with structured data
info!(
"Aggregator request - req_id: {}, SDK version: {}, SDK type: {:?}, user: {:?}",
req_id, version_str, sdk_type_enum, request.certificate.user
req_id, version_str, sdk_type, request.certificate.user
);

// Call to committee members' servers in parallel.
Expand Down Expand Up @@ -703,6 +713,7 @@ mod tests {
node_url: None,
key_server_object_id: Address::from([0u8; 32]),
ts_sdk_version_requirement: VersionReq::parse(">=0.9.0").unwrap(),
rust_sdk_version_requirement: VersionReq::parse(">=0.0.0").unwrap(),
key_server_version_requirement: VersionReq::parse(">=0.5.14").unwrap(),
api_credentials,
};
Expand Down Expand Up @@ -744,6 +755,7 @@ mod tests {
let (request, _, _) = create_test_fetch_key_request(&mut thread_rng());

let mut headers = HeaderMap::new();
headers.insert(HEADER_CLIENT_SDK_TYPE, "typescript".parse().unwrap());
headers.insert(HEADER_CLIENT_SDK_VERSION, "0.3.0".parse().unwrap()); // Too old
let result = handle_fetch_key(State(state), headers, Json(request)).await;

Expand Down Expand Up @@ -775,6 +787,7 @@ mod tests {
let (request, _, _) = create_test_fetch_key_request(&mut thread_rng());

let mut headers = HeaderMap::new();
headers.insert(HEADER_CLIENT_SDK_TYPE, "typescript".parse().unwrap());
headers.insert(HEADER_CLIENT_SDK_VERSION, "0.9.6".parse().unwrap());
let result = handle_fetch_key(State(state), headers, Json(request)).await;

Expand Down Expand Up @@ -806,6 +819,7 @@ mod tests {
let (request, _, _) = create_test_fetch_key_request(&mut thread_rng());

let mut headers = HeaderMap::new();
headers.insert(HEADER_CLIENT_SDK_TYPE, "typescript".parse().unwrap());
headers.insert(HEADER_CLIENT_SDK_VERSION, "0.9.6".parse().unwrap());
let result = handle_fetch_key(State(state), headers, Json(request)).await;
let response = result.unwrap().into_response();
Expand Down Expand Up @@ -869,6 +883,7 @@ mod tests {

// Call handle_fetch_key and check majority error.
let mut headers = HeaderMap::new();
headers.insert(HEADER_CLIENT_SDK_TYPE, "typescript".parse().unwrap());
headers.insert(HEADER_CLIENT_SDK_VERSION, "0.9.6".parse().unwrap());
let result = handle_fetch_key(State(state), headers, Json(request)).await;
match result {
Expand Down
21 changes: 14 additions & 7 deletions crates/key-server/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use axum::response::Response;
use serde::{Deserialize, Serialize};
use sui_types::base_types::ObjectID;

use crate::errors::InternalError;

/// Network configuration.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub enum Network {
Expand Down Expand Up @@ -50,6 +52,9 @@ pub const SDK_TYPE_AGGREGATOR: &str = "aggregator";
/// SDK type value for TypeScript clients.
pub const SDK_TYPE_TYPESCRIPT: &str = "typescript";

/// SDK type value for Rust clients.
pub const SDK_TYPE_RUST: &str = "rust";

/// Get the git version.
/// Based on https://github.com/MystenLabs/walrus/blob/7e282a681e6530ae4073210b33cac915fab439fa/crates/walrus-service/src/common/utils.rs#L69
#[macro_export]
Expand Down Expand Up @@ -80,23 +85,25 @@ macro_rules! git_version {
pub enum ClientSdkType {
Aggregator,
TypeScript,
Rust,
Other,
}

impl ClientSdkType {
pub fn from_header(header_value: Option<&str>) -> Self {
pub fn from_header(header_value: Option<&str>) -> Result<ClientSdkType, InternalError> {
match header_value {
Some(SDK_TYPE_AGGREGATOR) => ClientSdkType::Aggregator,
Some(SDK_TYPE_TYPESCRIPT) => ClientSdkType::TypeScript,
Some(_) => ClientSdkType::Other,
None => ClientSdkType::TypeScript, // Default to TypeScript for backward compatibility
Some(SDK_TYPE_AGGREGATOR) => Ok(ClientSdkType::Aggregator),
Some(SDK_TYPE_TYPESCRIPT) => Ok(ClientSdkType::TypeScript),
Some(SDK_TYPE_RUST) => Ok(ClientSdkType::Rust),
_ => Ok(ClientSdkType::Other),
}
}

pub fn as_str(&self) -> &'static str {
match self {
ClientSdkType::Aggregator => "aggregator",
ClientSdkType::TypeScript => "typescript",
ClientSdkType::Aggregator => SDK_TYPE_AGGREGATOR,
ClientSdkType::TypeScript => SDK_TYPE_TYPESCRIPT,
ClientSdkType::Rust => SDK_TYPE_RUST,
ClientSdkType::Other => "other",
}
}
Expand Down
9 changes: 9 additions & 0 deletions crates/key-server/src/key_server_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ pub struct KeyServerOptions {
#[serde(default = "default_ts_sdk_version_requirement")]
pub ts_sdk_version_requirement: VersionReq,

/// The minimum version of the Rust SDK that is required to use this key server.
#[serde(default = "default_rust_sdk_version_requirement")]
pub rust_sdk_version_requirement: VersionReq,

/// The minimum version of the aggregator that is required to use this key server.
#[serde(default = "default_aggregator_version_requirement")]
pub aggregator_version_requirement: VersionReq,
Expand Down Expand Up @@ -184,6 +188,7 @@ impl KeyServerOptions {
node_url: None,
ts_sdk_version_requirement: default_ts_sdk_version_requirement(),
aggregator_version_requirement: default_aggregator_version_requirement(),
rust_sdk_version_requirement: default_rust_sdk_version_requirement(),
server_mode: ServerMode::Open {
key_server_object_id,
},
Expand All @@ -203,6 +208,7 @@ impl KeyServerOptions {
node_url: None,
ts_sdk_version_requirement: default_ts_sdk_version_requirement(),
aggregator_version_requirement: default_aggregator_version_requirement(),
rust_sdk_version_requirement: default_rust_sdk_version_requirement(),
server_mode: ServerMode::Open {
key_server_object_id: ObjectID::random(),
},
Expand Down Expand Up @@ -336,6 +342,9 @@ fn default_aggregator_version_requirement() -> VersionReq {
VersionReq::parse(">=1000.0.0").expect("Failed to parse default aggregator version requirement")
}

fn default_rust_sdk_version_requirement() -> VersionReq {
VersionReq::parse(">=0.0.0").expect("Failed to parse default Rust SDK version requirement")
}
#[test]
fn test_parse_open_config() {
use std::str::FromStr;
Expand Down
10 changes: 5 additions & 5 deletions crates/key-server/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,8 @@ impl MyState {
let requirement = match sdk_type {
ClientSdkType::Aggregator => &self.server.options.aggregator_version_requirement,
ClientSdkType::TypeScript => &self.server.options.ts_sdk_version_requirement,
ClientSdkType::Other => return Ok(()),
ClientSdkType::Rust => &self.server.options.rust_sdk_version_requirement,
ClientSdkType::Other => return Ok(()), // Ignore if sdk type is unknown string or not provided
};

if !requirement.matches(&version) {
Expand All @@ -875,7 +876,7 @@ async fn handle_request_headers(
) -> Result<Response, InternalError> {
// Log the request id and SDK version
let version = request.headers().get(HEADER_CLIENT_SDK_VERSION);
let sdk_type = request.headers().get(HEADER_CLIENT_SDK_TYPE);
let sdk_type_header = request.headers().get(HEADER_CLIENT_SDK_TYPE);

info!(
"Request id: {:?}, SDK version: {:?}, SDK type: {:?}, Target API version: {:?}",
Expand All @@ -884,12 +885,11 @@ async fn handle_request_headers(
.get("Request-Id")
.map(|v| v.to_str().unwrap_or_default()),
version,
sdk_type,
sdk_type_header,
request.headers().get("Client-Target-Api-Version")
);

let sdk_type = ClientSdkType::from_header(sdk_type.and_then(|t| t.to_str().ok()));

let sdk_type = ClientSdkType::from_header(sdk_type_header.and_then(|t| t.to_str().ok()))?;
let version_str = version
.ok_or(MissingRequiredHeader(HEADER_CLIENT_SDK_VERSION.to_string()))
.and_then(|v| v.to_str().map_err(|_| InvalidSDKVersion))
Expand Down
1 change: 1 addition & 0 deletions crates/key-server/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ impl SealTestCluster {
rgp_update_interval: Duration::from_secs(60),
ts_sdk_version_requirement: VersionReq::from_str(">=0.4.6").unwrap(),
aggregator_version_requirement: VersionReq::from_str(">=0.5.15").unwrap(),
rust_sdk_version_requirement: VersionReq::from_str(">=0.0.0").unwrap(),
allowed_staleness,
session_key_ttl_max: from_mins(30),
rpc_config: RpcConfig::default(),
Expand Down
3 changes: 3 additions & 0 deletions crates/key-server/src/tests/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ async fn test_service() {
"http://{addr}/v1/service?service_id={}",
key_server_object_id.as_str()
))
.header(HEADER_CLIENT_SDK_TYPE, "typescript")
.header(HEADER_CLIENT_SDK_VERSION, "0.3.0") // Too old (requires >=0.4.6)
.body(Body::empty())
.unwrap(),
Expand Down Expand Up @@ -196,6 +197,7 @@ async fn test_service() {
"http://{addr}/v1/service?service_id={}",
key_server_object_id.as_str()
))
.header(HEADER_CLIENT_SDK_TYPE, "typescript")
.header(HEADER_CLIENT_SDK_VERSION, "0.4.11")
.body(Body::empty())
.unwrap(),
Expand Down Expand Up @@ -343,6 +345,7 @@ async fn test_fetch_key() {
Request::builder()
.uri(format!("http://{addr}/v1/fetch_key",))
.method("POST")
.header(HEADER_CLIENT_SDK_TYPE, "typescript")
.header(HEADER_CLIENT_SDK_VERSION, "0.4.11")
.header("Content-Type", "application/json")
.body(Body::from(json!(request).to_string()))
Expand Down
1 change: 1 addition & 0 deletions crates/key-server/src/tests/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ pub(crate) async fn create_test_server(
metrics_host_port: 0,
rgp_update_interval: Duration::from_secs(60),
ts_sdk_version_requirement: VersionReq::from_str(">=0.4.6").unwrap(),
rust_sdk_version_requirement: VersionReq::from_str(">=0.0.0").unwrap(),
aggregator_version_requirement: VersionReq::from_str(">=0.5.15").unwrap(),
allowed_staleness: Duration::from_secs(120),
session_key_ttl_max: from_mins(30),
Expand Down
2 changes: 1 addition & 1 deletion crates/seal-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ async fn main() -> FastCryptoResult<()> {
match client
.post(format!("{}/v1/fetch_key", server.url))
.header("Client-Sdk-Type", "rust")
.header("Client-Sdk-Version", "1.0.0")
.header("Client-Sdk-Version", "0.0.0")
.header("Content-Type", "application/json")
.body(Body::from(
request.to_json_string().expect("should not fail"),
Expand Down
32 changes: 1 addition & 31 deletions move/seal_testnet/Move.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,7 @@
# This file should be checked in.

[move]
version = 3
manifest_digest = "B153E07850EC7C7BD445C2B37390A7926AD3C299ADED88E38D8F0BB1E8393219"
deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082"
dependencies = [
{ id = "Sui", name = "Sui" },
]

[[move.package]]
id = "MoveStdlib"
source = { git = "https://github.com/MystenLabs/sui.git", rev = "testnet-v1.61.2", subdir = "crates/sui-framework/packages/move-stdlib" }

[[move.package]]
id = "Sui"
source = { git = "https://github.com/MystenLabs/sui.git", rev = "testnet-v1.61.2", subdir = "crates/sui-framework/packages/sui-framework" }

dependencies = [
{ id = "MoveStdlib", name = "MoveStdlib" },
]

[move.toolchain-version]
compiler-version = "1.61.2"
edition = "2024.beta"
flavor = "sui"
version = 4

[pinned.testnet.MoveStdlib]
source = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/move-stdlib", rev = "6c229fe6c04fb21ec98751c798e57e9a00e028e2" }
Expand All @@ -43,11 +21,3 @@ source = { root = true }
use_environment = "testnet"
manifest_digest = "65066A1AFA6718772BD68F6AFE27843F2371E14C4CF891FC7DADDFA586DABF89"
deps = { Sui = "Sui" }

[env]

[env.testnet]
chain-id = "4c78adac"
original-published-id = "0xbad13e742065222c16cc2936a46a5d44586b8546917fa129f65277c4bdbca03d"
latest-published-id = "0xbad13e742065222c16cc2936a46a5d44586b8546917fa129f65277c4bdbca03d"
published-version = "1"