mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-11-16 15:58:14 +00:00
test-utils: add crate::rpc::data
module (#231)
Some checks failed
CI / ci (macos-latest, stable, bash) (push) Has been cancelled
Audit / audit (push) Has been cancelled
CI / fmt (push) Has been cancelled
CI / typo (push) Has been cancelled
Deny / audit (push) Has been cancelled
Doc / build (push) Has been cancelled
CI / ci (ubuntu-latest, stable, bash) (push) Has been cancelled
CI / ci (windows-latest, stable-x86_64-pc-windows-gnu, msys2 {0}) (push) Has been cancelled
Doc / deploy (push) Has been cancelled
Some checks failed
CI / ci (macos-latest, stable, bash) (push) Has been cancelled
Audit / audit (push) Has been cancelled
CI / fmt (push) Has been cancelled
CI / typo (push) Has been cancelled
Deny / audit (push) Has been cancelled
Doc / build (push) Has been cancelled
CI / ci (ubuntu-latest, stable, bash) (push) Has been cancelled
CI / ci (windows-latest, stable-x86_64-pc-windows-gnu, msys2 {0}) (push) Has been cancelled
Doc / deploy (push) Has been cancelled
* test-utils: add `crate::rpc::types` module * test-utils: conditional json doc-tests * json: add test data, fix macro doc tests * json: add all data * other: add all data * bin: add skeleton * docs * move type to correct file * rpc: `client/{client,constants}.rs` -> `client.rs` * lib.rs: remove `clippy::module_inception`
This commit is contained in:
parent
0a88ea13fc
commit
aa718e224f
13 changed files with 2400 additions and 49 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -785,6 +785,7 @@ dependencies = [
|
||||||
"hex",
|
"hex",
|
||||||
"hex-literal",
|
"hex-literal",
|
||||||
"monero-serai",
|
"monero-serai",
|
||||||
|
"paste",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|
|
@ -22,7 +22,7 @@ serde = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
bytes = { workspace = true, features = ["std"] }
|
bytes = { workspace = true, features = ["std"] }
|
||||||
tempfile = { workspace = true }
|
tempfile = { workspace = true }
|
||||||
|
paste = { workspace = true }
|
||||||
borsh = { workspace = true, features = ["derive"]}
|
borsh = { workspace = true, features = ["derive"]}
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -7,3 +7,4 @@ It currently contains:
|
||||||
- Code to spawn monerod instances and a testing network zone
|
- Code to spawn monerod instances and a testing network zone
|
||||||
- Real raw and typed Monero data, e.g. `Block, Transaction`
|
- Real raw and typed Monero data, e.g. `Block, Transaction`
|
||||||
- An RPC client to generate types from `cuprate_types`
|
- An RPC client to generate types from `cuprate_types`
|
||||||
|
- Raw RPC request/response strings and binary data
|
|
@ -292,7 +292,7 @@ mod tests {
|
||||||
|
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
use crate::rpc::HttpRpcClient;
|
use crate::rpc::client::HttpRpcClient;
|
||||||
|
|
||||||
/// Assert the defined blocks are the same compared to ones received from a local RPC call.
|
/// Assert the defined blocks are the same compared to ones received from a local RPC call.
|
||||||
#[ignore] // FIXME: doesn't work in CI, we need a real unrestricted node
|
#[ignore] // FIXME: doesn't work in CI, we need a real unrestricted node
|
||||||
|
|
|
@ -12,7 +12,9 @@ use monero_serai::{
|
||||||
|
|
||||||
use cuprate_types::{VerifiedBlockInformation, VerifiedTransactionInformation};
|
use cuprate_types::{VerifiedBlockInformation, VerifiedTransactionInformation};
|
||||||
|
|
||||||
use crate::rpc::constants::LOCALHOST_RPC_URL;
|
//---------------------------------------------------------------------------------------------------- Constants
|
||||||
|
/// The default URL used for Monero RPC connections.
|
||||||
|
pub const LOCALHOST_RPC_URL: &str = "http://127.0.0.1:18081";
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- HttpRpcClient
|
//---------------------------------------------------------------------------------------------------- HttpRpcClient
|
||||||
/// An HTTP RPC client for Monero.
|
/// An HTTP RPC client for Monero.
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
//! RPC-related Constants.
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Use
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Constants
|
|
||||||
/// The default URL used for Monero RPC connections.
|
|
||||||
pub const LOCALHOST_RPC_URL: &str = "http://127.0.0.1:18081";
|
|
55
test-utils/src/rpc/data/bin.rs
Normal file
55
test-utils/src/rpc/data/bin.rs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
//! Binary data from [`.bin` endpoints](https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#get_blocksbin).
|
||||||
|
//!
|
||||||
|
//! TODO: Not implemented yet.
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
|
use crate::rpc::data::macros::define_request_and_response;
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------- TODO
|
||||||
|
define_request_and_response! {
|
||||||
|
get_blocksbin,
|
||||||
|
GET_BLOCKS: &[u8],
|
||||||
|
Request = &[];
|
||||||
|
Response = &[];
|
||||||
|
}
|
||||||
|
|
||||||
|
define_request_and_response! {
|
||||||
|
get_blocks_by_heightbin,
|
||||||
|
GET_BLOCKS_BY_HEIGHT: &[u8],
|
||||||
|
Request = &[];
|
||||||
|
Response = &[];
|
||||||
|
}
|
||||||
|
|
||||||
|
define_request_and_response! {
|
||||||
|
get_hashesbin,
|
||||||
|
GET_HASHES: &[u8],
|
||||||
|
Request = &[];
|
||||||
|
Response = &[];
|
||||||
|
}
|
||||||
|
|
||||||
|
define_request_and_response! {
|
||||||
|
get_o_indexesbin,
|
||||||
|
GET_O_INDEXES: &[u8],
|
||||||
|
Request = &[];
|
||||||
|
Response = &[];
|
||||||
|
}
|
||||||
|
|
||||||
|
define_request_and_response! {
|
||||||
|
get_outsbin,
|
||||||
|
GET_OUTS: &[u8],
|
||||||
|
Request = &[];
|
||||||
|
Response = &[];
|
||||||
|
}
|
||||||
|
|
||||||
|
define_request_and_response! {
|
||||||
|
get_transaction_pool_hashesbin,
|
||||||
|
GET_TRANSACTION_POOL_HASHES: &[u8],
|
||||||
|
Request = &[];
|
||||||
|
Response = &[];
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------- Tests
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
// use super::*;
|
||||||
|
}
|
1292
test-utils/src/rpc/data/json.rs
Normal file
1292
test-utils/src/rpc/data/json.rs
Normal file
File diff suppressed because it is too large
Load diff
168
test-utils/src/rpc/data/macros.rs
Normal file
168
test-utils/src/rpc/data/macros.rs
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
//! Macros.
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------- define_request_and_response
|
||||||
|
/// A template for generating the RPC request and response `const` data.
|
||||||
|
///
|
||||||
|
/// See the [`crate::json`] module for example usage.
|
||||||
|
///
|
||||||
|
/// # Macro internals
|
||||||
|
/// This macro uses:
|
||||||
|
/// - [`define_request_and_response_doc`]
|
||||||
|
/// - [`define_request_and_response_test`]
|
||||||
|
macro_rules! define_request_and_response {
|
||||||
|
(
|
||||||
|
// The markdown tag for Monero daemon RPC documentation. Not necessarily the endpoint.
|
||||||
|
//
|
||||||
|
// Adding `(json)` after this will trigger the macro to automatically
|
||||||
|
// add a `serde_json` test for the request/response data.
|
||||||
|
$monero_daemon_rpc_doc_link:ident $(($test:ident))?,
|
||||||
|
|
||||||
|
// The base name.
|
||||||
|
// Attributes added here will apply to _both_
|
||||||
|
// request and response types.
|
||||||
|
$( #[$attr:meta] )*
|
||||||
|
$name:ident: $type:ty,
|
||||||
|
|
||||||
|
// The request type (and any doc comments, derives, etc).
|
||||||
|
$( #[$request_attr:meta] )*
|
||||||
|
Request = $request:expr;
|
||||||
|
|
||||||
|
// The response type (and any doc comments, derives, etc).
|
||||||
|
$( #[$response_attr:meta] )*
|
||||||
|
Response = $response:expr;
|
||||||
|
) => { paste::paste! {
|
||||||
|
#[doc = $crate::rpc::data::macros::define_request_and_response_doc!(
|
||||||
|
"response" => [<$name:upper _RESPONSE>],
|
||||||
|
$monero_daemon_rpc_doc_link,
|
||||||
|
)]
|
||||||
|
///
|
||||||
|
$( #[$attr] )*
|
||||||
|
///
|
||||||
|
$( #[$request_attr] )*
|
||||||
|
///
|
||||||
|
$(
|
||||||
|
#[doc = $crate::rpc::data::macros::define_request_and_response_doc_test!([<$name:upper _REQUEST>], $test)]
|
||||||
|
)?
|
||||||
|
pub const [<$name:upper _REQUEST>]: $type = $request;
|
||||||
|
|
||||||
|
#[doc = $crate::rpc::data::macros::define_request_and_response_doc!(
|
||||||
|
"request" => [<$name:upper _REQUEST>],
|
||||||
|
$monero_daemon_rpc_doc_link,
|
||||||
|
)]
|
||||||
|
///
|
||||||
|
$( #[$attr] )*
|
||||||
|
///
|
||||||
|
$( #[$response_attr] )*
|
||||||
|
///
|
||||||
|
$(
|
||||||
|
#[doc = $crate::rpc::data::macros::define_request_and_response_doc_test!([<$name:upper _RESPONSE>], $test)]
|
||||||
|
)?
|
||||||
|
pub const [<$name:upper _RESPONSE>]: $type = $response;
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
pub(super) use define_request_and_response;
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------- define_request_and_response_doc
|
||||||
|
/// Generate documentation for the types generated
|
||||||
|
/// by the [`define_request_and_response`] macro.
|
||||||
|
///
|
||||||
|
/// See it for more info on inputs.
|
||||||
|
macro_rules! define_request_and_response_doc {
|
||||||
|
(
|
||||||
|
// This labels the last `[request]` or `[response]`
|
||||||
|
// hyperlink in documentation. Input is either:
|
||||||
|
// - "request"
|
||||||
|
// - "response"
|
||||||
|
//
|
||||||
|
// Remember this is linking to the _other_ type,
|
||||||
|
// so if defining a `Request` type, input should
|
||||||
|
// be "response".
|
||||||
|
$request_or_response:literal => $request_or_response_type:ident,
|
||||||
|
$monero_daemon_rpc_doc_link:ident,
|
||||||
|
) => {
|
||||||
|
concat!(
|
||||||
|
"",
|
||||||
|
"[Documentation](",
|
||||||
|
"https://www.getmonero.org/resources/developer-guides/daemon-rpc.html",
|
||||||
|
"#",
|
||||||
|
stringify!($monero_daemon_rpc_doc_link),
|
||||||
|
"), [",
|
||||||
|
$request_or_response,
|
||||||
|
"](",
|
||||||
|
stringify!($request_or_response_type),
|
||||||
|
")."
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
pub(super) use define_request_and_response_doc;
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------- define_request_and_response_test
|
||||||
|
/// Generate documentation for the types generated
|
||||||
|
/// by the [`define_request_and_response`] macro.
|
||||||
|
///
|
||||||
|
/// See it for more info on inputs.
|
||||||
|
macro_rules! define_request_and_response_doc_test {
|
||||||
|
// `/json_rpc` doc test.
|
||||||
|
(
|
||||||
|
// The ident of the `const` request/response.
|
||||||
|
$name:ident,
|
||||||
|
json_rpc
|
||||||
|
) => {
|
||||||
|
concat!(
|
||||||
|
"```rust\n",
|
||||||
|
"use cuprate_test_utils::rpc::data::json::*;\n",
|
||||||
|
"use serde_json::{to_value, Value};\n",
|
||||||
|
"\n",
|
||||||
|
"let value = serde_json::from_str::<Value>(&",
|
||||||
|
stringify!($name),
|
||||||
|
").unwrap();\n",
|
||||||
|
"let Value::Object(map) = value else {\n",
|
||||||
|
" panic!();\n",
|
||||||
|
"};\n",
|
||||||
|
"\n",
|
||||||
|
r#"assert_eq!(map.get("jsonrpc").unwrap(), "2.0");"#,
|
||||||
|
"\n",
|
||||||
|
r#"map.get("id").unwrap();"#,
|
||||||
|
"\n\n",
|
||||||
|
r#"if map.get("method").is_some() {"#,
|
||||||
|
"\n",
|
||||||
|
r#" return;"#,
|
||||||
|
"\n",
|
||||||
|
"}\n",
|
||||||
|
"\n",
|
||||||
|
r#"if map.get("result").is_none() {"#,
|
||||||
|
"\n",
|
||||||
|
r#" map.get("error").unwrap();"#,
|
||||||
|
"\n",
|
||||||
|
"}\n",
|
||||||
|
"\n",
|
||||||
|
"```\n",
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Other JSON endpoint doc test.
|
||||||
|
(
|
||||||
|
$name:ident,
|
||||||
|
other
|
||||||
|
) => {
|
||||||
|
concat!(
|
||||||
|
"```rust\n",
|
||||||
|
"use cuprate_test_utils::rpc::data::other::*;\n",
|
||||||
|
"use serde_json::{to_value, Value};\n",
|
||||||
|
"\n",
|
||||||
|
"let value = serde_json::from_str::<Value>(&",
|
||||||
|
stringify!($name),
|
||||||
|
");\n",
|
||||||
|
"```\n",
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
// No doc test.
|
||||||
|
(
|
||||||
|
$name:ident,
|
||||||
|
$test:ident,
|
||||||
|
) => {
|
||||||
|
""
|
||||||
|
};
|
||||||
|
}
|
||||||
|
pub(super) use define_request_and_response_doc_test;
|
18
test-utils/src/rpc/data/mod.rs
Normal file
18
test-utils/src/rpc/data/mod.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
//! Monero RPC data.
|
||||||
|
//!
|
||||||
|
//! This module contains real `monerod` RPC requests/responses
|
||||||
|
//! as `const` [`str`]s and byte arrays (binary).
|
||||||
|
//!
|
||||||
|
//! The strings include the JSON-RPC 2.0 portions of the JSON.
|
||||||
|
//! - Tests exist within this crate that ensure the JSON is valid
|
||||||
|
//! - Tests exist within Cuprate's `rpc/` crates that ensure these strings (de)serialize as valid types
|
||||||
|
//!
|
||||||
|
//! # Determinism
|
||||||
|
//! Note that although both request/response data is defined,
|
||||||
|
//! they aren't necessarily tied to each other, i.e. the request
|
||||||
|
//! will not deterministically lead to the response.
|
||||||
|
|
||||||
|
pub mod bin;
|
||||||
|
pub mod json;
|
||||||
|
mod macros;
|
||||||
|
pub mod other;
|
839
test-utils/src/rpc/data/other.rs
Normal file
839
test-utils/src/rpc/data/other.rs
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,25 +1,6 @@
|
||||||
//! Monero RPC client.
|
//! Monero RPC data & client.
|
||||||
//!
|
//!
|
||||||
//! This module is a client for Monero RPC that maps the types
|
//! This module has a `monerod` RPC [`client`] and some real request/response [`data`].
|
||||||
//! into the native types used by Cuprate found in `cuprate_types`.
|
|
||||||
//!
|
|
||||||
//! # Usage
|
|
||||||
//! ```rust,ignore
|
|
||||||
//! #[tokio::main]
|
|
||||||
//! async fn main() {
|
|
||||||
//! // Create RPC client.
|
|
||||||
//! let rpc = HttpRpcClient::new(None).await;
|
|
||||||
//!
|
|
||||||
//! // Collect 20 blocks.
|
|
||||||
//! let mut vec: Vec<VerifiedBlockInformation> = vec![];
|
|
||||||
//! for height in (3130269 - 20)..3130269 {
|
|
||||||
//! vec.push(rpc.get_verified_block_information(height).await);
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
mod client;
|
pub mod client;
|
||||||
pub use client::HttpRpcClient;
|
pub mod data;
|
||||||
|
|
||||||
mod constants;
|
|
||||||
pub use constants::LOCALHOST_RPC_URL;
|
|
||||||
|
|
|
@ -17,4 +17,5 @@ extend-ignore-identifiers-re = [
|
||||||
extend-exclude = [
|
extend-exclude = [
|
||||||
"/misc/gpg_keys/",
|
"/misc/gpg_keys/",
|
||||||
"cryptonight/",
|
"cryptonight/",
|
||||||
|
"/test-utils/src/rpc/data/json.rs",
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue