mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-11-16 15:58:14 +00:00
rewrite interface fns
This commit is contained in:
parent
61ab466a73
commit
b8966761e3
12 changed files with 397 additions and 155 deletions
49
Cargo.lock
generated
49
Cargo.lock
generated
|
@ -114,14 +114,11 @@ checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf"
|
|||
dependencies = [
|
||||
"async-trait",
|
||||
"axum-core",
|
||||
"axum-macros",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
"itoa",
|
||||
"matchit",
|
||||
"memchr",
|
||||
|
@ -132,13 +129,10 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"serde_path_to_error",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper 1.0.1",
|
||||
"tokio",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -159,19 +153,6 @@ dependencies = [
|
|||
"sync_wrapper 0.1.2",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-macros"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00c055ee2d014ae5981ce1016374e8213682aa14d9bf40e48ab48b5f3ef20eaa"
|
||||
dependencies = [
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -402,7 +383,7 @@ version = "4.5.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
|
@ -830,6 +811,7 @@ dependencies = [
|
|||
"cuprate-epee-encoding",
|
||||
"cuprate-json-rpc",
|
||||
"cuprate-rpc-types",
|
||||
"paste",
|
||||
"serde",
|
||||
"tower",
|
||||
]
|
||||
|
@ -838,6 +820,7 @@ dependencies = [
|
|||
name = "cuprate-rpc-types"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"cuprate-epee-encoding",
|
||||
"cuprate-fixed-bytes",
|
||||
"monero-serai",
|
||||
|
@ -1270,12 +1253,6 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
|
@ -1387,12 +1364,6 @@ version = "1.9.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0e7a4dd27b9476dc40cb050d3632d3bba3a70ddbff012285f7f8559a1e7e545"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "1.3.1"
|
||||
|
@ -1405,7 +1376,6 @@ dependencies = [
|
|||
"http",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project-lite",
|
||||
"smallvec",
|
||||
|
@ -2478,18 +2448,6 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.8"
|
||||
|
@ -2864,7 +2822,6 @@ version = "0.1.40"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
||||
dependencies = [
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
|
|
|
@ -46,6 +46,7 @@ opt-level = 1
|
|||
opt-level = 3
|
||||
|
||||
[workspace.dependencies]
|
||||
axum = { version = "0.7.5", default-features = false }
|
||||
async-trait = { version = "0.1.74", default-features = false }
|
||||
bitflags = { version = "2.4.2", default-features = false }
|
||||
borsh = { version = "1.2.1", default-features = false }
|
||||
|
|
|
@ -16,8 +16,9 @@ cuprate-epee-encoding = { path = "../../net/epee-encoding" }
|
|||
cuprate-json-rpc = { path = "../json-rpc" }
|
||||
cuprate-rpc-types = { path = "../types" }
|
||||
|
||||
axum = { version = "0.7.5", features = ["macros"] }
|
||||
axum = { workspace = true, features = ["json"] }
|
||||
serde = { workspace = true }
|
||||
tower = { workspace = true }
|
||||
paste = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -7,77 +7,80 @@ use axum::{extract::State, routing::method_routing::get, Router};
|
|||
use tower::Service;
|
||||
|
||||
use crate::{
|
||||
error::Error, request::Request, response::Response, route, rpc_handler::RpcHandler, RpcState,
|
||||
error::Error,
|
||||
request::Request,
|
||||
response::Response,
|
||||
route::{self, bin},
|
||||
rpc_handler::RpcHandler,
|
||||
RpcState,
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Router
|
||||
/// TODO
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
#[rustfmt::skip]
|
||||
pub fn create_router<H: RpcHandler>() -> Router<H> {
|
||||
// List of `monerod` routes:
|
||||
// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.h#L97-L189>
|
||||
|
||||
let mut router = Router::new();
|
||||
let router = Router::new();
|
||||
|
||||
// JSON-RPC route.
|
||||
router = router.route("/json_rpc", get(route::json_rpc::<H>));
|
||||
// // JSON-RPC route.
|
||||
// router = router.route("/json_rpc", get(route::json_rpc::<H>));
|
||||
|
||||
// Other JSON routes.
|
||||
for other_route in [
|
||||
"/get_height",
|
||||
"/getheight",
|
||||
"/get_transactions",
|
||||
"/gettransactions",
|
||||
"/get_alt_blocks_hashes",
|
||||
"/is_key_image_spent",
|
||||
"/send_raw_transaction",
|
||||
"/sendrawtransaction",
|
||||
"/start_mining",
|
||||
"/stop_mining",
|
||||
"/mining_status",
|
||||
"/save_bc",
|
||||
"/get_peer_list",
|
||||
"/get_public_nodes",
|
||||
"/set_log_hash_rate",
|
||||
"/set_log_level",
|
||||
"/set_log_categories",
|
||||
"/get_transaction_pool",
|
||||
"/get_transaction_pool_hashes",
|
||||
"/get_transaction_pool_stats",
|
||||
"/set_bootstrap_daemon",
|
||||
"/stop_daemon",
|
||||
"/get_info",
|
||||
"/getinfo",
|
||||
"/get_net_stats",
|
||||
"/get_limit",
|
||||
"/set_limit",
|
||||
"/out_peers",
|
||||
"/in_peers",
|
||||
"/get_outs",
|
||||
"/update",
|
||||
"/pop_blocks",
|
||||
] {
|
||||
router = router.route(other_route, get(route::other::<H>));
|
||||
}
|
||||
// // Other JSON routes.
|
||||
// for other_route in [
|
||||
// "/get_height",
|
||||
// "/getheight",
|
||||
// "/get_transactions",
|
||||
// "/gettransactions",
|
||||
// "/get_alt_blocks_hashes",
|
||||
// "/is_key_image_spent",
|
||||
// "/send_raw_transaction",
|
||||
// "/sendrawtransaction",
|
||||
// "/start_mining",
|
||||
// "/stop_mining",
|
||||
// "/mining_status",
|
||||
// "/save_bc",
|
||||
// "/get_peer_list",
|
||||
// "/get_public_nodes",
|
||||
// "/set_log_hash_rate",
|
||||
// "/set_log_level",
|
||||
// "/set_log_categories",
|
||||
// "/get_transaction_pool",
|
||||
// "/get_transaction_pool_hashes",
|
||||
// "/get_transaction_pool_stats",
|
||||
// "/set_bootstrap_daemon",
|
||||
// "/stop_daemon",
|
||||
// "/get_info",
|
||||
// "/getinfo",
|
||||
// "/get_net_stats",
|
||||
// "/get_limit",
|
||||
// "/set_limit",
|
||||
// "/out_peers",
|
||||
// "/in_peers",
|
||||
// "/get_outs",
|
||||
// "/update",
|
||||
// "/pop_blocks",
|
||||
// ] {
|
||||
// router = router.route(other_route, get(route::other::<H>));
|
||||
// }
|
||||
|
||||
// Binary routes.
|
||||
for binary_route in [
|
||||
"/get_blocks.bin",
|
||||
"/getblocks.bin",
|
||||
"/get_blocks_by_height.bin",
|
||||
"/getblocks_by_height.bin",
|
||||
"/get_hashes.bin",
|
||||
"/gethashes.bin",
|
||||
"/get_o_indexes.bin",
|
||||
"/get_outs.bin",
|
||||
"/get_transaction_pool_hashes.bin",
|
||||
"/get_output_distribution.bin",
|
||||
] {
|
||||
router = router.route(binary_route, get(route::bin::<H>));
|
||||
}
|
||||
|
||||
// Unknown route.
|
||||
router = router.route("/*", get(route::unknown));
|
||||
|
||||
router
|
||||
.route("/get_blocks.bin", get(bin::get_blocks::<H>))
|
||||
.route("/getblocks.bin", get(bin::get_blocks::<H>))
|
||||
.route("/get_blocks_by_height.bin", get(bin::get_blocks_by_height::<H>))
|
||||
.route("/getblocks_by_height.bin", get(bin::get_blocks_by_height::<H>))
|
||||
.route("/get_hashes.bin", get(bin::get_hashes::<H>))
|
||||
.route("/gethashes.bin", get(bin::get_hashes::<H>))
|
||||
.route("/get_o_indexes.bin", get(bin::get_o_indexes::<H>))
|
||||
.route("/get_outs.bin", get(bin::get_outs::<H>))
|
||||
.route("/get_transaction_pool_hashes.bin", get(bin::get_transaction_pool_hashes::<H>))
|
||||
.route("/get_output_distribution.bin", get(bin::get_output_distribution::<H>))
|
||||
|
||||
// // Unknown route.
|
||||
// router = router.route("/*", get(route::unknown));
|
||||
|
||||
// router
|
||||
}
|
||||
|
|
97
rpc/interface/src/route/bin.rs
Normal file
97
rpc/interface/src/route/bin.rs
Normal file
|
@ -0,0 +1,97 @@
|
|||
//! TODO
|
||||
#![allow(clippy::unused_async)] // TODO: remove after impl
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Import
|
||||
use std::{borrow::Cow, future::Future, sync::Arc};
|
||||
|
||||
use axum::{body::Bytes, extract::State, http::StatusCode, response::IntoResponse, Json};
|
||||
use cuprate_json_rpc::{
|
||||
error::{ErrorCode, ErrorObject},
|
||||
Id,
|
||||
};
|
||||
use tower::{Service, ServiceExt};
|
||||
|
||||
use cuprate_epee_encoding::from_bytes;
|
||||
use cuprate_rpc_types::{
|
||||
bin::{
|
||||
BinRequest, BinResponse, GetBlocksByHeightRequest, GetBlocksByHeightResponse,
|
||||
GetBlocksRequest, GetBlocksResponse, GetHashesRequest, GetHashesResponse,
|
||||
GetOutputIndexesRequest, GetOutputIndexesResponse, GetOutsRequest, GetOutsResponse,
|
||||
GetTransactionPoolHashesRequest, GetTransactionPoolHashesResponse,
|
||||
},
|
||||
json::{
|
||||
GetOutputDistributionRequest, GetOutputDistributionResponse, JsonRpcRequest,
|
||||
JsonRpcResponse,
|
||||
},
|
||||
other::{OtherRequest, OtherResponse},
|
||||
RpcRequest,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
error::Error, request::Request, response::Response, rpc_handler::RpcHandler,
|
||||
rpc_state::RpcState,
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Routes
|
||||
/// TODO
|
||||
macro_rules! serialize_binary_request {
|
||||
($variant:ident, $request:ident) => {
|
||||
BinRequest::$variant(
|
||||
from_bytes(&mut $request).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?,
|
||||
)
|
||||
};
|
||||
($variant:ident, $request:ident $(=> $constructor:expr)?) => {
|
||||
BinRequest::$variant(())
|
||||
};
|
||||
}
|
||||
|
||||
/// TODO
|
||||
macro_rules! generate_binary_endpoints {
|
||||
($(
|
||||
$endpoint:ident => $variant:ident $(=> $constructor:expr)?
|
||||
),*) => { paste::paste! {
|
||||
$(
|
||||
/// TODO
|
||||
#[allow(unused_mut)]
|
||||
pub(crate) async fn $endpoint<H: RpcHandler>(
|
||||
State(handler): State<H>,
|
||||
mut request: Bytes,
|
||||
) -> Result<Bytes, StatusCode> {
|
||||
// Serialize into the request type.
|
||||
let request = serialize_binary_request!($variant, request $(=> $constructor)?);
|
||||
|
||||
// TODO: call handler
|
||||
let Response::Binary(response) = todo!() else {
|
||||
panic!("RPC handler did not return a binary response");
|
||||
};
|
||||
|
||||
// Assert the response from the inner handler is correct.
|
||||
let BinResponse::$variant(response) = response else {
|
||||
panic!("RPC handler returned incorrect response");
|
||||
};
|
||||
|
||||
// Serialize to bytes and respond.
|
||||
match cuprate_epee_encoding::to_bytes(response) {
|
||||
Ok(bytes) => Ok(bytes.freeze()),
|
||||
Err(e) => Err(StatusCode::INTERNAL_SERVER_ERROR),
|
||||
}
|
||||
}
|
||||
)*
|
||||
}};
|
||||
}
|
||||
|
||||
generate_binary_endpoints! {
|
||||
get_blocks => GetBlocks,
|
||||
get_blocks_by_height => GetBlocksByHeight,
|
||||
get_hashes => GetHashes,
|
||||
get_o_indexes => GetOutputIndexes,
|
||||
get_outs => GetOuts,
|
||||
get_transaction_pool_hashes => GetTransactionPoolHashes => (),
|
||||
get_output_distribution => GetOutputDistribution
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Tests
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
// use super::*;
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
//! TODO
|
||||
#![allow(clippy::unused_async)] // TODO: remove after impl
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Import
|
||||
use std::{borrow::Cow, future::Future, sync::Arc};
|
||||
|
@ -10,7 +11,12 @@ use cuprate_json_rpc::{
|
|||
};
|
||||
use tower::{Service, ServiceExt};
|
||||
|
||||
use cuprate_epee_encoding::from_bytes;
|
||||
use cuprate_rpc_types::{
|
||||
bin::{
|
||||
BinRequest, BinResponse, GetBlocksByHeightRequest, GetBlocksRequest, GetHashesRequest,
|
||||
GetOutputIndexesRequest, GetOutsRequest, GetTransactionPoolHashesRequest,
|
||||
},
|
||||
json::{JsonRpcRequest, JsonRpcResponse},
|
||||
other::{OtherRequest, OtherResponse},
|
||||
RpcRequest,
|
||||
|
@ -55,49 +61,6 @@ pub(crate) async fn json_rpc<H: RpcHandler>(
|
|||
Ok(Json(response))
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub(crate) async fn bin<H: RpcHandler>(
|
||||
State(handler): State<H>,
|
||||
request: Bytes, // TODO: BinRequest
|
||||
) -> Result<Vec<u8>, StatusCode> {
|
||||
// TODO
|
||||
// if handler.state().restricted() && request.is_restricted() {
|
||||
if handler.state().restricted() {
|
||||
return Err(StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
// TODO: call handler
|
||||
let Response::Binary(response) = todo!() else {
|
||||
panic!("RPC handler returned incorrect response");
|
||||
};
|
||||
|
||||
let binary: Vec<u8> = todo!(); // TODO: serialize response.
|
||||
|
||||
Ok(binary)
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub(crate) async fn other<H: RpcHandler>(
|
||||
State(handler): State<H>,
|
||||
Json(request): Json<OtherRequest>,
|
||||
) -> Result<Json<OtherResponse>, StatusCode> {
|
||||
if handler.state().restricted() && request.is_restricted() {
|
||||
todo!();
|
||||
}
|
||||
|
||||
// TODO: call handler
|
||||
let Response::Other(response) = todo!() else {
|
||||
panic!("RPC handler returned incorrect response");
|
||||
};
|
||||
|
||||
Ok(Json(response))
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub(crate) async fn unknown() -> StatusCode {
|
||||
StatusCode::NOT_FOUND
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Tests
|
||||
#[cfg(test)]
|
||||
mod test {
|
6
rpc/interface/src/route/mod.rs
Normal file
6
rpc/interface/src/route/mod.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
//! TODO
|
||||
|
||||
pub(crate) mod bin;
|
||||
mod json;
|
||||
pub(crate) mod other;
|
||||
mod unknown;
|
135
rpc/interface/src/route/other.rs
Normal file
135
rpc/interface/src/route/other.rs
Normal file
|
@ -0,0 +1,135 @@
|
|||
//! TODO
|
||||
#![allow(clippy::unused_async)] // TODO: remove after impl
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Import
|
||||
use std::{borrow::Cow, future::Future, sync::Arc};
|
||||
|
||||
use axum::{body::Bytes, extract::State, http::StatusCode, Json};
|
||||
use cuprate_json_rpc::{
|
||||
error::{ErrorCode, ErrorObject},
|
||||
Id,
|
||||
};
|
||||
use tower::{Service, ServiceExt};
|
||||
|
||||
use cuprate_epee_encoding::from_bytes;
|
||||
use cuprate_rpc_types::{
|
||||
bin::{
|
||||
BinRequest, BinResponse, GetBlocksByHeightRequest, GetBlocksRequest, GetHashesRequest,
|
||||
GetOutputIndexesRequest, GetOutsRequest, GetTransactionPoolHashesRequest,
|
||||
},
|
||||
json::{JsonRpcRequest, JsonRpcResponse},
|
||||
other::{OtherRequest, OtherResponse},
|
||||
RpcRequest,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
error::Error, request::Request, response::Response, rpc_handler::RpcHandler,
|
||||
rpc_state::RpcState,
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Routes
|
||||
/// TODO
|
||||
pub(crate) async fn json_rpc<H: RpcHandler>(
|
||||
State(handler): State<H>,
|
||||
Json(request): Json<cuprate_json_rpc::Request<JsonRpcRequest>>,
|
||||
) -> Result<Json<cuprate_json_rpc::Response<JsonRpcResponse>>, StatusCode> {
|
||||
// Return early if this RPC server is restricted and
|
||||
// the requested method is only for non-restricted RPC.
|
||||
if handler.state().restricted() && request.body.is_restricted() {
|
||||
let error_object = ErrorObject {
|
||||
code: ErrorCode::ServerError(-1 /* TODO */),
|
||||
message: Cow::Borrowed("Restricted. TODO"),
|
||||
data: None,
|
||||
};
|
||||
|
||||
// JSON-RPC 2.0 rule:
|
||||
// If there was an error in detecting the `Request`'s ID,
|
||||
// the `Response` must contain an `Id::Null`
|
||||
let id = request.id.unwrap_or(Id::Null);
|
||||
|
||||
let response = cuprate_json_rpc::Response::err(id, error_object);
|
||||
|
||||
// TODO
|
||||
return Ok(Json(response));
|
||||
}
|
||||
|
||||
// TODO: call handler
|
||||
let Response::JsonRpc(response) = todo!() else {
|
||||
panic!("RPC handler returned incorrect response");
|
||||
};
|
||||
|
||||
Ok(Json(response))
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub(crate) async fn binary<H: RpcHandler>(
|
||||
State(handler): State<H>,
|
||||
endpoint: &'static str,
|
||||
mut request: Bytes, // TODO: BinRequest
|
||||
) -> Result<BinResponse, StatusCode> {
|
||||
let error = |_| StatusCode::INTERNAL_SERVER_ERROR;
|
||||
|
||||
let request = match endpoint {
|
||||
"/get_blocks.bin" | "/getblocks.bin" => {
|
||||
BinRequest::GetBlocks(from_bytes(&mut request).map_err(error)?)
|
||||
}
|
||||
"/get_blocks_by_height.bin" | "/getblocks_by_height.bin" => {
|
||||
BinRequest::GetBlocksByHeight(from_bytes(&mut request).map_err(error)?)
|
||||
}
|
||||
"/get_hashes.bin" | "/gethashes.bin" => {
|
||||
BinRequest::GetHashes(from_bytes(&mut request).map_err(error)?)
|
||||
}
|
||||
"/get_o_indexes.bin" => {
|
||||
BinRequest::GetOutputIndexes(from_bytes(&mut request).map_err(error)?)
|
||||
}
|
||||
"/get_outs.bin" => BinRequest::GetOuts(from_bytes(&mut request).map_err(error)?),
|
||||
"/get_transaction_pool_hashes.bin" => BinRequest::GetTransactionPoolHashes(()),
|
||||
"/get_output_distribution.bin" => {
|
||||
BinRequest::GetOutputDistribution(from_bytes(&mut request).map_err(error)?)
|
||||
}
|
||||
|
||||
// INVARIANT:
|
||||
// The `create_router` function only passes the above endpoints.
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
// TODO
|
||||
if handler.state().restricted() && request.is_restricted() {
|
||||
return Err(StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
// TODO: call handler
|
||||
let Response::Binary(response) = todo!() else {
|
||||
panic!("RPC handler returned incorrect response");
|
||||
};
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub(crate) async fn other<H: RpcHandler>(
|
||||
State(handler): State<H>,
|
||||
Json(request): Json<OtherRequest>,
|
||||
) -> Result<Json<OtherResponse>, StatusCode> {
|
||||
if handler.state().restricted() && request.is_restricted() {
|
||||
todo!();
|
||||
}
|
||||
|
||||
// TODO: call handler
|
||||
let Response::Other(response) = todo!() else {
|
||||
panic!("RPC handler returned incorrect response");
|
||||
};
|
||||
|
||||
Ok(Json(response))
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub(crate) async fn unknown() -> StatusCode {
|
||||
StatusCode::NOT_FOUND
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Tests
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
// use super::*;
|
||||
}
|
40
rpc/interface/src/route/unknown.rs
Normal file
40
rpc/interface/src/route/unknown.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
//! TODO
|
||||
#![allow(clippy::unused_async)] // TODO: remove after impl
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Import
|
||||
use std::{borrow::Cow, future::Future, sync::Arc};
|
||||
|
||||
use axum::{body::Bytes, extract::State, http::StatusCode, Json};
|
||||
use cuprate_json_rpc::{
|
||||
error::{ErrorCode, ErrorObject},
|
||||
Id,
|
||||
};
|
||||
use tower::{Service, ServiceExt};
|
||||
|
||||
use cuprate_epee_encoding::from_bytes;
|
||||
use cuprate_rpc_types::{
|
||||
bin::{
|
||||
BinRequest, BinResponse, GetBlocksByHeightRequest, GetBlocksRequest, GetHashesRequest,
|
||||
GetOutputIndexesRequest, GetOutsRequest, GetTransactionPoolHashesRequest,
|
||||
},
|
||||
json::{JsonRpcRequest, JsonRpcResponse},
|
||||
other::{OtherRequest, OtherResponse},
|
||||
RpcRequest,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
error::Error, request::Request, response::Response, rpc_handler::RpcHandler,
|
||||
rpc_state::RpcState,
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Routes
|
||||
/// TODO
|
||||
pub(crate) async fn unknown() -> StatusCode {
|
||||
StatusCode::NOT_FOUND
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Tests
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
// use super::*;
|
||||
}
|
|
@ -9,7 +9,7 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/rpc/types"
|
|||
keywords = ["cuprate", "rpc", "types", "monero"]
|
||||
|
||||
[features]
|
||||
default = ["serde", "epee"]
|
||||
default = ["serde", "epee", "axum"]
|
||||
serde = ["dep:serde", "cuprate-fixed-bytes/serde"]
|
||||
epee = ["dep:cuprate-epee-encoding"]
|
||||
|
||||
|
@ -17,6 +17,7 @@ epee = ["dep:cuprate-epee-encoding"]
|
|||
cuprate-epee-encoding = { path = "../../net/epee-encoding", optional = true }
|
||||
cuprate-fixed-bytes = { path = "../../net/fixed-bytes" }
|
||||
|
||||
axum = { workspace = true, optional = true }
|
||||
monero-serai = { workspace = true }
|
||||
paste = { workspace = true }
|
||||
serde = { workspace = true, optional = true }
|
||||
|
|
|
@ -5,6 +5,15 @@
|
|||
//---------------------------------------------------------------------------------------------------- Import
|
||||
use cuprate_fixed_bytes::ByteArrayVec;
|
||||
|
||||
#[cfg(feature = "axum")]
|
||||
use axum::{
|
||||
async_trait,
|
||||
body::{Body, Bytes},
|
||||
extract::{FromRequest, Request},
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -31,13 +40,13 @@ define_request_and_response! {
|
|||
core_rpc_server_commands_defs.h => 162..=262,
|
||||
GetBlocks,
|
||||
Request {
|
||||
requested_info: u8 = default_zero(), "default_zero",
|
||||
requested_info: u8 = default_zero::<u8>(), "default_zero",
|
||||
// FIXME: This is a `std::list` in `monerod` because...?
|
||||
block_ids: ByteArrayVec<32>,
|
||||
start_height: u64,
|
||||
prune: bool,
|
||||
no_miner_tx: bool = default_false(), "default_false",
|
||||
pool_info_since: u64 = default_zero(), "default_zero",
|
||||
pool_info_since: u64 = default_zero::<u64>(), "default_zero",
|
||||
},
|
||||
// TODO: this has custom epee (de)serialization.
|
||||
// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server_commands_defs.h#L242-L259>
|
||||
|
@ -150,6 +159,7 @@ pub enum BinRequest {
|
|||
GetOutputIndexes(GetOutputIndexesRequest),
|
||||
GetOuts(GetOutsRequest),
|
||||
GetTransactionPoolHashes(GetTransactionPoolHashesRequest),
|
||||
GetOutputDistribution(crate::json::GetOutputDistributionRequest),
|
||||
}
|
||||
|
||||
impl RpcRequest for BinRequest {
|
||||
|
@ -162,7 +172,8 @@ impl RpcRequest for BinRequest {
|
|||
| Self::GetHashes(_)
|
||||
| Self::GetOutputIndexes(_)
|
||||
| Self::GetOuts(_)
|
||||
| Self::GetTransactionPoolHashes(()) => false,
|
||||
| Self::GetTransactionPoolHashes(())
|
||||
| Self::GetOutputDistribution(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,6 +190,33 @@ pub enum BinResponse {
|
|||
GetOutputIndexes(GetOutputIndexesResponse),
|
||||
GetOuts(GetOutsResponse),
|
||||
GetTransactionPoolHashes(GetTransactionPoolHashesResponse),
|
||||
GetOutputDistribution(crate::json::GetOutputDistributionResponse),
|
||||
}
|
||||
|
||||
#[cfg(feature = "axum")]
|
||||
#[cfg(feature = "epee")]
|
||||
impl axum::response::IntoResponse for BinResponse {
|
||||
fn into_response(self) -> axum::response::Response {
|
||||
use cuprate_epee_encoding::to_bytes;
|
||||
|
||||
let mut bytes = axum::body::Bytes::new();
|
||||
let writer = &mut bytes;
|
||||
|
||||
let result = match self {
|
||||
Self::GetBlocks(s) => to_bytes(s),
|
||||
Self::GetBlocksByHeight(s) => to_bytes(s),
|
||||
Self::GetHashes(s) => to_bytes(s),
|
||||
Self::GetOutputIndexes(s) => to_bytes(s),
|
||||
Self::GetOuts(s) => to_bytes(s),
|
||||
Self::GetTransactionPoolHashes(s) => to_bytes(s),
|
||||
Self::GetOutputDistribution(s) => to_bytes(s),
|
||||
};
|
||||
|
||||
match result {
|
||||
Ok(bytes) => bytes.into_response(),
|
||||
Err(e) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Tests
|
||||
|
|
|
@ -483,9 +483,9 @@ define_request_and_response! {
|
|||
version: u32,
|
||||
release: bool,
|
||||
#[serde(skip_serializing_if = "is_zero")]
|
||||
current_height: u64 = default_zero(), "default_zero",
|
||||
current_height: u64 = default_zero::<u64>(), "default_zero",
|
||||
#[serde(skip_serializing_if = "is_zero")]
|
||||
target_height: u64 = default_zero(), "default_zero",
|
||||
target_height: u64 = default_zero::<u64>(), "default_zero",
|
||||
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||
hard_forks: Vec<HardforkEntry> = default_vec(), "default_vec",
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue