This commit is contained in:
hinto.janai 2024-06-12 16:16:09 -04:00
parent 865ff304c5
commit 81aad9641f
No known key found for this signature in database
GPG key ID: D47CE05FA175A499
7 changed files with 123 additions and 36 deletions

View file

@ -9,12 +9,12 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/rpc/monero-rpc-types
keywords = ["monero", "rpc", "types"] keywords = ["monero", "rpc", "types"]
[features] [features]
default = ["serde"] default = []
[dependencies] [dependencies]
monero-serai = { workspace = true } monero-serai = { workspace = true }
paste = { workspace = true } paste = { workspace = true }
serde = { workspace = true, optional = true } serde = { workspace = true }
strum = { workspace = true, features = ["derive"] } strum = { workspace = true, features = ["derive"] }
[dev-dependencies] [dev-dependencies]

View file

@ -0,0 +1,61 @@
Monero RPC types.
# What
This crate ports the types used in Monero's RPC interface, including:
- JSON types
- Binary (epee) types
- Mixed types
- Other commonly used RPC types
# Modules
This crate's types are split in the following manner:
1. This crate has 3 modules:
- The root module (`monero_rpc_types`)
- [`req`] (request types)
- [`resp`] (response types)
1. Miscellaneous types are found in the root module, e.g. [`Status`]
1. The `req` and `resp` modules perfectly mirror each-other, and are split into 3 modules:
- `json` (JSON types from the `/json_rpc` endpoint)
- `bin` (Binary types from the binary endpoints)
- `other` (Misc JSON types from other endpoints)
1. Each type in `req` has a corresponding type in `resp` and vice-versa with an identical name, e.g. [`req::json::GetBlockCount`] and [`resp::json::GetBlockCount`]
# Documentation
The documentation for types within [`req`] and [`resp`] are omitted,
as they can be found in [Monero's RPC documentation](https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#on_get_block_hash).
However, each type will document:
- The exact type definition location in `monerod`
- The Monero RPC documentation link
# Naming
The naming for types within [`req`] and [`resp`] follow the following scheme:
- Convert the endpoint or method name into `UpperCamelCase`
- Remove any suffix extension
For example:
| Endpoint/method | Crate location and name |
|-----------------|-------------------------|
| [`get_block_count`](https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#get_block_count) | [`req::json::GetBlockCount`] & [`resp::json::GetBlockCount`]
| [`/get_blocks.bin`](https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#get_blockbin) | `req::bin::GetBlocks` & `resp::bin::GetBlocks`
| [`/get_height`](https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#get_height) | `req::other::GetHeight` & `resp::other::GetHeight`
TODO: fix doc links when types are ready.
# Mixed types
Note that some types within [`resp::other`] mix JSON & binary, i.e.,
the message overall is JSON, however some fields contain binary
values, for example:
```json
{
"string": "",
"float": 30.0,
"integer": 30,
"binary": /* serialized binary */
}
```
TODO: list the specific types.

View file

@ -32,7 +32,7 @@ define_monero_rpc_struct! {
// The struct generated and all fields are `pub`. // The struct generated and all fields are `pub`.
count: u64, count: u64,
status: crate::misc::Status, status: crate::Status,
untrusted: bool, untrusted: bool,
} }
} }

View file

@ -1,7 +1,4 @@
//! Monero RPC types. #![doc = include_str!("../README.md")]
//!
//! TODO.
//---------------------------------------------------------------------------------------------------- Lints //---------------------------------------------------------------------------------------------------- Lints
// Forbid lints. // Forbid lints.
// Our code, and code generated (e.g macros) cannot overrule these. // Our code, and code generated (e.g macros) cannot overrule these.
@ -98,11 +95,16 @@
)] )]
//---------------------------------------------------------------------------------------------------- Use //---------------------------------------------------------------------------------------------------- Use
mod bin; // Misc types.
mod data; mod status;
mod json; pub use status::Status;
// Internal modules.
mod macros; mod macros;
pub mod misc;
// Request/response JSON/binary/other types.
mod bin;
mod json;
mod other; mod other;
/// TODO /// TODO
@ -130,23 +132,23 @@ macro_rules! re_export_request_and_response_types {
)* )*
} }
) => { paste::paste! { ) => { paste::paste! {
/// TODO /// RPC request types.
pub mod req { pub mod req {
/// TODO /// JSON types from the [`/json_rpc`](https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#json-rpc-methods) endpoint.
pub mod json { pub mod json {
$( $(
pub use $crate::json::[<Request $json_type>] as $json_type; pub use $crate::json::[<Request $json_type>] as $json_type;
)* )*
} }
/// TODO /// Binary types from [binary](https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#get_blocksbin) endpoints.
pub mod bin { pub mod bin {
$( $(
pub use $crate::bin::[<Request $binary_type>] as $binary_type; pub use $crate::bin::[<Request $binary_type>] as $binary_type;
)* )*
} }
/// TODO /// JSON types from the [`other`](https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#other-daemon-rpc-calls) endpoints.
pub mod other { pub mod other {
$( $(
pub use $crate::other::[<Request $other_type>] as $other_type; pub use $crate::other::[<Request $other_type>] as $other_type;
@ -154,23 +156,23 @@ macro_rules! re_export_request_and_response_types {
} }
} }
/// TODO /// RPC response types.
pub mod resp { pub mod resp {
/// TODO /// JSON types from the [`/json_rpc`](https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#json-rpc-methods) endpoint.
pub mod json { pub mod json {
$( $(
pub use $crate::json::[<Response $json_type>] as $json_type; pub use $crate::json::[<Response $json_type>] as $json_type;
)* )*
} }
/// TODO /// Binary types from [binary](https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#get_blocksbin) endpoints.
pub mod bin { pub mod bin {
$( $(
pub use $crate::bin::[<Response $binary_type>] as $binary_type; pub use $crate::bin::[<Response $binary_type>] as $binary_type;
)* )*
} }
/// TODO /// JSON types from the [`other`](https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#other-daemon-rpc-calls) endpoints.
pub mod other { pub mod other {
$( $(
pub use $crate::other::[<Response $other_type>] as $other_type; pub use $crate::other::[<Response $other_type>] as $other_type;

View file

@ -43,7 +43,7 @@ macro_rules! define_monero_rpc_struct {
) => { paste::paste! { ) => { paste::paste! {
#[allow(dead_code)] #[allow(dead_code)]
#[allow(missing_docs)] #[allow(missing_docs)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(serde::Serialize, serde::Deserialize)]
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
$( #[$request_type_attr] )* $( #[$request_type_attr] )*
#[doc = concat!( #[doc = concat!(
@ -81,7 +81,7 @@ macro_rules! define_monero_rpc_struct {
#[allow(dead_code)] #[allow(dead_code)]
#[allow(missing_docs)] #[allow(missing_docs)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(serde::Serialize, serde::Deserialize)]
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
$( #[$response_type_attr] )* $( #[$response_type_attr] )*
#[doc = concat!( #[doc = concat!(

View file

@ -13,7 +13,7 @@ define_monero_rpc_struct! {
#[derive(Copy)] #[derive(Copy)]
Request {}, Request {},
Response { Response {
status: crate::misc::Status, status: crate::Status,
untrusted: bool, untrusted: bool,
} }
} }

View file

@ -1,19 +1,24 @@
//! TODO. //! RPC response status type.
//---------------------------------------------------------------------------------------------------- Import //---------------------------------------------------------------------------------------------------- Import
use serde::{Deserialize, Serialize};
use strum::{ use strum::{
AsRefStr, Display, EnumCount, EnumIs, EnumIter, EnumMessage, EnumProperty, EnumString, AsRefStr, Display, EnumCount, EnumIs, EnumIter, EnumMessage, EnumProperty, EnumString,
EnumTryAs, FromRepr, IntoStaticStr, VariantArray, VariantNames, EnumTryAs, FromRepr, IntoStaticStr, VariantArray, VariantNames,
}; };
//---------------------------------------------------------------------------------------------------- TODO //---------------------------------------------------------------------------------------------------- TODO
/// TODO /// RPC response status.
/// ///
/// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/message.cpp#L40-L44>. /// This type represents `monerod`'s frequently appearing string field, `status`.
/// ///
/// ## String formatting /// This field appears within RPC [JSON response](crate::resp::json) types.
///
/// Reference: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/message.cpp#L40-L44>.
///
/// ## Serialization and string formatting
/// ```rust /// ```rust
/// # use monero_rpc_types::misc::*; /// # use monero_rpc_types::*;
/// use serde_json::to_string; /// use serde_json::to_string;
/// use strum::AsRefStr; /// use strum::AsRefStr;
/// ///
@ -70,30 +75,49 @@ use strum::{
IntoStaticStr, IntoStaticStr,
VariantArray, VariantArray,
VariantNames, VariantNames,
Serialize,
Deserialize,
)] )]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Status { pub enum Status {
/// TODO /// Successful RPC response, everything is OK.
#[strum(serialize = "OK")] #[strum(serialize = "OK")]
#[cfg_attr(feature = "serde", serde(rename = "OK"))] #[serde(rename = "OK", alias = "Ok", alias = "ok")]
#[default] #[default]
Ok, Ok,
/// TODO #[serde(alias = "Retry", alias = "RETRY", alias = "retry")]
/// The RPC call failed and should be retried.
///
/// TODO: confirm this.
Retry, Retry,
/// TODO #[serde(alias = "failed", alias = "FAILED")]
/// The RPC call failed.
Failed, Failed,
/// TODO /// The RPC call contained bad input, unknown method, unknown params, etc.
#[strum(serialize = "Invalid request type")] #[strum(serialize = "Invalid request type")]
#[cfg_attr(feature = "serde", serde(rename = "Invalid request type"))] #[serde(
rename = "Invalid request type",
alias = "invalid request type",
alias = "INVALID REQUEST TYPE"
)]
BadRequest, BadRequest,
/// TODO /// The RPC call contained malformed JSON.
#[strum(serialize = "Malformed json")] #[strum(serialize = "Malformed json")]
#[cfg_attr(feature = "serde", serde(rename = "Malformed json"))] #[serde(
rename = "Malformed json",
alias = "malformed json",
alias = "MALFORMED JSON",
alias = "Malformed JSON",
alias = "malformed JSON"
)]
BadJson, BadJson,
// TODO:
// This may not be all the string `monerod` uses.
// We could use an `Other(String)` here just in case,
// otherwise deserialization would fail.
} }
//---------------------------------------------------------------------------------------------------- Tests //---------------------------------------------------------------------------------------------------- Tests