Skip to content

Commit 7954ff6

Browse files
committed
feat: remove HTTP port restrictions and request limit for WASM challenges
- allowed_ports: vec![] in development mode (allow all ports) - max_requests: u32::MAX in development mode (effectively unlimited) - Various clippy fixes and code improvements across crates
1 parent 95685d7 commit 7954ff6

File tree

25 files changed

+497
-368
lines changed

25 files changed

+497
-368
lines changed

.env.example

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ VALIDATOR_SECRET_KEY=
5151
# Bootstrap peers (auto-discovered from Bittensor if not set)
5252
# BOOTSTRAP_PEERS=/ip4/1.2.3.4/tcp/8090/p2p/12D3KooW...
5353

54+
# -----------------------------------------------------------------------------
55+
# LLM Review (Optional)
56+
# -----------------------------------------------------------------------------
57+
# Chutes API key for LLM review host function (enables LLM reviews in WASM challenges)
58+
# Get your key at https://chutes.ai
59+
# CHUTES_API_KEY=cpk_...
60+
5461
# -----------------------------------------------------------------------------
5562
# Logging (Optional)
5663
# -----------------------------------------------------------------------------

bins/platform-sudo/src/main.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,7 @@ impl SudoCli {
195195
Ok(keypair.sign(data).0.to_vec())
196196
}
197197

198-
async fn upload_wasm(
199-
&self,
200-
file: &PathBuf,
201-
challenge_id: &str,
202-
name: String,
203-
) -> Result<()> {
198+
async fn upload_wasm(&self, file: &PathBuf, challenge_id: &str, name: String) -> Result<()> {
204199
let wasm_bytes = std::fs::read(file).context("Failed to read WASM file")?;
205200

206201
info!(file = %file.display(), size = wasm_bytes.len(), "Uploading WASM module");
@@ -433,7 +428,9 @@ impl SudoCli {
433428
match parts[0] {
434429
"help" | "?" => {
435430
println!("\nCommands:");
436-
println!(" upload <file> <challenge_id> <name> - Upload WASM module");
431+
println!(
432+
" upload <file> <challenge_id> <name> - Upload WASM module"
433+
);
437434
println!(" activate <challenge_id> - Activate challenge");
438435
println!(
439436
" deactivate <challenge_id> - Deactivate challenge"

bins/validator-node/src/main.rs

Lines changed: 171 additions & 122 deletions
Large diffs are not rendered by default.

bins/validator-node/src/wasm_executor.rs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,7 +1220,8 @@ impl WasmChallengeExecutor {
12201220
}
12211221
}
12221222

1223-
let result = pi_guard.instance
1223+
let result = pi_guard
1224+
.instance
12241225
.call_return_i64("sync")
12251226
.map_err(|e| anyhow::anyhow!("WASM sync call failed: {}", e))?;
12261227

@@ -1238,7 +1239,8 @@ impl WasmChallengeExecutor {
12381239
});
12391240
}
12401241

1241-
let result_data = pi_guard.instance
1242+
let result_data = pi_guard
1243+
.instance
12421244
.read_memory(out_ptr as usize, out_len as usize)
12431245
.map_err(|e| anyhow::anyhow!("failed to read WASM memory for sync output: {}", e))?;
12441246

@@ -1445,7 +1447,12 @@ impl WasmChallengeExecutor {
14451447
block_height: u64,
14461448
epoch: u64,
14471449
) -> Result<Arc<Mutex<PersistentInstance>>> {
1448-
let current_version = self.module_versions.read().get(module_path).copied().unwrap_or(0);
1450+
let current_version = self
1451+
.module_versions
1452+
.read()
1453+
.get(module_path)
1454+
.copied()
1455+
.unwrap_or(0);
14491456

14501457
// Check if we already have a valid persistent instance
14511458
{
@@ -1461,7 +1468,8 @@ impl WasmChallengeExecutor {
14611468
}
14621469

14631470
// Create a new persistent instance
1464-
let module = self.load_module(module_path)
1471+
let module = self
1472+
.load_module(module_path)
14651473
.context("Failed to load WASM module for persistent instance")?;
14661474

14671475
let real_now_ms = std::time::SystemTime::now()
@@ -1490,7 +1498,8 @@ impl WasmChallengeExecutor {
14901498
..Default::default()
14911499
};
14921500

1493-
let instance = self.runtime
1501+
let instance = self
1502+
.runtime
14941503
.instantiate(&module, instance_config, None)
14951504
.map_err(|e| anyhow::anyhow!("Failed to create persistent WASM instance: {}", e))?;
14961505

@@ -1500,8 +1509,14 @@ impl WasmChallengeExecutor {
15001509
created_at: Instant::now(),
15011510
}));
15021511

1503-
self.persistent_instances.write().insert(module_path.to_string(), Arc::clone(&pi));
1504-
info!(module = module_path, version = current_version, "persistent WASM instance created");
1512+
self.persistent_instances
1513+
.write()
1514+
.insert(module_path.to_string(), Arc::clone(&pi));
1515+
info!(
1516+
module = module_path,
1517+
version = current_version,
1518+
"persistent WASM instance created"
1519+
);
15051520
Ok(pi)
15061521
}
15071522

@@ -1518,7 +1533,10 @@ impl WasmChallengeExecutor {
15181533
let mut guard = match pi.try_lock() {
15191534
Some(g) => g,
15201535
None => {
1521-
debug!(module = module_path, "background_tick skipped: instance busy (sync in progress)");
1536+
debug!(
1537+
module = module_path,
1538+
"background_tick skipped: instance busy (sync in progress)"
1539+
);
15221540
return Ok(());
15231541
}
15241542
};
@@ -1571,7 +1589,12 @@ impl WasmChallengeExecutor {
15711589
*v += 1;
15721590
info!(module = module_path, version = *v, "module version bumped");
15731591
// Drop old persistent instance
1574-
if self.persistent_instances.write().remove(module_path).is_some() {
1592+
if self
1593+
.persistent_instances
1594+
.write()
1595+
.remove(module_path)
1596+
.is_some()
1597+
{
15751598
info!(module = module_path, "persistent instance dropped");
15761599
}
15771600
}

crates/bittensor-integration/src/block_sync.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,7 @@ impl BlockSync {
245245
))
246246
.await;
247247

248-
tokio::time::sleep(std::time::Duration::from_secs(delay_secs as u64))
249-
.await;
248+
tokio::time::sleep(std::time::Duration::from_secs(delay_secs as u64)).await;
250249

251250
match BlockSync::recreate_listener(&rpc_url, &config).await {
252251
Ok((new_client, new_listener, new_rx, epoch_info)) => {
@@ -265,8 +264,7 @@ impl BlockSync {
265264
if let Err(e) = new_listener.start(new_client).await {
266265
warn!("Failed to start recreated listener: {}", e);
267266
} else {
268-
let _ =
269-
event_tx.send(BlockSyncEvent::Reconnected).await;
267+
let _ = event_tx.send(BlockSyncEvent::Reconnected).await;
270268
}
271269
}
272270
Err(e) => {

crates/bittensor-integration/src/client.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,7 @@ impl SubtensorClient {
4242
/// Reconnect to Subtensor by creating a fresh client.
4343
/// Useful when the underlying websocket has died.
4444
pub async fn reconnect(&mut self) -> Result<()> {
45-
info!(
46-
"Reconnecting to Subtensor: {}",
47-
self.config.endpoint
48-
);
45+
info!("Reconnecting to Subtensor: {}", self.config.endpoint);
4946
self.client = None;
5047
let client = BittensorClient::new(&self.config.endpoint).await?;
5148
self.client = Some(client);
@@ -82,7 +79,10 @@ impl SubtensorClient {
8279
return Err(first_err);
8380
}
8481

85-
info!("Transport error detected, attempting reconnect: {}", first_err);
82+
info!(
83+
"Transport error detected, attempting reconnect: {}",
84+
first_err
85+
);
8686
self.reconnect().await?;
8787

8888
let client = self

crates/challenge-registry/src/lifecycle.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,9 @@ mod tests {
277277
let challenge_id = ChallengeId::new("test");
278278

279279
// Test Registered event
280-
let registered_event = LifecycleEvent::Registered { challenge_id: challenge_id.clone() };
280+
let registered_event = LifecycleEvent::Registered {
281+
challenge_id: challenge_id.clone(),
282+
};
281283
match registered_event {
282284
LifecycleEvent::Registered { challenge_id: id } => {
283285
assert_eq!(id, challenge_id);
@@ -286,7 +288,9 @@ mod tests {
286288
}
287289

288290
// Test Unregistered event
289-
let unregistered_event = LifecycleEvent::Unregistered { challenge_id: challenge_id.clone() };
291+
let unregistered_event = LifecycleEvent::Unregistered {
292+
challenge_id: challenge_id.clone(),
293+
};
290294
match unregistered_event {
291295
LifecycleEvent::Unregistered { challenge_id: id } => {
292296
assert_eq!(id, challenge_id);

crates/challenge-registry/src/registry.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,9 @@ impl ChallengeRegistry {
201201
name_index.insert(name.clone(), id.clone());
202202

203203
info!(challenge_id = %id, name = %name, "Challenge registered");
204-
self.emit_event(LifecycleEvent::Registered { challenge_id: id.clone() });
204+
self.emit_event(LifecycleEvent::Registered {
205+
challenge_id: id.clone(),
206+
});
205207

206208
Ok(id)
207209
}
@@ -248,7 +250,9 @@ impl ChallengeRegistry {
248250
name_index.remove(&registered.entry.name);
249251

250252
info!(challenge_id = %id, "Challenge unregistered");
251-
self.emit_event(LifecycleEvent::Unregistered { challenge_id: id.clone() });
253+
self.emit_event(LifecycleEvent::Unregistered {
254+
challenge_id: id.clone(),
255+
});
252256

253257
Ok(registered.entry)
254258
}

crates/challenge-sdk-wasm/src/llm_types.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ pub struct FunctionDef {
149149
}
150150

151151
#[derive(Clone, Debug, Serialize, Deserialize)]
152-
#[serde(untagged)]
153152
pub enum ToolChoice {
154153
Auto,
155154
None,

crates/challenge-sdk/src/server.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -636,11 +636,17 @@ async fn custom_route_handler<C: ServerChallenge + 'static>(
636636
// In production, the ChallengeContext would be populated by the validator node
637637
let ctx = ChallengeContext {
638638
db: Arc::new(
639-
ChallengeDatabase::open(std::env::temp_dir(), crate::types::ChallengeId::new("test-challenge"))
640-
.unwrap_or_else(|_| {
641-
ChallengeDatabase::open(std::env::temp_dir(), crate::types::ChallengeId::new("test-challenge"))
642-
.expect("Failed to open temporary challenge database")
643-
}),
639+
ChallengeDatabase::open(
640+
std::env::temp_dir(),
641+
crate::types::ChallengeId::new("test-challenge"),
642+
)
643+
.unwrap_or_else(|_| {
644+
ChallengeDatabase::open(
645+
std::env::temp_dir(),
646+
crate::types::ChallengeId::new("test-challenge"),
647+
)
648+
.expect("Failed to open temporary challenge database")
649+
}),
644650
),
645651
challenge_id: state.challenge.challenge_id().to_string(),
646652
epoch: 0,

0 commit comments

Comments
 (0)