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, page: u32 },
43 AvailableUTXOs { address: Public, page: u32 },
44 Balance { address: Public },
45 Reward,
46 Peers,
47 Mempool { page: u32 },
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 > u32::MAX as usize {
61 return Err(RequestResponseError::MalformedData);
62 }
63
64 let mut buf = vec![0u8; request_length + 4];
65 buf[0..4].copy_from_slice(&(request_length as u32).to_be_bytes());
66 buf[4..].copy_from_slice(request_bytes);
67
68 Ok(buf)
69 }
70
71 pub async fn decode_from_stream(stream: &mut TcpStream) -> Result<Self, RequestResponseError> {
73 let mut size_buf = [0u8; 4];
74 stream
75 .read_exact(&mut size_buf)
76 .await
77 .map_err(|_| RequestResponseError::Stream)?;
78
79 let request_size = u32::from_be_bytes(size_buf) as usize;
80 let mut request_buf = vec![0u8; request_size];
81
82 stream
83 .read_exact(&mut request_buf)
84 .await
85 .map_err(|_| RequestResponseError::Stream)?;
86
87 let request: Request = serde_json::from_slice(&request_buf)
88 .map_err(|_| RequestResponseError::DecodingFailed)?;
89
90 Ok(request)
91 }
92}
93
94#[derive(Serialize, Deserialize)]
95pub enum Response {
96 Height {
97 height: u64,
98 },
99 Block {
100 block: Option<Block>,
101 },
102 Difficulty {
103 transaction_difficulty: [u8; 32],
104 block_difficulty: [u8; 32],
105 },
106 BlockHash {
107 hash: Option<Hash>,
108 },
109 BlockHeight {
110 height: Option<usize>,
111 },
112 Transaction {
113 transaction: Option<Transaction>,
114 },
115 TransactionsOfAddress {
116 transactions: Vec<TransactionId>,
117 next_page: Option<u32>,
118 },
119 AvailableUTXOs {
120 available_inputs: Vec<(TransactionId, TransactionOutput, usize)>,
121 next_page: Option<u32>,
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 next_page: Option<u32>,
135 },
136 NewBlock {
137 status: Result<(), BlockchainError>,
138 },
139 NewTransaction {
140 status: Result<(), BlockchainError>,
141 },
142}
143
144impl Response {
145 pub fn encode(self) -> Result<Vec<u8>, RequestResponseError> {
147 let response_string =
148 serde_json::to_string(&self).map_err(|_| RequestResponseError::EncodingFailed)?;
149 let response_bytes = response_string.as_bytes();
150 let response_length = response_bytes.len();
151
152 if response_length > u16::MAX as usize {
153 return Err(RequestResponseError::MalformedData);
154 }
155
156 let mut buf = vec![0u8; response_length + 2];
157 buf[0..2].copy_from_slice(&(response_length as u16).to_be_bytes());
158 buf[2..].copy_from_slice(response_bytes);
159
160 Ok(buf)
161 }
162
163 pub async fn decode_from_stream(stream: &mut TcpStream) -> Result<Self, RequestResponseError> {
165 let mut size_buf = [0u8; 2];
166 stream
167 .read_exact(&mut size_buf)
168 .await
169 .map_err(|_| RequestResponseError::Stream)?;
170
171 let response_size = u16::from_be_bytes(size_buf) as usize;
172 let mut response_buf = vec![0u8; response_size];
173
174 stream
175 .read_exact(&mut response_buf)
176 .await
177 .map_err(|_| RequestResponseError::Stream)?;
178
179 let response: Response = serde_json::from_slice(&response_buf)
180 .map_err(|_| RequestResponseError::DecodingFailed)?;
181
182 Ok(response)
183 }
184}