mina_node_testing/server/
webnode.rs

1use 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    // make sure cluster exists
25    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}