Skip to main content

casper_devnet/
control.rs

1use anyhow::{Result, anyhow};
2use serde::{Deserialize, Serialize};
3use std::path::Path;
4use tokio::io::{AsyncReadExt, AsyncWriteExt};
5use tokio::net::UnixStream;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8#[serde(tag = "command", rename_all = "snake_case")]
9pub enum ControlRequest {
10    RuntimeStatus,
11    StageProtocol {
12        #[serde(default, skip_serializing_if = "Option::is_none")]
13        asset: Option<String>,
14        #[serde(default, skip_serializing_if = "Option::is_none")]
15        custom_asset: Option<String>,
16        #[serde(default, skip_serializing_if = "Option::is_none")]
17        asset_name: Option<String>,
18        protocol_version: String,
19        activation_point: u64,
20        #[serde(default, skip_serializing_if = "Vec::is_empty")]
21        chainspec_overrides: Vec<String>,
22        restart_sidecars: bool,
23        rust_log: Option<String>,
24    },
25    AddNodes {
26        count: u32,
27    },
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize)]
31#[serde(tag = "status", rename_all = "snake_case")]
32pub enum ControlResponse {
33    Ok { result: ControlResult },
34    Error { error: String },
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize)]
38#[serde(tag = "command", rename_all = "snake_case")]
39pub enum ControlResult {
40    RuntimeStatus {
41        running_node_ids: Vec<u32>,
42        last_block_height: Option<u64>,
43    },
44    StageProtocol {
45        live_mode: bool,
46        staged_nodes: u32,
47        restarted_sidecars: Vec<u32>,
48    },
49    AddNodes {
50        added_node_ids: Vec<u32>,
51        total_nodes: u32,
52        started_processes: u32,
53    },
54}
55
56pub async fn send_request(socket_path: &Path, request: &ControlRequest) -> Result<ControlResponse> {
57    let mut stream = UnixStream::connect(socket_path).await?;
58    let request_bytes = serde_json::to_vec(request)?;
59    stream.write_all(&request_bytes).await?;
60    stream.shutdown().await?;
61
62    let mut response_bytes = Vec::new();
63    stream.read_to_end(&mut response_bytes).await?;
64    if response_bytes.is_empty() {
65        return Err(anyhow!(
66            "empty control response from {}",
67            socket_path.display()
68        ));
69    }
70
71    let response = serde_json::from_slice::<ControlResponse>(&response_bytes)?;
72    Ok(response)
73}