Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crate restructuring #590

Merged
merged 28 commits into from
Dec 17, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
cb3e37d
Nuke V2
maciejhirsz Dec 5, 2021
09ceb90
fmt
maciejhirsz Dec 5, 2021
714ce5d
Formatting and imports
maciejhirsz Dec 9, 2021
4d79729
Merge branch 'master' of github.com:paritytech/jsonrpsee into mh-cleanup
maciejhirsz Dec 9, 2021
22dd3a7
Updated benches
maciejhirsz Dec 9, 2021
6bb0224
Fix doc comment link
maciejhirsz Dec 9, 2021
bc22ac2
Brace imports in ws-server
maciejhirsz Dec 9, 2021
392daa7
Reworking imports
maciejhirsz Dec 10, 2021
a9c37fa
Merge branch 'master' of github.com:paritytech/jsonrpsee into mh-cleanup
maciejhirsz Dec 10, 2021
57bdf5a
std first
maciejhirsz Dec 10, 2021
e24f12d
fmt
maciejhirsz Dec 10, 2021
e59732f
std on top
maciejhirsz Dec 10, 2021
4f32c88
Update to match changed line numbers
maciejhirsz Dec 10, 2021
3ec6e62
Merge branch 'master' of github.com:paritytech/jsonrpsee into mh-cleanup
maciejhirsz Dec 13, 2021
f2f5315
Rename jsonrpsee_utils -> jsonrpsee_core
maciejhirsz Dec 14, 2021
e29bdec
Migrating things types -> core
maciejhirsz Dec 14, 2021
faa0da1
RpcError -> ErrorResponse
maciejhirsz Dec 14, 2021
a9567f0
Merge types::client into core::client
maciejhirsz Dec 14, 2021
f914dca
Continued move types -> core
maciejhirsz Dec 15, 2021
6c15874
Removing features to make checks pass
maciejhirsz Dec 15, 2021
7ed2316
Move rpc_module tests to tests crate
maciejhirsz Dec 16, 2021
1d09ee4
Merge branch 'master' of github.com:paritytech/jsonrpsee into mh-cleanup
maciejhirsz Dec 16, 2021
dc4ab02
Fixed doc comment links
maciejhirsz Dec 16, 2021
394a3c2
Add futures-util dependency for client
maciejhirsz Dec 16, 2021
c38ec76
Remove dead code
maciejhirsz Dec 16, 2021
e93c2d9
fmt
maciejhirsz Dec 16, 2021
51eec24
Feature gate the Client trait
maciejhirsz Dec 17, 2021
9a88c70
Move `Client` traits to `client` module
maciejhirsz Dec 17, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ edition = "2018"
license = "MIT"

[dependencies]
anyhow = "1"
arrayvec = "0.7.1"
async-trait = "0.1"
beef = { version = "0.5.1", features = ["impl_serde"] }
thiserror = { version = "1", optional = true }
thiserror = "1"
futures-channel = { version = "0.3.14", default-features = false, optional = true }
futures-util = { version = "0.3.14", default-features = false, optional = true }
hyper = { version = "0.14.10", default-features = false, features = ["stream"], optional = true }
Expand All @@ -20,14 +21,14 @@ rustc-hash = { version = "1", optional = true }
rand = { version = "0.8", optional = true }
serde = { version = "1.0", default-features = false, features = ["derive"], optional = true }
serde_json = { version = "1", features = ["raw_value"], optional = true }
soketto = "0.7.1"
parking_lot = { version = "0.11", optional = true }
tokio = { version = "1.8", features = ["rt"], optional = true }

[features]
default = []
http-helpers = ["hyper", "futures-util", "jsonrpsee-types"]
server = [
"thiserror",
"futures-channel",
"futures-util",
"jsonrpsee-types",
Expand Down
14 changes: 7 additions & 7 deletions core/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,20 @@ use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use std::task;

use crate::error::{Error, SubscriptionClosedError};
use core::marker::PhantomData;
use futures_channel::{mpsc, oneshot};
use futures_util::{
future::FutureExt,
sink::SinkExt,
stream::{Stream, StreamExt},
};
use jsonrpsee_types::{error::SubscriptionClosedError, Error, SubscriptionId};
use futures_util::future::FutureExt;
use futures_util::sink::SinkExt;
use futures_util::stream::{Stream, StreamExt};
use jsonrpsee_types::SubscriptionId;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serde_json::Value as JsonValue;

#[doc(hidden)]
pub mod __reexports {
pub use jsonrpsee_types::{to_json_value, ParamsSer};
pub use crate::to_json_value;
pub use jsonrpsee_types::ParamsSer;
}

#[macro_export]
Expand Down
212 changes: 212 additions & 0 deletions core/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
// Copyright 2019-2021 Parity Technologies (UK) Ltd.
//
// Permission is hereby granted, free of charge, to any
// person obtaining a copy of this software and associated
// documentation files (the "Software"), to deal in the
// Software without restriction, including without
// limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice
// shall be included in all copies or substantial portions
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

use std::fmt;

use jsonrpsee_types::error::CallError;
use serde::{Deserialize, Serialize};

/// Convenience type for displaying errors.
#[derive(Clone, Debug, PartialEq)]
pub struct Mismatch<T> {
/// Expected value.
pub expected: T,
/// Actual value.
pub got: T,
}

impl<T: fmt::Display> fmt::Display for Mismatch<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_fmt(format_args!("Expected: {}, Got: {}", self.expected, self.got))
}
}

// NOTE(niklasad1): this `From` impl is a bit opinionated to regard all generic errors as `CallError`.
// In practice this should be the most common use case for users of this library.
impl From<anyhow::Error> for Error {
fn from(err: anyhow::Error) -> Self {
Error::Call(CallError::Failed(err))
}
}

/// Error type.
#[derive(Debug, thiserror::Error)]
pub enum Error {
/// Error that occurs when a call failed.
#[error("Server call failed: {0}")]
Call(#[from] CallError),
/// Networking error or error on the low-level protocol layer.
#[error("Networking or low-level protocol error: {0}")]
Transport(#[source] anyhow::Error),
/// JSON-RPC request error.
#[error("JSON-RPC request error: {0:?}")]
Request(String),
/// Frontend/backend channel error.
#[error("Frontend/backend channel error: {0}")]
Internal(#[from] futures_channel::mpsc::SendError),
/// Invalid response,
#[error("Invalid response: {0}")]
InvalidResponse(Mismatch<String>),
/// The background task has been terminated.
#[error("The background task been terminated because: {0}; restart required")]
RestartNeeded(String),
/// Failed to parse the data.
#[error("Parse error: {0}")]
ParseError(#[from] serde_json::Error),
/// Invalid subscription ID.
#[error("Invalid subscription ID")]
InvalidSubscriptionId,
/// Invalid request ID.
#[error("Invalid request ID")]
InvalidRequestId,
/// Client received a notification with an unregistered method
TarikGul marked this conversation as resolved.
Show resolved Hide resolved
#[error("Unregistered notification method")]
UnregisteredNotification(String),
/// A request with the same request ID has already been registered.
#[error("A request with the same request ID has already been registered")]
DuplicateRequestId,
/// Method was already registered.
#[error("Method: {0} was already registered")]
MethodAlreadyRegistered(String),
/// Method with that name has not yet been registered.
#[error("Method: {0} has not yet been registered")]
MethodNotFound(String),
/// Subscribe and unsubscribe method names are the same.
#[error("Cannot use the same method name for subscribe and unsubscribe, used: {0}")]
SubscriptionNameConflict(String),
/// Subscription got closed.
#[error("Subscription closed: {0:?}")]
SubscriptionClosed(SubscriptionClosedError),
/// Request timeout
#[error("Request timeout")]
RequestTimeout,
/// Configured max number of request slots exceeded.
#[error("Configured max number of request slots exceeded")]
MaxSlotsExceeded,
/// Attempted to stop server that is already stopped.
#[error("Attempted to stop server that is already stopped")]
AlreadyStopped,
/// List passed into `set_allowed_origins` was empty
#[error("Must set at least one allowed value for the {0} header")]
EmptyAllowList(&'static str),
/// Failed to execute a method because a resource was already at capacity
#[error("Resource at capacity: {0}")]
ResourceAtCapacity(&'static str),
/// Failed to register a resource due to a name conflict
#[error("Resource name already taken: {0}")]
ResourceNameAlreadyTaken(&'static str),
/// Failed to initialize resources for a method at startup
#[error("Resource name `{0}` not found for method `{1}`")]
ResourceNameNotFoundForMethod(&'static str, &'static str),
/// Trying to claim resources for a method execution, but the method resources have not been initialized
#[error("Method `{0}` has uninitialized resources")]
UninitializedMethod(Box<str>),
/// Failed to register a resource due to a maximum number of resources already registered
#[error("Maximum number of resources reached")]
MaxResourcesReached,
/// Custom error.
#[error("Custom error: {0}")]
Custom(String),
/// Not implemented for HTTP clients.
#[error("Not implemented")]
HttpNotImplemented,
}

impl Error {
/// Create `Error::CallError` from a generic error.
/// Useful if you don't care about specific JSON-RPC error code and
/// just wants to return your custom error type.
pub fn to_call_error<E>(err: E) -> Self
where
E: std::error::Error + Send + Sync + 'static,
{
Error::Call(CallError::from_std_error(err))
}
}

/// Error type with a special `subscription_closed` field to detect that
/// a subscription has been closed to distinguish valid items produced
/// by the server on the subscription stream from an error.
#[derive(Deserialize, Serialize, Debug, PartialEq)]
pub struct SubscriptionClosedError {
subscription_closed: String,
id: u64,
}

impl SubscriptionClosedError {
/// Create a new subscription closed error.
pub fn new(reason: impl Into<String>, id: u64) -> Self {
Self { subscription_closed: reason.into(), id }
}

/// Get the reason why the subscription was closed.
pub fn close_reason(&self) -> &str {
&self.subscription_closed
}

/// Get the subscription ID.
pub fn subscription_id(&self) -> u64 {
self.id
}
}

/// Generic transport error.
#[derive(Debug, thiserror::Error)]
pub enum GenericTransportError<T: std::error::Error + Send + Sync> {
/// Request was too large.
#[error("The request was too big")]
TooLarge,
/// Malformed request
#[error("Malformed request")]
Malformed,
/// Concrete transport error.
#[error("Transport error: {0}")]
Inner(T),
}

impl From<std::io::Error> for Error {
fn from(io_err: std::io::Error) -> Error {
Error::Transport(io_err.into())
}
}

impl From<soketto::handshake::Error> for Error {
fn from(handshake_err: soketto::handshake::Error) -> Error {
Error::Transport(handshake_err.into())
}
}

impl From<soketto::connection::Error> for Error {
fn from(conn_err: soketto::connection::Error) -> Error {
Error::Transport(conn_err.into())
}
}

impl From<hyper::Error> for Error {
fn from(hyper_err: hyper::Error) -> Error {
Error::Transport(hyper_err.into())
}
}
2 changes: 1 addition & 1 deletion core/src/http_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@

//! Utility methods relying on hyper

use crate::error::GenericTransportError;
use futures_util::stream::StreamExt;
use jsonrpsee_types::error::GenericTransportError;

/// Read a data from a [`hyper::Body`] and return the data if it is valid and within the allowed size range.
///
Expand Down
18 changes: 16 additions & 2 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,15 @@

#![warn(missing_docs, missing_debug_implementations, unreachable_pub)]

/// Middleware trait and implementation.
pub mod middleware;
/// Error type.
pub mod error;

/// Traits
pub mod traits;

/// Middleware trait and implementation.
pub mod middleware;

/// Shared hyper helpers.
#[cfg(feature = "http-helpers")]
pub mod http_helpers;
Expand All @@ -47,6 +50,10 @@ pub mod server;
pub mod client;

pub use async_trait::async_trait;
pub use error::Error;

/// JSON-RPC result.
pub type RpcResult<T> = std::result::Result<T, Error>;

/// Re-exports for proc-macro library to not require any additional
/// dependencies to be explicitly added on the client side.
Expand All @@ -56,3 +63,10 @@ pub mod __reexports {
pub use serde;
pub use serde_json;
}

pub use beef::Cow;
pub use serde::{de::DeserializeOwned, Serialize};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should re-export Deserialize here too..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mayhaps, we are also super inconsistent about reexports, sometimes we put them in __reexports module, and sometimes not, I'd leave that for a future PR.

pub use serde_json::{
to_value as to_json_value, value::to_raw_value as to_json_raw_value, value::RawValue as JsonRawValue,
Value as JsonValue,
};
10 changes: 5 additions & 5 deletions core/src/server/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@

use std::io;

use crate::{to_json_raw_value, Error};
use futures_channel::mpsc;
use futures_util::stream::StreamExt;
use jsonrpsee_types::error::{CallError, Error};
use jsonrpsee_types::error_response::{
ErrorCode, ErrorObject, ErrorResponse, CALL_EXECUTION_FAILED_CODE, OVERSIZED_RESPONSE_CODE, OVERSIZED_RESPONSE_MSG,
UNKNOWN_ERROR_CODE,
use jsonrpsee_types::error::{
CallError, ErrorCode, ErrorObject, ErrorResponse, CALL_EXECUTION_FAILED_CODE, OVERSIZED_RESPONSE_CODE,
OVERSIZED_RESPONSE_MSG, UNKNOWN_ERROR_CODE,
};
use jsonrpsee_types::{to_json_raw_value, Id, InvalidRequest, Response};
use jsonrpsee_types::{Id, InvalidRequest, Response};
use serde::Serialize;

/// Bounded writer that allows writing at most `max_len` bytes.
Expand Down
4 changes: 2 additions & 2 deletions core/src/server/resource_limiting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
//! `#[method]` attribute:
//!
//! ```
//! # use jsonrpsee::{types::RpcResult, proc_macros::rpc};
//! # use jsonrpsee::{core::RpcResult, proc_macros::rpc};
//! #
//! #[rpc(server)]
//! pub trait Rpc {
Expand Down Expand Up @@ -91,8 +91,8 @@

use std::sync::Arc;

use crate::Error;
use arrayvec::ArrayVec;
use jsonrpsee_types::error::Error;
use parking_lot::Mutex;

// The number of kinds of resources that can be used for limiting.
Expand Down
11 changes: 5 additions & 6 deletions core/src/server/rpc_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,21 @@ use std::future::Future;
use std::ops::{Deref, DerefMut};
use std::sync::Arc;

use crate::error::{Error, SubscriptionClosedError};
use crate::server::helpers::MethodSink;
use crate::server::resource_limiting::{ResourceGuard, ResourceTable, ResourceVec, Resources};
use crate::to_json_raw_value;
use crate::traits::ToRpcParams;
use beef::Cow;
use futures_channel::{mpsc, oneshot};
use futures_util::{future::BoxFuture, FutureExt, StreamExt};
use jsonrpsee_types::error::{Error, SubscriptionClosedError};
use jsonrpsee_types::error_response::{invalid_subscription_err, ErrorCode, CALL_EXECUTION_FAILED_CODE};
use jsonrpsee_types::to_json_raw_value;
use jsonrpsee_types::error::{invalid_subscription_err, ErrorCode, CALL_EXECUTION_FAILED_CODE};
use jsonrpsee_types::{
DeserializeOwned, Id, Params, Request, Response, SubscriptionId as RpcSubscriptionId, SubscriptionPayload,
SubscriptionResponse,
Id, Params, Request, Response, SubscriptionId as RpcSubscriptionId, SubscriptionPayload, SubscriptionResponse,
};
use parking_lot::Mutex;
use rustc_hash::FxHashMap;
use serde::Serialize;
use serde::{de::DeserializeOwned, Serialize};

/// A `MethodCallback` is an RPC endpoint, callable with a standard JSON-RPC request,
/// implemented as a function pointer to a `Fn` function taking four arguments:
Expand Down
2 changes: 1 addition & 1 deletion core/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
// DEALINGS IN THE SOFTWARE.

use crate::client::Subscription;
use crate::Error;
use async_trait::async_trait;
use jsonrpsee_types::Error;
use jsonrpsee_types::ParamsSer;
use serde::de::DeserializeOwned;
use serde::Serialize;
Expand Down
Loading