Skip to main content

interstice_cli/
node_client.rs

1use crate::data_directory::load_cli_identity;
2use interstice_core::{
3    IntersticeError, NetworkPacket,
4    interstice_abi::NodeSchema,
5    packet::{read_packet, write_packet},
6};
7use uuid::Uuid;
8
9pub struct HandshakeInfo {
10    pub node_id: String,
11    pub address: String,
12}
13
14pub async fn handshake_with_node(
15    address: &str,
16) -> Result<(tokio::net::TcpStream, HandshakeInfo), IntersticeError> {
17    let cli_identity = load_cli_identity()?;
18    let mut stream = tokio::net::TcpStream::connect(address)
19        .await
20        .map_err(|_| IntersticeError::Internal("Failed to connect to node".into()))?;
21    let packet = NetworkPacket::Handshake {
22        node_id: cli_identity.cli_id,
23        address: "127.0.0.1:12345".into(),
24        token: cli_identity.cli_token,
25    };
26    write_packet(&mut stream, &packet).await?;
27    let response = read_packet(&mut stream).await?;
28    match response {
29        NetworkPacket::Handshake {
30            node_id, address, ..
31        } => Ok((stream, HandshakeInfo { node_id, address })),
32        _ => Err(IntersticeError::ProtocolError(
33            "Expected handshake response".into(),
34        )),
35    }
36}
37
38pub async fn fetch_node_schema(
39    address: &str,
40    node_name: &str,
41) -> Result<(NodeSchema, HandshakeInfo), IntersticeError> {
42    let (mut stream, handshake) = handshake_with_node(address).await?;
43    let request_id = Uuid::new_v4().to_string();
44    let packet = NetworkPacket::SchemaRequest {
45        request_id: request_id.clone(),
46        node_name: node_name.to_string(),
47    };
48    write_packet(&mut stream, &packet).await?;
49    let response = read_packet(&mut stream).await?;
50    match response {
51        NetworkPacket::SchemaResponse {
52            request_id: response_id,
53            schema,
54        } => {
55            if response_id != request_id {
56                return Err(IntersticeError::ProtocolError(
57                    "Schema response id mismatch".into(),
58                ));
59            }
60            Ok((schema, handshake))
61        }
62        _ => Err(IntersticeError::ProtocolError(
63            "Expected schema response".into(),
64        )),
65    }
66}