mina_node_testing/server/
webnode.rs1use axum::{
2 extract::{Path, State},
3 http::StatusCode,
4 response::Redirect,
5 routing::get,
6};
7use rand::prelude::*;
8
9use crate::scenarios::ClusterRunner;
10
11use super::AppState;
12
13pub fn router() -> axum::Router<AppState> {
14 axum::Router::new()
15 .route("/", get(webnode_get))
16 .route("/lock-random-bp", get(webnode_lock_random_bp))
17}
18
19async fn webnode_get(
20 State(state): State<AppState>,
21 Path(cluster_id): Path<u16>,
22) -> Result<Redirect, (StatusCode, String)> {
23 use base64::{engine::general_purpose::URL_SAFE, Engine as _};
24 state.cluster_mutex(cluster_id).await?;
26
27 let args = serde_json::json!({
28 "network": cluster_id,
29 })
30 .to_string();
31 let args = URL_SAFE.encode(&args);
32
33 Ok(Redirect::temporary(&format!("/?a={args}")))
34}
35
36async fn webnode_lock_random_bp(
37 State(state): State<AppState>,
38 Path(cluster_id): Path<u16>,
39) -> Result<Redirect, (StatusCode, String)> {
40 use base64::{engine::general_purpose::URL_SAFE, Engine as _};
41 let mut state_guard = state.lock().await;
42 let state = &mut *state_guard;
43 let mut cluster = state.cluster(cluster_id).await?;
44 let runner = ClusterRunner::new(&mut cluster, |_| {});
45 let locked_keys = state
46 .locked_block_producer_keys
47 .entry(cluster_id)
48 .or_default();
49
50 let (sec_key, _) = runner
51 .block_producer_sec_keys(runner.nodes_iter().next().unwrap().0)
52 .into_iter()
53 .filter(|(key, _)| !locked_keys.contains(&key.public_key()))
54 .choose(&mut state.rng)
55 .ok_or_else(|| {
56 (
57 StatusCode::NOT_ACCEPTABLE,
58 "no more block producer keys available!".to_owned(),
59 )
60 })?;
61 locked_keys.insert(sec_key.public_key());
62
63 let args = serde_json::json!({
64 "network": cluster_id,
65 "block_producer": {
66 "sec_key": sec_key.to_string(),
67 "pub_key": sec_key.public_key().to_string(),
68 },
69 })
70 .to_string();
71 let args = URL_SAFE.encode(&args);
72
73 Ok(Redirect::temporary(&format!("/?a={args}")))
74}