jsonrpc.rs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2023 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. //! JSON-RPC 2.0 primitives
  19. use std::fmt;
  20. use async_std::sync::Arc;
  21. use darkfi_serial::{serialize, Encodable};
  22. use rand::{rngs::OsRng, Rng};
  23. use serde::{Deserialize, Deserializer, Serialize, Serializer};
  24. use serde_json::{json, Value};
  25. use crate::system::{Subscriber, SubscriberPtr};
  26. /// JSON-RPC error codes.
  27. /// The error codes from and including -32768 to -32000 are reserved for pre-defined errors.
  28. #[derive(Debug, Clone)]
  29. pub enum ErrorCode {
  30. ParseError,
  31. InvalidRequest,
  32. MethodNotFound,
  33. InvalidParams,
  34. InternalError,
  35. ServerError(i64),
  36. InvalidId,
  37. }
  38. impl ErrorCode {
  39. pub fn code(&self) -> i64 {
  40. match *self {
  41. Self::ParseError => -32700,
  42. Self::InvalidRequest => -32600,
  43. Self::MethodNotFound => -32601,
  44. Self::InvalidParams => -32602,
  45. Self::InternalError => -32603,
  46. // -32000 to -32099
  47. Self::ServerError(c) => c,
  48. Self::InvalidId => -32001,
  49. }
  50. }
  51. pub fn desc(&self) -> String {
  52. let desc = match *self {
  53. Self::ParseError => "Parse error",
  54. Self::InvalidRequest => "Invalid request",
  55. Self::MethodNotFound => "Method not found",
  56. Self::InvalidParams => "Invalid params",
  57. Self::InternalError => "Internal error",
  58. Self::ServerError(_) => "",
  59. Self::InvalidId => "Request ID mismatch",
  60. };
  61. desc.to_string()
  62. }
  63. }
  64. /// Wrapping enum around the possible JSON-RPC object types.
  65. // ANCHOR: jsonresult
  66. #[derive(Clone, Debug, Serialize, Deserialize)]
  67. #[serde(untagged)]
  68. pub enum JsonResult {
  69. Response(JsonResponse),
  70. Error(JsonError),
  71. Notification(JsonNotification),
  72. Subscriber(JsonSubscriber),
  73. }
  74. // ANCHOR_END: jsonresult
  75. impl From<JsonResponse> for JsonResult {
  76. fn from(resp: JsonResponse) -> Self {
  77. Self::Response(resp)
  78. }
  79. }
  80. impl From<JsonError> for JsonResult {
  81. fn from(err: JsonError) -> Self {
  82. Self::Error(err)
  83. }
  84. }
  85. impl From<JsonNotification> for JsonResult {
  86. fn from(notif: JsonNotification) -> Self {
  87. Self::Notification(notif)
  88. }
  89. }
  90. impl From<JsonSubscriber> for JsonResult {
  91. fn from(sub: JsonSubscriber) -> Self {
  92. Self::Subscriber(sub)
  93. }
  94. }
  95. /// A JSON-RPC request object.
  96. // ANCHOR: jsonrequest
  97. #[derive(Clone, Debug, Serialize, Deserialize)]
  98. pub struct JsonRequest {
  99. /// JSON-RPC version
  100. pub jsonrpc: Value,
  101. /// Request ID
  102. pub id: Value,
  103. /// Request method
  104. pub method: Value,
  105. /// Request parameters
  106. pub params: Value,
  107. }
  108. // ANCHOR_END: jsonrequest
  109. impl JsonRequest {
  110. pub fn new(method: &str, parameters: Value) -> Self {
  111. Self {
  112. jsonrpc: json!("2.0"),
  113. id: json!(OsRng.gen::<u64>()),
  114. method: json!(method),
  115. params: parameters,
  116. }
  117. }
  118. }
  119. /// A JSON-RPC notification object.
  120. #[derive(Clone, Debug, Serialize, Deserialize)]
  121. pub struct JsonNotification {
  122. /// JSON-RPC version
  123. pub jsonrpc: Value,
  124. /// Notification method
  125. pub method: Value,
  126. /// Notification parameters
  127. pub params: Value,
  128. }
  129. impl JsonNotification {
  130. pub fn new(method: Value, params: Value) -> Self {
  131. Self { jsonrpc: json!("2.0"), method, params }
  132. }
  133. }
  134. /// A method specific JSON-RPC subscriber for notifications
  135. #[derive(Clone)]
  136. pub struct MethodSubscriber {
  137. /// Notification method
  138. pub method: Value,
  139. /// Notification subscriber
  140. pub subscriber: SubscriberPtr<JsonNotification>,
  141. }
  142. impl MethodSubscriber {
  143. pub fn new(method: Value) -> Self {
  144. let subscriber = Subscriber::new();
  145. Self { method, subscriber }
  146. }
  147. /// Auxiliary function to format provided message and notify the subscriber.
  148. pub async fn notify<T: Encodable>(&self, message: &T) {
  149. let params = json!([bs58::encode(&serialize(message)).into_string()]);
  150. let notif = JsonNotification::new(self.method.clone(), params);
  151. self.subscriber.notify(notif).await;
  152. }
  153. }
  154. impl fmt::Debug for MethodSubscriber {
  155. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  156. f.debug_struct("MethodSubscriber")
  157. .field("method", &self.method)
  158. .field("pointer", &Arc::as_ptr(&self.subscriber))
  159. .finish()
  160. }
  161. }
  162. /// A JSON-RPC subscriber for notifications
  163. #[derive(Clone, Debug)]
  164. pub struct JsonSubscriber {
  165. /// JSON-RPC version
  166. pub jsonrpc: Value,
  167. /// Method subscriber
  168. pub subscriber: MethodSubscriber,
  169. }
  170. impl JsonSubscriber {
  171. pub fn new(subscriber: MethodSubscriber) -> Self {
  172. Self { jsonrpc: json!("2.0"), subscriber }
  173. }
  174. }
  175. impl Serialize for JsonSubscriber {
  176. fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
  177. where
  178. S: Serializer,
  179. {
  180. unimplemented!();
  181. }
  182. }
  183. impl<'de> Deserialize<'de> for JsonSubscriber {
  184. fn deserialize<D>(_deserializer: D) -> Result<JsonSubscriber, D::Error>
  185. where
  186. D: Deserializer<'de>,
  187. {
  188. unimplemented!();
  189. }
  190. }
  191. /// A JSON-RPC response object.
  192. #[derive(Clone, Debug, Serialize, Deserialize)]
  193. pub struct JsonResponse {
  194. /// JSON-RPC version
  195. pub jsonrpc: Value,
  196. /// Request ID
  197. pub id: Value,
  198. /// Response result
  199. pub result: Value,
  200. }
  201. impl JsonResponse {
  202. pub fn new(result: Value, id: Value) -> Self {
  203. Self { jsonrpc: json!("2.0"), id, result }
  204. }
  205. }
  206. /// A JSON-RPC error object.
  207. #[derive(Clone, Debug, Serialize, Deserialize)]
  208. pub struct JsonError {
  209. /// JSON-RPC version
  210. pub jsonrpc: Value,
  211. /// Request ID
  212. pub id: Value,
  213. /// JSON-RPC error (code and message)
  214. pub error: JsonErrorVal,
  215. }
  216. /// A JSON-RPC error value (code and message)
  217. #[derive(Clone, Debug, Serialize, Deserialize)]
  218. pub struct JsonErrorVal {
  219. /// Error code
  220. pub code: Value,
  221. /// Error message
  222. pub message: Value,
  223. }
  224. impl JsonError {
  225. pub fn new(c: ErrorCode, m: Option<String>, id: Value) -> Self {
  226. let error = JsonErrorVal {
  227. code: json!(c.code()),
  228. message: if m.is_none() { json!(c.desc()) } else { json!(m.unwrap()) },
  229. };
  230. Self { jsonrpc: json!("2.0"), error, id }
  231. }
  232. }