confium_tc/coordinator/
client.rs1use std::io;
22use std::net::TcpStream;
23
24use crate::coordinator::net::{ProtocolMessage, recv_message, send_message};
25
26pub struct SignerClient {
28 stream: TcpStream,
29}
30
31impl SignerClient {
32 pub fn connect(addr: &str) -> io::Result<Self> {
34 let stream = TcpStream::connect(addr)?;
35 Ok(Self { stream })
36 }
37
38 pub fn register(&mut self, signer_id: &str, quorum_id: &str) -> io::Result<()> {
40 send_message(
41 &mut self.stream,
42 &ProtocolMessage::Register {
43 signer_id: signer_id.into(),
44 quorum_id: quorum_id.into(),
45 },
46 )?;
47 let resp = recv_message(&mut self.stream)?;
48 match resp {
49 ProtocolMessage::Registered { signer_id: sid } if sid == signer_id => Ok(()),
50 _ => Err(io::Error::new(
51 io::ErrorKind::InvalidData,
52 "unexpected register response",
53 )),
54 }
55 }
56
57 pub fn create_session(
59 &mut self,
60 quorum_id: &str,
61 scheme: &str,
62 message: &[u8],
63 threshold: u32,
64 num_parties: u32,
65 ) -> io::Result<String> {
66 send_message(
67 &mut self.stream,
68 &ProtocolMessage::CreateSession {
69 quorum_id: quorum_id.into(),
70 scheme: scheme.into(),
71 message: message.to_vec(),
72 threshold,
73 num_parties,
74 },
75 )?;
76 let resp = recv_message(&mut self.stream)?;
77 match resp {
78 ProtocolMessage::SessionCreated { session_id } => Ok(session_id),
79 ProtocolMessage::Error { message } => {
80 Err(io::Error::other(format!("coordinator error: {message}")))
81 }
82 _ => Err(io::Error::new(
83 io::ErrorKind::InvalidData,
84 "unexpected response",
85 )),
86 }
87 }
88
89 pub fn submit_commitment(
91 &mut self,
92 session_id: &str,
93 signer_id: &str,
94 commitment_bytes: &[u8],
95 ) -> io::Result<()> {
96 send_message(
97 &mut self.stream,
98 &ProtocolMessage::Commitment {
99 session_id: session_id.into(),
100 signer_id: signer_id.into(),
101 bytes: commitment_bytes.to_vec(),
102 signature: vec![0u8; 64],
103 },
104 )?;
105 self.stream
107 .set_read_timeout(Some(std::time::Duration::from_secs(5)))?;
108 match recv_message(&mut self.stream) {
109 Ok(ProtocolMessage::Ack { .. }) => Ok(()),
110 Ok(ProtocolMessage::Error { message }) => {
111 Err(io::Error::other(format!("coordinator error: {message}")))
112 }
113 Ok(_) => Ok(()), Err(e) => Err(e),
115 }
116 }
117
118 pub fn submit_share(
121 &mut self,
122 session_id: &str,
123 signer_id: &str,
124 share_bytes: &[u8],
125 ) -> io::Result<Option<Vec<u8>>> {
126 send_message(
127 &mut self.stream,
128 &ProtocolMessage::Share {
129 session_id: session_id.into(),
130 signer_id: signer_id.into(),
131 bytes: share_bytes.to_vec(),
132 signature: vec![0u8; 64],
133 },
134 )?;
135
136 self.stream
139 .set_read_timeout(Some(std::time::Duration::from_secs(5)))?;
140
141 match recv_message(&mut self.stream) {
142 Ok(ProtocolMessage::Signature { bytes, .. }) => Ok(Some(bytes)),
143 Ok(ProtocolMessage::Ack { .. }) => Ok(None),
144 Ok(ProtocolMessage::Error { message }) => {
145 Err(io::Error::other(format!("coordinator error: {message}")))
146 }
147 Ok(_) => Ok(None),
148 Err(ref e)
149 if e.kind() == io::ErrorKind::WouldBlock || e.kind() == io::ErrorKind::TimedOut =>
150 {
151 Ok(None)
152 }
153 Err(e) => Err(e),
154 }
155 }
156
157 pub fn get_status(&mut self, session_id: &str) -> io::Result<String> {
159 send_message(
160 &mut self.stream,
161 &ProtocolMessage::GetStatus {
162 session_id: Some(session_id.into()),
163 },
164 )?;
165 let resp = recv_message(&mut self.stream)?;
166 match resp {
167 ProtocolMessage::Status { state, .. } => Ok(state),
168 _ => Err(io::Error::new(
169 io::ErrorKind::InvalidData,
170 "unexpected status response",
171 )),
172 }
173 }
174}