Skip to content

Commit 972161d

Browse files
committed
feat: validate miner_hotkey is SS58 format in /submit endpoint
Reject submissions with invalid miner_hotkey format early with clear error message. This ensures miner identity is always stored as valid SS58 hotkey address.
1 parent 319f92d commit 972161d

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

crates/platform-server/src/api/submissions.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@ use axum::{
99
Json,
1010
};
1111
use serde::Deserialize;
12+
use sp_core::crypto::Ss58Codec;
1213
use std::sync::Arc;
1314

15+
/// Validate that a string is a valid SS58 hotkey address
16+
fn is_valid_ss58_hotkey(hotkey: &str) -> bool {
17+
sp_core::crypto::AccountId32::from_ss58check(hotkey).is_ok()
18+
}
19+
1420
#[derive(Debug, Deserialize)]
1521
pub struct ListSubmissionsQuery {
1622
pub limit: Option<usize>,
@@ -63,6 +69,26 @@ pub async fn submit_agent(
6369
State(state): State<Arc<AppState>>,
6470
Json(req): Json<SubmitAgentRequest>,
6571
) -> Result<Json<SubmitAgentResponse>, (StatusCode, Json<SubmitAgentResponse>)> {
72+
// Validate miner_hotkey is a valid SS58 address
73+
if !is_valid_ss58_hotkey(&req.miner_hotkey) {
74+
tracing::warn!(
75+
"Invalid miner_hotkey format: {} (expected SS58 address starting with '5')",
76+
&req.miner_hotkey[..32.min(req.miner_hotkey.len())]
77+
);
78+
return Err((
79+
StatusCode::BAD_REQUEST,
80+
Json(SubmitAgentResponse {
81+
success: false,
82+
submission_id: None,
83+
agent_hash: None,
84+
error: Some(format!(
85+
"Invalid miner_hotkey: must be a valid SS58 address (e.g., '5GrwvaEF...'). Received: {}",
86+
&req.miner_hotkey[..32.min(req.miner_hotkey.len())]
87+
)),
88+
}),
89+
));
90+
}
91+
6692
let epoch = queries::get_current_epoch(&state.db).await.unwrap_or(0);
6793

6894
// Rate limiting: 0.33 submissions per epoch (1 every 3 epochs)

0 commit comments

Comments
 (0)