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