snap_coin/api/
requests.rs1use std::net::SocketAddr;
2
3use serde::{Deserialize, Serialize};
4use thiserror::Error;
5use tokio::{io::AsyncReadExt, net::TcpStream};
6
7use crate::{
8 core::{
9 block::Block,
10 blockchain::BlockchainError,
11 transaction::{Transaction, TransactionId, TransactionOutput},
12 },
13 crypto::{Hash, keys::Public},
14};
15
16#[derive(Error, Debug, Serialize, Deserialize)]
17pub enum RequestResponseError {
18 #[error("Failed to deserialize message")]
19 DecodingFailed,
20
21 #[error("Failed to serialize message")]
22 EncodingFailed,
23
24 #[error("Malformed data error")]
25 MalformedData,
26
27 #[error("Stream error")]
28 Stream,
29
30 #[error("Request returned invalid response")]
31 IncorrectResponse,
32}
33
34#[derive(Serialize, Deserialize)]
35pub enum Request {
36 Height,
37 Block { block_hash: Hash },
38 Difficulty,
39 BlockHash { height: u64 },
40 BlockHeight { hash: Hash },
41 Transaction { transaction_id: TransactionId },
42 TransactionsOfAddress { address: Public },
43 AvailableUTXOs { address: Public },
44 Balance { address: Public },
45 Reward,
46 Peers,
47 Mempool,
48 NewBlock { new_block: Block },
49 NewTransaction { new_transaction: Transaction },
50}
51
52impl Request {
53 pub fn encode(self) -> Result<Vec<u8>, RequestResponseError> {
55 let request_string =
56 serde_json::to_string(&self).map_err(|_| RequestResponseError::EncodingFailed)?;
57 let request_bytes = request_string.as_bytes();
58 let request_length = request_bytes.len();
59
60 if request_length > u16::MAX as usize {
61 return Err(RequestResponseError::MalformedData);
62 }
63
64 let mut buf = vec![0u8; request_length + 2];
65 buf[0..2].copy_from_slice(&(request_length as u16).to_be_bytes());
66 buf[2..].copy_from_slice(request_bytes);
67
68 Ok(buf)
69 }
70
71 pub async fn decode_from_stream(
73 stream: &mut TcpStream,
74 ) -> Result<Self, RequestResponseError> {
75 let mut size_buf = [0u8; 2];
76 stream
77 .read_exact(&mut size_buf)
78 .await
79 .map_err(|_| RequestResponseError::Stream)?;
80
81 let request_size = u16::from_be_bytes(size_buf) as usize;
82 let mut request_buf = vec![0u8; request_size];
83
84 stream
85 .read_exact(&mut request_buf)
86 .await
87 .map_err(|_| RequestResponseError::Stream)?;
88
89 let request: Request = serde_json::from_slice(&request_buf)
90 .map_err(|_| RequestResponseError::DecodingFailed)?;
91
92 Ok(request)
93 }
94}
95
96#[derive(Serialize, Deserialize)]
97pub enum Response {
98 Height {
99 height: u64,
100 },
101 Block {
102 block: Option<Block>,
103 },
104 Difficulty {
105 transaction_difficulty: [u8; 32],
106 block_difficulty: [u8; 32],
107 },
108 BlockHash {
109 hash: Option<Hash>,
110 },
111 BlockHeight {
112 height: Option<usize>,
113 },
114 Transaction {
115 transaction: Option<Transaction>,
116 },
117 TransactionsOfAddress {
118 transactions: Vec<TransactionId>,
119 },
120 AvailableUTXOs {
121 available_inputs: Vec<(TransactionId, TransactionOutput, usize)>,
122 },
123 Balance {
124 balance: u64,
125 },
126 Reward {
127 reward: u64,
128 },
129 Peers {
130 peers: Vec<SocketAddr>,
131 },
132 Mempool {
133 mempool: Vec<Transaction>,
134 },
135 NewBlock {
136 status: Result<(), BlockchainError>,
137 },
138 NewTransaction {
139 status: Result<(), BlockchainError>,
140 },
141}
142
143impl Response {
144 pub fn encode(self) -> Result<Vec<u8>, RequestResponseError> {
146 let response_string =
147 serde_json::to_string(&self).map_err(|_| RequestResponseError::EncodingFailed)?;
148 let response_bytes = response_string.as_bytes();
149 let response_length = response_bytes.len();
150
151 if response_length > u16::MAX as usize {
152 return Err(RequestResponseError::MalformedData);
153 }
154
155 let mut buf = vec![0u8; response_length + 2];
156 buf[0..2].copy_from_slice(&(response_length as u16).to_be_bytes());
157 buf[2..].copy_from_slice(response_bytes);
158
159 Ok(buf)
160 }
161
162 pub async fn decode_from_stream(stream: &mut TcpStream) -> Result<Self, RequestResponseError> {
164 let mut size_buf = [0u8; 2];
165 stream
166 .read_exact(&mut size_buf)
167 .await
168 .map_err(|_| RequestResponseError::Stream)?;
169
170 let response_size = u16::from_be_bytes(size_buf) as usize;
171 let mut response_buf = vec![0u8; response_size];
172
173 stream
174 .read_exact(&mut response_buf)
175 .await
176 .map_err(|_| RequestResponseError::Stream)?;
177
178 let response: Response = serde_json::from_slice(&response_buf)
179 .map_err(|_| RequestResponseError::DecodingFailed)?;
180
181 Ok(response)
182 }
183}