grin_api/owner_rpc.rs
1// Copyright 2021 The Grin Developers
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! JSON-RPC Stub generation for the Owner API
16
17use crate::owner::Owner;
18use crate::p2p::types::PeerInfoDisplay;
19use crate::p2p::PeerData;
20use crate::rest::Error;
21use crate::types::Status;
22use std::net::SocketAddr;
23
24/// Public definition used to generate Node jsonrpc api.
25/// * When running `grin` with defaults, the V2 api is available at
26/// `localhost:3413/v2/owner`
27/// * The endpoint only supports POST operations, with the json-rpc request as the body
28#[easy_jsonrpc_mw::rpc]
29pub trait OwnerRpc: Sync + Send {
30 /**
31 Networked version of [Owner::get_status](struct.Owner.html#method.get_status).
32
33 # Json rpc example
34
35 ```
36 # grin_api::doctest_helper_json_rpc_owner_assert_response!(
37 # r#"
38 {
39 "jsonrpc": "2.0",
40 "method": "get_status",
41 "params": [],
42 "id": 1
43 }
44 # "#
45 # ,
46 # r#"
47 {
48 "id": 1,
49 "jsonrpc": "2.0",
50 "result": {
51 "Ok": {
52 "chain": "main",
53 "protocol_version": "2",
54 "user_agent": "MW/Grin 2.x.x",
55 "connections": "8",
56 "tip": {
57 "height": 371553,
58 "last_block_pushed": "00001d1623db988d7ed10c5b6319360a52f20c89b4710474145806ba0e8455ec",
59 "prev_block_to_last": "0000029f51bacee81c49a27b4bc9c6c446e03183867c922890f90bb17108d89f",
60 "total_difficulty": 1127628411943045
61 },
62 "sync_status": "header_sync",
63 "sync_info": {
64 "current_height": 371553,
65 "highest_height": 0
66 }
67 }
68 }
69 }
70 # "#
71 # );
72 ```
73 */
74 fn get_status(&self) -> Result<Status, Error>;
75
76 /**
77 Networked version of [Owner::validate_chain](struct.Owner.html#method.validate_chain).
78
79 # Json rpc example
80
81 ```
82 # grin_api::doctest_helper_json_rpc_owner_assert_response!(
83 # r#"
84 {
85 "jsonrpc": "2.0",
86 "method": "validate_chain",
87 "params": ["false"],
88 "id": 1
89 }
90 # "#
91 # ,
92 # r#"
93 {
94 "id": 1,
95 "jsonrpc": "2.0",
96 "result": {
97 "Ok": null
98 }
99 }
100 # "#
101 # );
102 ```
103 */
104 fn validate_chain(&self, assume_valid_rangeproofs_kernels: bool) -> Result<(), Error>;
105
106 /**
107 Networked version of [Owner::compact_chain](struct.Owner.html#method.compact_chain).
108
109 # Json rpc example
110
111 ```
112 # grin_api::doctest_helper_json_rpc_owner_assert_response!(
113 # r#"
114 {
115 "jsonrpc": "2.0",
116 "method": "compact_chain",
117 "params": [],
118 "id": 1
119 }
120 # "#
121 # ,
122 # r#"
123 {
124 "id": 1,
125 "jsonrpc": "2.0",
126 "result": {
127 "Ok": null
128 }
129 }
130 # "#
131 # );
132 ```
133 */
134 fn compact_chain(&self) -> Result<(), Error>;
135
136 fn reset_chain_head(&self, hash: String) -> Result<(), Error>;
137
138 fn invalidate_header(&self, hash: String) -> Result<(), Error>;
139
140 /**
141 Networked version of [Owner::get_peers](struct.Owner.html#method.get_peers).
142
143 # Json rpc example
144
145 ```
146 # grin_api::doctest_helper_json_rpc_owner_assert_response!(
147 # r#"
148 {
149 "jsonrpc": "2.0",
150 "method": "get_peers",
151 "params": ["70.50.33.130:3414"],
152 "id": 1
153 }
154 # "#
155 # ,
156 # r#"
157 {
158 "id": 1,
159 "jsonrpc": "2.0",
160 "result": {
161 "Ok": [
162 {
163 "addr": "70.50.33.130:3414",
164 "ban_reason": "None",
165 "capabilities": {
166 "bits": 15
167 },
168 "flags": "Defunct",
169 "last_banned": 0,
170 "last_connected": 1570129317,
171 "user_agent": "MW/Grin 2.0.0"
172 }
173 ]
174 }
175 }
176 # "#
177 # );
178 ```
179 */
180 fn get_peers(&self, peer_addr: Option<SocketAddr>) -> Result<Vec<PeerData>, Error>;
181
182 /**
183 Networked version of [Owner::get_connected_peers](struct.Owner.html#method.get_connected_peers).
184
185 # Json rpc example
186
187 ```
188 # grin_api::doctest_helper_json_rpc_owner_assert_response!(
189 # r#"
190 {
191 "jsonrpc": "2.0",
192 "method": "get_connected_peers",
193 "params": [],
194 "id": 1
195 }
196 # "#
197 # ,
198 # r#"
199 {
200 "id": 1,
201 "jsonrpc": "2.0",
202 "result": {
203 "Ok": [
204 {
205 "addr": "35.176.195.242:3414",
206 "capabilities": {
207 "bits": 15
208 },
209 "direction": "Outbound",
210 "height": 374510,
211 "total_difficulty": 1133954621205750,
212 "user_agent": "MW/Grin 2.0.0",
213 "version": 1
214 },
215 {
216 "addr": "47.97.198.21:3414",
217 "capabilities": {
218 "bits": 15
219 },
220 "direction": "Outbound",
221 "height": 374510,
222 "total_difficulty": 1133954621205750,
223 "user_agent": "MW/Grin 2.0.0",
224 "version": 1
225 },
226 {
227 "addr": "148.251.16.13:3414",
228 "capabilities": {
229 "bits": 15
230 },
231 "direction": "Outbound",
232 "height": 374510,
233 "total_difficulty": 1133954621205750,
234 "user_agent": "MW/Grin 2.0.0",
235 "version": 1
236 },
237 {
238 "addr": "68.195.18.155:3414",
239 "capabilities": {
240 "bits": 15
241 },
242 "direction": "Outbound",
243 "height": 374510,
244 "total_difficulty": 1133954621205750,
245 "user_agent": "MW/Grin 2.0.0",
246 "version": 1
247 },
248 {
249 "addr": "52.53.221.15:3414",
250 "capabilities": {
251 "bits": 15
252 },
253 "direction": "Outbound",
254 "height": 0,
255 "total_difficulty": 1133954621205750,
256 "user_agent": "MW/Grin 2.0.0",
257 "version": 1
258 },
259 {
260 "addr": "109.74.202.16:3414",
261 "capabilities": {
262 "bits": 15
263 },
264 "direction": "Outbound",
265 "height": 374510,
266 "total_difficulty": 1133954621205750,
267 "user_agent": "MW/Grin 2.0.0",
268 "version": 1
269 },
270 {
271 "addr": "121.43.183.180:3414",
272 "capabilities": {
273 "bits": 15
274 },
275 "direction": "Outbound",
276 "height": 374510,
277 "total_difficulty": 1133954621205750,
278 "user_agent": "MW/Grin 2.0.0",
279 "version": 1
280 },
281 {
282 "addr": "35.157.247.209:23414",
283 "capabilities": {
284 "bits": 15
285 },
286 "direction": "Outbound",
287 "height": 374510,
288 "total_difficulty": 1133954621205750,
289 "user_agent": "MW/Grin 2.0.0",
290 "version": 1
291 }
292 ]
293 }
294 }
295 # "#
296 # );
297 ```
298 */
299 fn get_connected_peers(&self) -> Result<Vec<PeerInfoDisplay>, Error>;
300
301 /**
302 Networked version of [Owner::ban_peer](struct.Owner.html#method.ban_peer).
303
304 # Json rpc example
305
306 ```
307 # grin_api::doctest_helper_json_rpc_owner_assert_response!(
308 # r#"
309 {
310 "jsonrpc": "2.0",
311 "method": "ban_peer",
312 "params": ["70.50.33.130:3414"],
313 "id": 1
314 }
315 # "#
316 # ,
317 # r#"
318 {
319 "id": 1,
320 "jsonrpc": "2.0",
321 "result": {
322 "Ok": null
323 }
324 }
325 # "#
326 # );
327 ```
328 */
329 fn ban_peer(&self, peer_addr: SocketAddr) -> Result<(), Error>;
330
331 /**
332 Networked version of [Owner::unban_peer](struct.Owner.html#method.unban_peer).
333
334 # Json rpc example
335
336 ```
337 # grin_api::doctest_helper_json_rpc_owner_assert_response!(
338 # r#"
339 {
340 "jsonrpc": "2.0",
341 "method": "unban_peer",
342 "params": ["70.50.33.130:3414"],
343 "id": 1
344 }
345 # "#
346 # ,
347 # r#"
348 {
349 "id": 1,
350 "jsonrpc": "2.0",
351 "result": {
352 "Ok": null
353 }
354 }
355 # "#
356 # );
357 ```
358 */
359 fn unban_peer(&self, peer_addr: SocketAddr) -> Result<(), Error>;
360}
361
362impl OwnerRpc for Owner {
363 fn get_status(&self) -> Result<Status, Error> {
364 Owner::get_status(self)
365 }
366
367 fn validate_chain(&self, assume_valid_rangeproofs_kernels: bool) -> Result<(), Error> {
368 Owner::validate_chain(self, assume_valid_rangeproofs_kernels)
369 }
370
371 fn reset_chain_head(&self, hash: String) -> Result<(), Error> {
372 Owner::reset_chain_head(self, hash)
373 }
374
375 fn invalidate_header(&self, hash: String) -> Result<(), Error> {
376 Owner::invalidate_header(self, hash)
377 }
378
379 fn compact_chain(&self) -> Result<(), Error> {
380 Owner::compact_chain(self)
381 }
382
383 fn get_peers(&self, addr: Option<SocketAddr>) -> Result<Vec<PeerData>, Error> {
384 Owner::get_peers(self, addr)
385 }
386
387 fn get_connected_peers(&self) -> Result<Vec<PeerInfoDisplay>, Error> {
388 Owner::get_connected_peers(self)
389 }
390
391 fn ban_peer(&self, addr: SocketAddr) -> Result<(), Error> {
392 Owner::ban_peer(self, addr)
393 }
394
395 fn unban_peer(&self, addr: SocketAddr) -> Result<(), Error> {
396 Owner::unban_peer(self, addr)
397 }
398}
399
400#[doc(hidden)]
401#[macro_export]
402macro_rules! doctest_helper_json_rpc_owner_assert_response {
403 ($request:expr, $expected_response:expr) => {
404 // create temporary grin server, run jsonrpc request on node api, delete server, return
405 // json response.
406
407 {
408 /*use grin_servers::test_framework::framework::run_doctest;
409 use grin_util as util;
410 use serde_json;
411 use serde_json::Value;
412 use tempfile::tempdir;
413
414 let dir = tempdir().map_err(|e| format!("{:#?}", e)).unwrap();
415 let dir = dir
416 .path()
417 .to_str()
418 .ok_or("Failed to convert tmpdir path to string.".to_owned())
419 .unwrap();
420
421 let request_val: Value = serde_json::from_str($request).unwrap();
422 let expected_response: Value = serde_json::from_str($expected_response).unwrap();
423 let response = run_doctest(
424 request_val,
425 dir,
426 $use_token,
427 $blocks_to_mine,
428 $perform_tx,
429 $lock_tx,
430 $finalize_tx,
431 )
432 .unwrap()
433 .unwrap();
434 if response != expected_response {
435 panic!(
436 "(left != right) \nleft: {}\nright: {}",
437 serde_json::to_string_pretty(&response).unwrap(),
438 serde_json::to_string_pretty(&expected_response).unwrap()
439 );
440 }*/
441 }
442 };
443}