From bbacdaf201c045bae2590a8afcc5d4fec3e80a10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 23 Aug 2019 13:05:37 +0200 Subject: [PATCH 1/6] Extract author API from the substrate-rpc crate. --- Cargo.lock | 23 +++++++ core/rpc/Cargo.toml | 1 + core/rpc/api/Cargo.toml | 23 +++++++ core/rpc/{ => api}/src/author/error.rs | 8 +-- core/rpc/{ => api}/src/author/hash.rs | 0 core/rpc/api/src/author/mod.rs | 87 +++++++++++++++++++++++++ core/rpc/{ => api}/src/errors.rs | 0 core/rpc/api/src/lib.rs | 36 ++++++++++ core/rpc/{ => api}/src/metadata.rs | 0 core/rpc/{ => api}/src/subscriptions.rs | 0 core/rpc/src/author/mod.rs | 59 +---------------- core/rpc/src/lib.rs | 10 ++- 12 files changed, 180 insertions(+), 67 deletions(-) create mode 100644 core/rpc/api/Cargo.toml rename core/rpc/{ => api}/src/author/error.rs (96%) rename core/rpc/{ => api}/src/author/hash.rs (100%) create mode 100644 core/rpc/api/src/author/mod.rs rename core/rpc/{ => api}/src/errors.rs (100%) create mode 100644 core/rpc/api/src/lib.rs rename core/rpc/{ => api}/src/metadata.rs (100%) rename core/rpc/{ => api}/src/subscriptions.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 1c6a4f19231f8..225bfa766e765 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4971,6 +4971,7 @@ dependencies = [ "substrate-keystore 2.0.0", "substrate-network 2.0.0", "substrate-primitives 2.0.0", + "substrate-rpc-api 2.0.0", "substrate-session 2.0.0", "substrate-state-machine 2.0.0", "substrate-test-runtime-client 2.0.0", @@ -4978,6 +4979,28 @@ dependencies = [ "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "substrate-rpc-api" +version = "2.0.0" +dependencies = [ + "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", + "sr-version 2.0.0", + "substrate-primitives 2.0.0", + "substrate-transaction-graph 2.0.0", +] + [[package]] name = "substrate-rpc-servers" version = "2.0.0" diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index 0a9cf108c9ede..19cdd7529cea9 100644 --- a/core/rpc/Cargo.toml +++ b/core/rpc/Cargo.toml @@ -5,6 +5,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] +api = { package = "substrate-rpc-api", path = "./api" } derive_more = "0.14.0" futures = "0.1" futures03 = { package = "futures-preview", version = "0.3.0-alpha.17", features = ["compat"] } diff --git a/core/rpc/api/Cargo.toml b/core/rpc/api/Cargo.toml new file mode 100644 index 0000000000000..39c31873acd5a --- /dev/null +++ b/core/rpc/api/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "substrate-rpc-api" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0" } +derive_more = "0.14.0" +futures = "0.1" +futures03 = { package = "futures-preview", version = "0.3.0-alpha.17", features = ["compat"] } +jsonrpc-core = "13.0.0" +jsonrpc-core-client = "13.0.0" +jsonrpc-derive = "13.0.0" +jsonrpc-pubsub = "13.0.0" +log = "0.4" +parking_lot = "0.9.0" +primitives = { package = "substrate-primitives", path = "../../primitives" } +runtime_version = { package = "sr-version", path = "../../sr-version" } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +sr-primitives = { path = "../../sr-primitives" } +txpool = { package = "substrate-transaction-graph", path = "../../transaction-pool/graph" } diff --git a/core/rpc/src/author/error.rs b/core/rpc/api/src/author/error.rs similarity index 96% rename from core/rpc/src/author/error.rs rename to core/rpc/api/src/author/error.rs index 2fcc8c780dfdb..9083ae23a0387 100644 --- a/core/rpc/src/author/error.rs +++ b/core/rpc/api/src/author/error.rs @@ -16,8 +16,6 @@ //! Authoring RPC module errors. -use client; -use transaction_pool::txpool; use crate::rpc; use crate::errors; @@ -28,8 +26,10 @@ pub type Result = std::result::Result; #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { /// Client error. - Client(client::error::Error), + #[display(fmt="Client error: {}", _0)] + Client(Box), /// Transaction pool error, + #[display(fmt="Transaction pool error: {}", _0)] Pool(txpool::error::Error), /// Verification error #[display(fmt="Extrinsic verification error: {}", _0)] @@ -54,7 +54,7 @@ pub enum Error { impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - Error::Client(ref err) => Some(err), + Error::Client(ref err) => Some(&**err), Error::Pool(ref err) => Some(err), Error::Verification(ref err) => Some(&**err), _ => None, diff --git a/core/rpc/src/author/hash.rs b/core/rpc/api/src/author/hash.rs similarity index 100% rename from core/rpc/src/author/hash.rs rename to core/rpc/api/src/author/hash.rs diff --git a/core/rpc/api/src/author/mod.rs b/core/rpc/api/src/author/mod.rs new file mode 100644 index 0000000000000..3eb36b1e3c636 --- /dev/null +++ b/core/rpc/api/src/author/mod.rs @@ -0,0 +1,87 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate block-author/full-node API. + +mod error; +mod hash; + +use jsonrpc_derive::rpc; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use primitives::{ + Bytes +}; +use self::error::Result; +use txpool::watcher::Status; + +pub use self::gen_client::Client as AuthorClient; + +/// Substrate authoring RPC API +#[rpc] +pub trait AuthorApi { + /// RPC metadata + type Metadata; + + /// Submit hex-encoded extrinsic for inclusion in block. + #[rpc(name = "author_submitExtrinsic")] + fn submit_extrinsic(&self, extrinsic: Bytes) -> Result; + + /// Insert a key into the keystore. + #[rpc(name = "author_insertKey")] + fn insert_key(&self, + key_type: String, + suri: String, + maybe_public: Option + ) -> Result; + + /// Generate new session keys and returns the corresponding public keys. + #[rpc(name = "author_rotateKeys")] + fn rotate_keys(&self) -> Result; + + /// Returns all pending extrinsics, potentially grouped by sender. + #[rpc(name = "author_pendingExtrinsics")] + fn pending_extrinsics(&self) -> Result>; + + /// Remove given extrinsic from the pool and temporarily ban it to prevent reimporting. + #[rpc(name = "author_removeExtrinsic")] + fn remove_extrinsic(&self, + bytes_or_hash: Vec> + ) -> Result>; + + /// Submit an extrinsic to watch. + #[pubsub( + subscription = "author_extrinsicUpdate", + subscribe, + name = "author_submitAndWatchExtrinsic" + )] + fn watch_extrinsic(&self, + metadata: Self::Metadata, + subscriber: Subscriber>, + bytes: Bytes + ); + + /// Unsubscribe from extrinsic watching. + #[pubsub( + subscription = "author_extrinsicUpdate", + unsubscribe, + name = "author_unwatchExtrinsic" + )] + fn unwatch_extrinsic(&self, + metadata: Option, + id: SubscriptionId + ) -> Result; +} + diff --git a/core/rpc/src/errors.rs b/core/rpc/api/src/errors.rs similarity index 100% rename from core/rpc/src/errors.rs rename to core/rpc/api/src/errors.rs diff --git a/core/rpc/api/src/lib.rs b/core/rpc/api/src/lib.rs new file mode 100644 index 0000000000000..1a84077c29f04 --- /dev/null +++ b/core/rpc/api/src/lib.rs @@ -0,0 +1,36 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate RPC interfaces. +//! +//! A collection of RPC methods and subscriptions supported by all substrate clients. + +#![warn(missing_docs)] + +mod errors; +mod metadata; +mod subscriptions; + +use jsonrpc_core as rpc; + +pub use metadata::Metadata; +pub use rpc::IoHandlerExtension as RpcExtension; +pub use subscriptions::Subscriptions; + +pub mod author; +// pub mod chain; +// pub mod state; +// pub mod system; diff --git a/core/rpc/src/metadata.rs b/core/rpc/api/src/metadata.rs similarity index 100% rename from core/rpc/src/metadata.rs rename to core/rpc/api/src/metadata.rs diff --git a/core/rpc/src/subscriptions.rs b/core/rpc/api/src/subscriptions.rs similarity index 100% rename from core/rpc/src/subscriptions.rs rename to core/rpc/api/src/subscriptions.rs diff --git a/core/rpc/src/author/mod.rs b/core/rpc/src/author/mod.rs index 6e2d7aa92abc9..372096da5e050 100644 --- a/core/rpc/src/author/mod.rs +++ b/core/rpc/src/author/mod.rs @@ -50,63 +50,8 @@ use transaction_pool::{ }; use session::SessionKeys; -pub use self::gen_client::Client as AuthorClient; - -/// Substrate authoring RPC API -#[rpc] -pub trait AuthorApi { - /// RPC metadata - type Metadata; - - /// Submit hex-encoded extrinsic for inclusion in block. - #[rpc(name = "author_submitExtrinsic")] - fn submit_extrinsic(&self, extrinsic: Bytes) -> Result; - - /// Insert a key into the keystore. - #[rpc(name = "author_insertKey")] - fn insert_key(&self, - key_type: String, - suri: String, - maybe_public: Option - ) -> Result; - - /// Generate new session keys and returns the corresponding public keys. - #[rpc(name = "author_rotateKeys")] - fn rotate_keys(&self) -> Result; - - /// Returns all pending extrinsics, potentially grouped by sender. - #[rpc(name = "author_pendingExtrinsics")] - fn pending_extrinsics(&self) -> Result>; - - /// Remove given extrinsic from the pool and temporarily ban it to prevent reimporting. - #[rpc(name = "author_removeExtrinsic")] - fn remove_extrinsic(&self, - bytes_or_hash: Vec> - ) -> Result>; - - /// Submit an extrinsic to watch. - #[pubsub( - subscription = "author_extrinsicUpdate", - subscribe, - name = "author_submitAndWatchExtrinsic" - )] - fn watch_extrinsic(&self, - metadata: Self::Metadata, - subscriber: Subscriber>, - bytes: Bytes - ); - - /// Unsubscribe from extrinsic watching. - #[pubsub( - subscription = "author_extrinsicUpdate", - unsubscribe, - name = "author_unwatchExtrinsic" - )] - fn unwatch_extrinsic(&self, - metadata: Option, - id: SubscriptionId - ) -> Result; -} +/// Re-export the API for backward compatibility. +pub use api::author::*; /// Authoring API pub struct Author where P: PoolChainApi + Sync + Send + 'static { diff --git a/core/rpc/src/lib.rs b/core/rpc/src/lib.rs index 7ca3fde01de46..39a7b72d35de0 100644 --- a/core/rpc/src/lib.rs +++ b/core/rpc/src/lib.rs @@ -14,22 +14,20 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Substrate RPC interfaces. +//! Substrate RPC implementation. //! -//! A collection of RPC methods and subscriptions supported by all substrate clients. +//! A core implementation of Substrate RPC interfaces. #![warn(missing_docs)] mod errors; mod helpers; -mod metadata; -mod subscriptions; use jsonrpc_core as rpc; -pub use metadata::Metadata; +pub use api::metadata::Metadata; +pub use api::subscriptions::Subscriptions; pub use rpc::IoHandlerExtension as RpcExtension; -pub use subscriptions::Subscriptions; pub mod author; pub mod chain; From 9054549cb1e48490422524c12099bbd10a722df9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 27 Aug 2019 16:26:55 +0200 Subject: [PATCH 2/6] Split out API from RPC. --- core/rpc/Cargo.toml | 24 +-- core/rpc/api/Cargo.toml | 4 +- core/rpc/api/src/author/error.rs | 2 +- core/rpc/api/src/author/mod.rs | 6 +- core/rpc/{ => api}/src/chain/error.rs | 8 +- core/rpc/api/src/chain/mod.rs | 89 +++++++++++ core/rpc/{ => api}/src/chain/number.rs | 0 core/rpc/api/src/errors.rs | 2 +- core/rpc/api/src/helpers.rs | 31 ++++ core/rpc/api/src/lib.rs | 12 +- core/rpc/{ => api}/src/state/error.rs | 8 +- core/rpc/api/src/state/mod.rs | 143 +++++++++++++++++ core/rpc/api/src/subscriptions.rs | 4 +- core/rpc/{ => api}/src/system/error.rs | 2 +- core/rpc/{ => api}/src/system/helpers.rs | 0 core/rpc/api/src/system/mod.rs | 67 ++++++++ core/rpc/src/author/mod.rs | 12 +- core/rpc/src/chain/mod.rs | 90 ++--------- core/rpc/src/helpers.rs | 16 -- core/rpc/src/lib.rs | 6 +- core/rpc/{api => }/src/metadata.rs | 4 +- core/rpc/src/state/mod.rs | 188 ++++++----------------- core/rpc/src/system/mod.rs | 52 +------ core/service/src/lib.rs | 4 +- 24 files changed, 440 insertions(+), 334 deletions(-) rename core/rpc/{ => api}/src/chain/error.rs (91%) create mode 100644 core/rpc/api/src/chain/mod.rs rename core/rpc/{ => api}/src/chain/number.rs (100%) create mode 100644 core/rpc/api/src/helpers.rs rename core/rpc/{ => api}/src/state/error.rs (92%) create mode 100644 core/rpc/api/src/state/mod.rs rename core/rpc/{ => api}/src/system/error.rs (98%) rename core/rpc/{ => api}/src/system/helpers.rs (100%) create mode 100644 core/rpc/api/src/system/mod.rs rename core/rpc/{api => }/src/metadata.rs (95%) diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index 19cdd7529cea9..9031c814160ca 100644 --- a/core/rpc/Cargo.toml +++ b/core/rpc/Cargo.toml @@ -6,28 +6,20 @@ edition = "2018" [dependencies] api = { package = "substrate-rpc-api", path = "./api" } -derive_more = "0.14.0" -futures = "0.1" +client = { package = "substrate-client", path = "../client" } +codec = { package = "parity-scale-codec", version = "1.0.0" } futures03 = { package = "futures-preview", version = "0.3.0-alpha.17", features = ["compat"] } -jsonrpc-core = "13.0.0" -jsonrpc-core-client = "13.0.0" -jsonrpc-pubsub = "13.0.0" -jsonrpc-derive = "13.0.0" log = "0.4" -parking_lot = "0.9.0" -codec = { package = "parity-scale-codec", version = "1.0.0" } -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -client = { package = "substrate-client", path = "../client" } -substrate-executor = { path = "../executor" } -network = { package = "substrate-network", path = "../network" } primitives = { package = "substrate-primitives", path = "../primitives" } +rpc = { package = "jsonrpc-core", version = "13.0.0" } +runtime_version = { package = "sr-version", path = "../sr-version" } +serde_json = "1.0" session = { package = "substrate-session", path = "../session" } -state_machine = { package = "substrate-state-machine", path = "../state-machine" } -transaction_pool = { package = "substrate-transaction-pool", path = "../transaction-pool" } sr-primitives = { path = "../sr-primitives" } -runtime_version = { package = "sr-version", path = "../sr-version" } +state_machine = { package = "substrate-state-machine", path = "../state-machine" } +substrate-executor = { path = "../executor" } substrate-keystore = { path = "../keystore" } +transaction_pool = { package = "substrate-transaction-pool", path = "../transaction-pool" } [dev-dependencies] assert_matches = "1.1" diff --git a/core/rpc/api/Cargo.toml b/core/rpc/api/Cargo.toml index 39c31873acd5a..18fa45f332c22 100644 --- a/core/rpc/api/Cargo.toml +++ b/core/rpc/api/Cargo.toml @@ -7,17 +7,15 @@ edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0" } derive_more = "0.14.0" -futures = "0.1" futures03 = { package = "futures-preview", version = "0.3.0-alpha.17", features = ["compat"] } -jsonrpc-core = "13.0.0" jsonrpc-core-client = "13.0.0" jsonrpc-derive = "13.0.0" jsonrpc-pubsub = "13.0.0" log = "0.4" parking_lot = "0.9.0" primitives = { package = "substrate-primitives", path = "../../primitives" } +rpc = { package = "jsonrpc-core", version = "13.0.0" } runtime_version = { package = "sr-version", path = "../../sr-version" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -sr-primitives = { path = "../../sr-primitives" } txpool = { package = "substrate-transaction-graph", path = "../../transaction-pool/graph" } diff --git a/core/rpc/api/src/author/error.rs b/core/rpc/api/src/author/error.rs index 9083ae23a0387..cc339b1652464 100644 --- a/core/rpc/api/src/author/error.rs +++ b/core/rpc/api/src/author/error.rs @@ -16,7 +16,7 @@ //! Authoring RPC module errors. -use crate::rpc; +use rpc; use crate::errors; /// Author RPC Result type. diff --git a/core/rpc/api/src/author/mod.rs b/core/rpc/api/src/author/mod.rs index 3eb36b1e3c636..3d5698880a8b4 100644 --- a/core/rpc/api/src/author/mod.rs +++ b/core/rpc/api/src/author/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. +// Copyright 2017-2019 Parity Technologies (UK) Ltd. // This file is part of Substrate. // Substrate is free software: you can redistribute it and/or modify @@ -16,8 +16,8 @@ //! Substrate block-author/full-node API. -mod error; -mod hash; +pub mod error; +pub mod hash; use jsonrpc_derive::rpc; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; diff --git a/core/rpc/src/chain/error.rs b/core/rpc/api/src/chain/error.rs similarity index 91% rename from core/rpc/src/chain/error.rs rename to core/rpc/api/src/chain/error.rs index ad63af9add051..9bfed53fbd15c 100644 --- a/core/rpc/src/chain/error.rs +++ b/core/rpc/api/src/chain/error.rs @@ -17,8 +17,7 @@ //! Error helpers for Chain RPC module. -use client; -use crate::rpc; +use rpc; use crate::errors; /// Chain RPC Result type. @@ -28,7 +27,8 @@ pub type Result = std::result::Result; #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { /// Client error. - Client(client::error::Error), + #[display(fmt="Client error: {}", _0)] + Client(Box), /// Other error type. Other(String), } @@ -36,7 +36,7 @@ pub enum Error { impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - Error::Client(ref err) => Some(err), + Error::Client(ref err) => Some(&**err), _ => None, } } diff --git a/core/rpc/api/src/chain/mod.rs b/core/rpc/api/src/chain/mod.rs new file mode 100644 index 0000000000000..49473ce376d92 --- /dev/null +++ b/core/rpc/api/src/chain/mod.rs @@ -0,0 +1,89 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate blockchain API. + +pub mod error; +pub mod number; + +use rpc::Result as RpcResult; +use rpc::futures::Future; +use jsonrpc_derive::rpc; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use self::error::Result; + +pub use self::gen_client::Client as ChainClient; + +/// Substrate blockchain API +#[rpc] +pub trait ChainApi { + /// RPC metadata + type Metadata; + + /// Get header of a relay chain block. + #[rpc(name = "chain_getHeader")] + fn header(&self, hash: Option) -> Result>; + + /// Get header and body of a relay chain block. + #[rpc(name = "chain_getBlock")] + fn block(&self, hash: Option) -> Result>; + + /// Get hash of the n-th block in the canon chain. + /// + /// By default returns latest block hash. + #[rpc(name = "chain_getBlockHash", alias("chain_getHead"))] + fn block_hash(&self, hash: Option>) -> Result>; + + /// Get hash of the last finalized block in the canon chain. + #[rpc(name = "chain_getFinalizedHead", alias("chain_getFinalisedHead"))] + fn finalized_head(&self) -> Result; + + /// New head subscription + #[pubsub( + subscription = "chain_newHead", + subscribe, + name = "chain_subscribeNewHead", + alias("subscribe_newHead") + )] + fn subscribe_new_head(&self, metadata: Self::Metadata, subscriber: Subscriber
); + + /// Unsubscribe from new head subscription. + #[pubsub( + subscription = "chain_newHead", + unsubscribe, + name = "chain_unsubscribeNewHead", + alias("unsubscribe_newHead") + )] + fn unsubscribe_new_head(&self, metadata: Option, id: SubscriptionId) -> RpcResult; + + /// New head subscription + #[pubsub( + subscription = "chain_finalizedHead", + subscribe, + name = "chain_subscribeFinalizedHeads", + alias("chain_subscribeFinalisedHeads") + )] + fn subscribe_finalized_heads(&self, metadata: Self::Metadata, subscriber: Subscriber
); + + /// Unsubscribe from new head subscription. + #[pubsub( + subscription = "chain_finalizedHead", + unsubscribe, + name = "chain_unsubscribeFinalizedHeads", + alias("chain_unsubscribeFinalisedHeads") + )] + fn unsubscribe_finalized_heads(&self, metadata: Option, id: SubscriptionId) -> RpcResult; +} diff --git a/core/rpc/src/chain/number.rs b/core/rpc/api/src/chain/number.rs similarity index 100% rename from core/rpc/src/chain/number.rs rename to core/rpc/api/src/chain/number.rs diff --git a/core/rpc/api/src/errors.rs b/core/rpc/api/src/errors.rs index da910de76215a..b69a2638b2fc8 100644 --- a/core/rpc/api/src/errors.rs +++ b/core/rpc/api/src/errors.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use crate::rpc; +use rpc; use log::warn; pub fn internal(e: E) -> rpc::Error { diff --git a/core/rpc/api/src/helpers.rs b/core/rpc/api/src/helpers.rs new file mode 100644 index 0000000000000..4d93a2f6f6dc8 --- /dev/null +++ b/core/rpc/api/src/helpers.rs @@ -0,0 +1,31 @@ +// Copyright 2018-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use rpc::futures::prelude::*; +use futures03::{channel::oneshot, compat::Compat}; + +/// Wraps around `oneshot::Receiver` and adjusts the error type to produce an internal error if the +/// sender gets dropped. +pub struct Receiver(pub Compat>); + +impl Future for Receiver { + type Item = T; + type Error = jsonrpc_core::Error; + + fn poll(&mut self) -> Poll { + self.0.poll().map_err(|_| jsonrpc_core::Error::internal_error()) + } +} diff --git a/core/rpc/api/src/lib.rs b/core/rpc/api/src/lib.rs index 1a84077c29f04..eb11865ed85cd 100644 --- a/core/rpc/api/src/lib.rs +++ b/core/rpc/api/src/lib.rs @@ -21,16 +21,14 @@ #![warn(missing_docs)] mod errors; -mod metadata; +mod helpers; mod subscriptions; -use jsonrpc_core as rpc; - -pub use metadata::Metadata; pub use rpc::IoHandlerExtension as RpcExtension; pub use subscriptions::Subscriptions; +pub use helpers::Receiver; pub mod author; -// pub mod chain; -// pub mod state; -// pub mod system; +pub mod chain; +pub mod state; +pub mod system; diff --git a/core/rpc/src/state/error.rs b/core/rpc/api/src/state/error.rs similarity index 92% rename from core/rpc/src/state/error.rs rename to core/rpc/api/src/state/error.rs index 4b9d30b36b204..b39e159bfc4e1 100644 --- a/core/rpc/src/state/error.rs +++ b/core/rpc/api/src/state/error.rs @@ -16,8 +16,7 @@ //! State RPC errors. -use client; -use crate::rpc; +use rpc; use crate::errors; /// State RPC Result type. @@ -27,7 +26,8 @@ pub type Result = std::result::Result; #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { /// Client error. - Client(client::error::Error), + #[display(fmt="Client error: {}", _0)] + Client(Box), /// Provided block range couldn't be resolved to a list of blocks. #[display(fmt = "Cannot resolve a block range ['{:?}' ... '{:?}]. {}", from, to, details)] InvalidBlockRange { @@ -43,7 +43,7 @@ pub enum Error { impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - Error::Client(ref err) => Some(err), + Error::Client(ref err) => Some(&**err), _ => None, } } diff --git a/core/rpc/api/src/state/mod.rs b/core/rpc/api/src/state/mod.rs new file mode 100644 index 0000000000000..7463f1c109d27 --- /dev/null +++ b/core/rpc/api/src/state/mod.rs @@ -0,0 +1,143 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate state API. + +pub mod error; + +use rpc::Result as RpcResult; +use rpc::futures::Future; +use jsonrpc_derive::rpc; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use primitives::Bytes; +use primitives::storage::{StorageKey, StorageData, StorageChangeSet}; +use runtime_version::RuntimeVersion; +use self::error::Result; + +pub use self::gen_client::Client as StateClient; + +/// Substrate state API +#[rpc] +pub trait StateApi { + /// RPC Metadata + type Metadata; + + /// Call a contract at a block's state. + #[rpc(name = "state_call", alias("state_callAt"))] + fn call(&self, name: String, bytes: Bytes, hash: Option) -> Result; + + /// Returns the keys with prefix, leave empty to get all the keys + #[rpc(name = "state_getKeys")] + fn storage_keys(&self, prefix: StorageKey, hash: Option) -> Result>; + + /// Returns a storage entry at a specific block's state. + #[rpc(name = "state_getStorage", alias("state_getStorageAt"))] + fn storage(&self, key: StorageKey, hash: Option) -> Result>; + + /// Returns the hash of a storage entry at a block's state. + #[rpc(name = "state_getStorageHash", alias("state_getStorageHashAt"))] + fn storage_hash(&self, key: StorageKey, hash: Option) -> Result>; + + /// Returns the size of a storage entry at a block's state. + #[rpc(name = "state_getStorageSize", alias("state_getStorageSizeAt"))] + fn storage_size(&self, key: StorageKey, hash: Option) -> Result>; + + /// Returns the keys with prefix from a child storage, leave empty to get all the keys + #[rpc(name = "state_getChildKeys")] + fn child_storage_keys( + &self, + child_storage_key: StorageKey, + prefix: StorageKey, + hash: Option + ) -> Result>; + + /// Returns a child storage entry at a specific block's state. + #[rpc(name = "state_getChildStorage")] + fn child_storage( + &self, + child_storage_key: StorageKey, + key: StorageKey, + hash: Option + ) -> Result>; + + /// Returns the hash of a child storage entry at a block's state. + #[rpc(name = "state_getChildStorageHash")] + fn child_storage_hash( + &self, + child_storage_key: StorageKey, + key: StorageKey, + hash: Option + ) -> Result>; + + /// Returns the size of a child storage entry at a block's state. + #[rpc(name = "state_getChildStorageSize")] + fn child_storage_size( + &self, + child_storage_key: StorageKey, + key: StorageKey, + hash: Option + ) -> Result>; + + /// Returns the runtime metadata as an opaque blob. + #[rpc(name = "state_getMetadata")] + fn metadata(&self, hash: Option) -> Result; + + /// Get the runtime version. + #[rpc(name = "state_getRuntimeVersion", alias("chain_getRuntimeVersion"))] + fn runtime_version(&self, hash: Option) -> Result; + + /// Query historical storage entries (by key) starting from a block given as the second parameter. + /// + /// NOTE This first returned result contains the initial state of storage for all keys. + /// Subsequent values in the vector represent changes to the previous state (diffs). + #[rpc(name = "state_queryStorage")] + fn query_storage( + &self, + keys: Vec, + block: Hash, + hash: Option + ) -> Result>>; + + /// New runtime version subscription + #[pubsub( + subscription = "state_runtimeVersion", + subscribe, + name = "state_subscribeRuntimeVersion", + alias("chain_subscribeRuntimeVersion") + )] + fn subscribe_runtime_version(&self, metadata: Self::Metadata, subscriber: Subscriber); + + /// Unsubscribe from runtime version subscription + #[pubsub( + subscription = "state_runtimeVersion", + unsubscribe, + name = "state_unsubscribeRuntimeVersion", + alias("chain_unsubscribeRuntimeVersion") + )] + fn unsubscribe_runtime_version(&self, metadata: Option, id: SubscriptionId) -> RpcResult; + + /// New storage subscription + #[pubsub(subscription = "state_storage", subscribe, name = "state_subscribeStorage")] + fn subscribe_storage( + &self, metadata: Self::Metadata, subscriber: Subscriber>, keys: Option> + ); + + /// Unsubscribe from storage subscription + #[pubsub(subscription = "state_storage", unsubscribe, name = "state_unsubscribeStorage")] + fn unsubscribe_storage( + &self, metadata: Option, id: SubscriptionId + ) -> RpcResult; +} diff --git a/core/rpc/api/src/subscriptions.rs b/core/rpc/api/src/subscriptions.rs index 77df0c09fdc78..4c6a71bc695ec 100644 --- a/core/rpc/api/src/subscriptions.rs +++ b/core/rpc/api/src/subscriptions.rs @@ -20,8 +20,8 @@ use std::sync::{Arc, atomic::{self, AtomicUsize}}; use log::{error, warn}; use jsonrpc_pubsub::{SubscriptionId, typed::{Sink, Subscriber}}; use parking_lot::Mutex; -use crate::rpc::futures::sync::oneshot; -use crate::rpc::futures::{Future, future}; +use rpc::futures::sync::oneshot; +use rpc::futures::{Future, future}; type Id = u64; diff --git a/core/rpc/src/system/error.rs b/core/rpc/api/src/system/error.rs similarity index 98% rename from core/rpc/src/system/error.rs rename to core/rpc/api/src/system/error.rs index bdd4cbe667e59..313210b988d9e 100644 --- a/core/rpc/src/system/error.rs +++ b/core/rpc/api/src/system/error.rs @@ -16,7 +16,7 @@ //! System RPC module errors. -use crate::rpc; +use rpc; use crate::system::helpers::Health; /// System RPC Result type. diff --git a/core/rpc/src/system/helpers.rs b/core/rpc/api/src/system/helpers.rs similarity index 100% rename from core/rpc/src/system/helpers.rs rename to core/rpc/api/src/system/helpers.rs diff --git a/core/rpc/api/src/system/mod.rs b/core/rpc/api/src/system/mod.rs new file mode 100644 index 0000000000000..b5eacc5d61823 --- /dev/null +++ b/core/rpc/api/src/system/mod.rs @@ -0,0 +1,67 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate system API. + +pub mod error; +pub mod helpers; + +use crate::helpers::Receiver; +use jsonrpc_derive::rpc; + +use self::error::Result; + +pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo}; +pub use self::gen_client::Client as SystemClient; + +/// Substrate system RPC API +#[rpc] +pub trait SystemApi { + /// Get the node's implementation name. Plain old string. + #[rpc(name = "system_name")] + fn system_name(&self) -> Result; + + /// Get the node implementation's version. Should be a semver string. + #[rpc(name = "system_version")] + fn system_version(&self) -> Result; + + /// Get the chain's type. Given as a string identifier. + #[rpc(name = "system_chain")] + fn system_chain(&self) -> Result; + + /// Get a custom set of properties as a JSON object, defined in the chain spec. + #[rpc(name = "system_properties")] + fn system_properties(&self) -> Result; + + /// Return health status of the node. + /// + /// Node is considered healthy if it is: + /// - connected to some peers (unless running in dev mode) + /// - not performing a major sync + #[rpc(name = "system_health", returns = "Health")] + fn system_health(&self) -> Receiver; + + /// Returns currently connected peers + #[rpc(name = "system_peers", returns = "Vec>")] + fn system_peers(&self) -> Receiver>>; + + /// Returns current state of the network. + /// + /// **Warning**: This API is not stable. + // TODO: make this stable and move structs https://github.com/paritytech/substrate/issues/1890 + #[rpc(name = "system_networkState", returns = "jsonrpc_core::Value")] + fn system_network_state(&self) -> Receiver; +} diff --git a/core/rpc/src/author/mod.rs b/core/rpc/src/author/mod.rs index 372096da5e050..81aa92e3ab451 100644 --- a/core/rpc/src/author/mod.rs +++ b/core/rpc/src/author/mod.rs @@ -16,19 +16,15 @@ //! Substrate block-author/full-node API. -pub mod error; -pub mod hash; - #[cfg(test)] mod tests; use std::{sync::Arc, convert::TryInto}; use client::{self, Client}; -use crate::rpc::futures::{Sink, Future}; -use crate::subscriptions::Subscriptions; +use rpc::futures::{Sink, Future}; use futures03::{StreamExt as _, compat::Compat}; -use jsonrpc_derive::rpc; +use api::Subscriptions; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use log::warn; use codec::{Encode, Decode}; @@ -37,7 +33,6 @@ use primitives::{ traits::BareCryptoStorePtr, }; use sr_primitives::{generic, traits::{self, ProvideRuntimeApi}}; -use self::error::{Error, Result}; use transaction_pool::{ txpool::{ ChainApi as PoolChainApi, @@ -52,6 +47,7 @@ use session::SessionKeys; /// Re-export the API for backward compatibility. pub use api::author::*; +use self::error::{Error, Result}; /// Authoring API pub struct Author where P: PoolChainApi + Sync + Send + 'static { @@ -128,7 +124,7 @@ impl AuthorApi, BlockHash

> for Author whe self.client.runtime_api().generate_session_keys( &generic::BlockId::Hash(best_block_hash), None, - ).map(Into::into).map_err(Into::into) + ).map(Into::into).map_err(|e| Error::Client(Box::new(e))) } fn submit_extrinsic(&self, ext: Bytes) -> Result> { diff --git a/core/rpc/src/chain/mod.rs b/core/rpc/src/chain/mod.rs index 9b8192e660e9b..98b7d5540a76b 100644 --- a/core/rpc/src/chain/mod.rs +++ b/core/rpc/src/chain/mod.rs @@ -16,9 +16,6 @@ //! Substrate blockchain API. -pub mod error; -pub mod number; - #[cfg(test)] mod tests; @@ -26,79 +23,17 @@ use std::sync::Arc; use futures03::{future, StreamExt as _, TryStreamExt as _}; use client::{self, Client, BlockchainEvents}; -use crate::rpc::Result as RpcResult; -use crate::rpc::futures::{stream, Future, Sink, Stream}; -use crate::subscriptions::Subscriptions; -use jsonrpc_derive::rpc; +use rpc::Result as RpcResult; +use rpc::futures::{stream, Future, Sink, Stream}; +use api::Subscriptions; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use log::warn; use primitives::{H256, Blake2Hasher}; use sr_primitives::generic::{BlockId, SignedBlock}; use sr_primitives::traits::{Block as BlockT, Header, NumberFor}; -use self::error::Result; - -pub use self::gen_client::Client as ChainClient; - -/// Substrate blockchain API -#[rpc] -pub trait ChainApi { - /// RPC metadata - type Metadata; - - /// Get header of a relay chain block. - #[rpc(name = "chain_getHeader")] - fn header(&self, hash: Option) -> Result>; - - /// Get header and body of a relay chain block. - #[rpc(name = "chain_getBlock")] - fn block(&self, hash: Option) -> Result>; - - /// Get hash of the n-th block in the canon chain. - /// - /// By default returns latest block hash. - #[rpc(name = "chain_getBlockHash", alias("chain_getHead"))] - fn block_hash(&self, hash: Option>) -> Result>; - - /// Get hash of the last finalized block in the canon chain. - #[rpc(name = "chain_getFinalizedHead", alias("chain_getFinalisedHead"))] - fn finalized_head(&self) -> Result; - - /// New head subscription - #[pubsub( - subscription = "chain_newHead", - subscribe, - name = "chain_subscribeNewHead", - alias("subscribe_newHead") - )] - fn subscribe_new_head(&self, metadata: Self::Metadata, subscriber: Subscriber

); - - /// Unsubscribe from new head subscription. - #[pubsub( - subscription = "chain_newHead", - unsubscribe, - name = "chain_unsubscribeNewHead", - alias("unsubscribe_newHead") - )] - fn unsubscribe_new_head(&self, metadata: Option, id: SubscriptionId) -> RpcResult; - - /// New head subscription - #[pubsub( - subscription = "chain_finalizedHead", - subscribe, - name = "chain_subscribeFinalizedHeads", - alias("chain_subscribeFinalisedHeads") - )] - fn subscribe_finalized_heads(&self, metadata: Self::Metadata, subscriber: Subscriber
); - - /// Unsubscribe from new head subscription. - #[pubsub( - subscription = "chain_finalizedHead", - unsubscribe, - name = "chain_unsubscribeFinalizedHeads", - alias("chain_unsubscribeFinalisedHeads") - )] - fn unsubscribe_finalized_heads(&self, metadata: Option, id: SubscriptionId) -> RpcResult; -} +use self::error::{Error, Result}; + +pub use api::chain::*; /// Chain API with subscriptions support. pub struct Chain { @@ -168,6 +103,10 @@ impl Chain where } } +fn client_error(err: client::error::Error) -> Error { + Error::Client(Box::new(err)) +} + impl ChainApi, Block::Hash, Block::Header, SignedBlock> for Chain where Block: BlockT + 'static, B: client::backend::Backend + Send + Sync + 'static, @@ -178,20 +117,23 @@ impl ChainApi, Block::Hash, Block::Header, Sig fn header(&self, hash: Option) -> Result> { let hash = self.unwrap_or_best(hash)?; - Ok(self.client.header(&BlockId::Hash(hash))?) + Ok(self.client.header(&BlockId::Hash(hash)).map_err(client_error)?) } fn block(&self, hash: Option) -> Result>> { let hash = self.unwrap_or_best(hash)?; - Ok(self.client.block(&BlockId::Hash(hash))?) + Ok(self.client.block(&BlockId::Hash(hash)).map_err(client_error)?) } fn block_hash(&self, number: Option>>) -> Result> { Ok(match number { None => Some(self.client.info().chain.best_hash), - Some(num_or_hex) => self.client.header(&BlockId::number(num_or_hex.to_number()?))?.map(|h| h.hash()), + Some(num_or_hex) => self.client + .header(&BlockId::number(num_or_hex.to_number()?)) + .map_err(client_error)? + .map(|h| h.hash()), }) } diff --git a/core/rpc/src/helpers.rs b/core/rpc/src/helpers.rs index 2c69ead76caae..e579c743acdad 100644 --- a/core/rpc/src/helpers.rs +++ b/core/rpc/src/helpers.rs @@ -14,22 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use futures::prelude::*; -use futures03::{channel::oneshot, compat::Compat}; - -/// Wraps around `oneshot::Receiver` and adjusts the error type to produce an internal error if the -/// sender gets dropped. -pub struct Receiver(pub Compat>); - -impl Future for Receiver { - type Item = T; - type Error = jsonrpc_core::Error; - - fn poll(&mut self) -> Poll { - self.0.poll().map_err(|_| jsonrpc_core::Error::internal_error()) - } -} - /// Unwraps the trailing parameter or falls back with the closure result. pub fn unwrap_or_else(or_else: F, optional: Option) -> Result where F: FnOnce() -> Result, diff --git a/core/rpc/src/lib.rs b/core/rpc/src/lib.rs index 39a7b72d35de0..696ab116a435c 100644 --- a/core/rpc/src/lib.rs +++ b/core/rpc/src/lib.rs @@ -20,13 +20,13 @@ #![warn(missing_docs)] -mod errors; mod helpers; +mod metadata; use jsonrpc_core as rpc; -pub use api::metadata::Metadata; -pub use api::subscriptions::Subscriptions; +pub use api::Subscriptions; +pub use self::metadata::Metadata; pub use rpc::IoHandlerExtension as RpcExtension; pub mod author; diff --git a/core/rpc/api/src/metadata.rs b/core/rpc/src/metadata.rs similarity index 95% rename from core/rpc/api/src/metadata.rs rename to core/rpc/src/metadata.rs index 4567b8fabc784..73bf583765b20 100644 --- a/core/rpc/api/src/metadata.rs +++ b/core/rpc/src/metadata.rs @@ -18,7 +18,7 @@ use std::sync::Arc; use jsonrpc_pubsub::{Session, PubSubMetadata}; -use crate::rpc::futures::sync::mpsc; +use rpc::futures::sync::mpsc; /// RPC Metadata. /// @@ -30,7 +30,7 @@ pub struct Metadata { session: Option>, } -impl crate::rpc::Metadata for Metadata {} +impl rpc::Metadata for Metadata {} impl PubSubMetadata for Metadata { fn session(&self) -> Option> { self.session.clone() diff --git a/core/rpc/src/state/mod.rs b/core/rpc/src/state/mod.rs index 0044ad77b8000..8e44275f1e96e 100644 --- a/core/rpc/src/state/mod.rs +++ b/core/rpc/src/state/mod.rs @@ -16,8 +16,6 @@ //! Substrate state API. -pub mod error; - #[cfg(test)] mod tests; @@ -29,10 +27,9 @@ use std::{ use futures03::{future, StreamExt as _, TryStreamExt as _}; use client::{self, Client, CallExecutor, BlockchainEvents, runtime_api::Metadata}; -use crate::rpc::Result as RpcResult; -use crate::rpc::futures::{stream, Future, Sink, Stream}; -use crate::subscriptions::Subscriptions; -use jsonrpc_derive::rpc; +use rpc::Result as RpcResult; +use rpc::futures::{stream, Future, Sink, Stream}; +use api::Subscriptions; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use log::{warn, trace}; use primitives::hexdisplay::HexDisplay; @@ -44,123 +41,10 @@ use sr_primitives::traits::{ SaturatedConversion }; use runtime_version::RuntimeVersion; -use self::error::Result; +use self::error::{Error, Result}; use state_machine::{self, ExecutionStrategy}; -pub use self::gen_client::Client as StateClient; - -/// Substrate state API -#[rpc] -pub trait StateApi { - /// RPC Metadata - type Metadata; - - /// Call a contract at a block's state. - #[rpc(name = "state_call", alias("state_callAt"))] - fn call(&self, name: String, bytes: Bytes, hash: Option) -> Result; - - /// Returns the keys with prefix, leave empty to get all the keys - #[rpc(name = "state_getKeys")] - fn storage_keys(&self, prefix: StorageKey, hash: Option) -> Result>; - - /// Returns a storage entry at a specific block's state. - #[rpc(name = "state_getStorage", alias("state_getStorageAt"))] - fn storage(&self, key: StorageKey, hash: Option) -> Result>; - - /// Returns the hash of a storage entry at a block's state. - #[rpc(name = "state_getStorageHash", alias("state_getStorageHashAt"))] - fn storage_hash(&self, key: StorageKey, hash: Option) -> Result>; - - /// Returns the size of a storage entry at a block's state. - #[rpc(name = "state_getStorageSize", alias("state_getStorageSizeAt"))] - fn storage_size(&self, key: StorageKey, hash: Option) -> Result>; - - /// Returns the keys with prefix from a child storage, leave empty to get all the keys - #[rpc(name = "state_getChildKeys")] - fn child_storage_keys( - &self, - child_storage_key: StorageKey, - prefix: StorageKey, - hash: Option - ) -> Result>; - - /// Returns a child storage entry at a specific block's state. - #[rpc(name = "state_getChildStorage")] - fn child_storage( - &self, - child_storage_key: StorageKey, - key: StorageKey, - hash: Option - ) -> Result>; - - /// Returns the hash of a child storage entry at a block's state. - #[rpc(name = "state_getChildStorageHash")] - fn child_storage_hash( - &self, - child_storage_key: StorageKey, - key: StorageKey, - hash: Option - ) -> Result>; - - /// Returns the size of a child storage entry at a block's state. - #[rpc(name = "state_getChildStorageSize")] - fn child_storage_size( - &self, - child_storage_key: StorageKey, - key: StorageKey, - hash: Option - ) -> Result>; - - /// Returns the runtime metadata as an opaque blob. - #[rpc(name = "state_getMetadata")] - fn metadata(&self, hash: Option) -> Result; - - /// Get the runtime version. - #[rpc(name = "state_getRuntimeVersion", alias("chain_getRuntimeVersion"))] - fn runtime_version(&self, hash: Option) -> Result; - - /// Query historical storage entries (by key) starting from a block given as the second parameter. - /// - /// NOTE This first returned result contains the initial state of storage for all keys. - /// Subsequent values in the vector represent changes to the previous state (diffs). - #[rpc(name = "state_queryStorage")] - fn query_storage( - &self, - keys: Vec, - block: Hash, - hash: Option - ) -> Result>>; - - /// New runtime version subscription - #[pubsub( - subscription = "state_runtimeVersion", - subscribe, - name = "state_subscribeRuntimeVersion", - alias("chain_subscribeRuntimeVersion") - )] - fn subscribe_runtime_version(&self, metadata: Self::Metadata, subscriber: Subscriber); - - /// Unsubscribe from runtime version subscription - #[pubsub( - subscription = "state_runtimeVersion", - unsubscribe, - name = "state_unsubscribeRuntimeVersion", - alias("chain_unsubscribeRuntimeVersion") - )] - fn unsubscribe_runtime_version(&self, metadata: Option, id: SubscriptionId) -> RpcResult; - - /// New storage subscription - #[pubsub(subscription = "state_storage", subscribe, name = "state_subscribeStorage")] - fn subscribe_storage( - &self, metadata: Self::Metadata, subscriber: Subscriber>, keys: Option> - ); - - /// Unsubscribe from storage subscription - #[pubsub(subscription = "state_storage", unsubscribe, name = "state_unsubscribeStorage")] - fn unsubscribe_storage( - &self, metadata: Option, id: SubscriptionId - ) -> RpcResult; -} +pub use api::state::*; /// State API with subscriptions support. pub struct State { @@ -184,6 +68,10 @@ struct QueryStorageRange { pub filtered_range: Option>, } +fn client_err(err: client::error::Error) -> Error { + Error::Client(Box::new(err)) +} + impl State where Block: BlockT, B: client::backend::Backend, @@ -206,8 +94,8 @@ impl State where to: Option ) -> Result> { let to = self.unwrap_or_best(to)?; - let from_hdr = self.client.header(&BlockId::hash(from))?; - let to_hdr = self.client.header(&BlockId::hash(to))?; + let from_hdr = self.client.header(&BlockId::hash(from)).map_err(client_err)?; + let to_hdr = self.client.header(&BlockId::hash(to)).map_err(client_err)?; match (from_hdr, to_hdr) { (Some(ref from), Some(ref to)) if from.number() <= to.number() => { // check if we can get from `to` to `from` by going through parent_hashes. @@ -216,7 +104,10 @@ impl State where let mut blocks = vec![to.hash()]; let mut last = to.clone(); while *last.number() > from_number { - if let Some(hdr) = self.client.header(&BlockId::hash(*last.parent_hash()))? { + let hdr = self.client + .header(&BlockId::hash(*last.parent_hash())) + .map_err(client_err)?; + if let Some(hdr) = hdr { blocks.push(hdr.hash()); last = hdr; } else { @@ -238,7 +129,9 @@ impl State where blocks }; // check if we can filter blocks-with-changes from some (sub)range using changes tries - let changes_trie_range = self.client.max_key_changes_range(from_number, BlockId::Hash(to.hash()))?; + let changes_trie_range = self.client + .max_key_changes_range(from_number, BlockId::Hash(to.hash())) + .map_err(client_err)?; let filtered_range_begin = changes_trie_range.map(|(begin, _)| (begin - from_number).saturated_into::()); let (unfiltered_range, filtered_range) = split_range(blocks.len(), filtered_range_begin); Ok(QueryStorageRange { @@ -268,7 +161,8 @@ impl State where let id = BlockId::hash(block_hash); for key in keys { let (has_changed, data) = { - let curr_data = self.client.storage(&id, key)?; + let curr_data = self.client.storage(&id, key) + .map_err(client_err)?; match last_values.get(key) { Some(prev_data) => (curr_data != *prev_data, curr_data), None => (true, curr_data), @@ -305,14 +199,14 @@ impl State where for key in keys { let mut last_block = None; let mut last_value = last_values.get(key).cloned().unwrap_or_default(); - for (block, _) in self.client.key_changes(begin, end, key)?.into_iter().rev() { + for (block, _) in self.client.key_changes(begin, end, key).map_err(client_err)?.into_iter().rev() { if last_block == Some(block) { continue; } let block_hash = range.hashes[(block - range.first_number).saturated_into::()].clone(); let id = BlockId::Hash(block_hash); - let value_at_block = self.client.storage(&id, key)?; + let value_at_block = self.client.storage(&id, key).map_err(client_err)?; if last_value == value_at_block { continue; } @@ -360,26 +254,27 @@ impl StateApi for State where .call( &BlockId::Hash(block), &method, &data.0, ExecutionStrategy::NativeElseWasm, state_machine::NeverOffchainExt::new(), - )?; + ) + .map_err(client_err)?; Ok(Bytes(return_data)) } fn storage_keys(&self, key_prefix: StorageKey, block: Option) -> Result> { let block = self.unwrap_or_best(block)?; trace!(target: "rpc", "Querying storage keys at {:?}", block); - Ok(self.client.storage_keys(&BlockId::Hash(block), &key_prefix)?) + Ok(self.client.storage_keys(&BlockId::Hash(block), &key_prefix).map_err(client_err)?) } fn storage(&self, key: StorageKey, block: Option) -> Result> { let block = self.unwrap_or_best(block)?; trace!(target: "rpc", "Querying storage at {:?} for key {}", block, HexDisplay::from(&key.0)); - Ok(self.client.storage(&BlockId::Hash(block), &key)?) + Ok(self.client.storage(&BlockId::Hash(block), &key).map_err(client_err)?) } fn storage_hash(&self, key: StorageKey, block: Option) -> Result> { let block = self.unwrap_or_best(block)?; trace!(target: "rpc", "Querying storage hash at {:?} for key {}", block, HexDisplay::from(&key.0)); - Ok(self.client.storage_hash(&BlockId::Hash(block), &key)?) + Ok(self.client.storage_hash(&BlockId::Hash(block), &key).map_err(client_err)?) } fn storage_size(&self, key: StorageKey, block: Option) -> Result> { @@ -394,7 +289,10 @@ impl StateApi for State where ) -> Result> { let block = self.unwrap_or_best(block)?; trace!(target: "rpc", "Querying child storage at {:?} for key {}", block, HexDisplay::from(&key.0)); - Ok(self.client.child_storage(&BlockId::Hash(block), &child_storage_key, &key)?) + Ok(self.client + .child_storage(&BlockId::Hash(block), &child_storage_key, &key) + .map_err(client_err)? + ) } fn child_storage_keys( @@ -405,7 +303,10 @@ impl StateApi for State where ) -> Result> { let block = self.unwrap_or_best(block)?; trace!(target: "rpc", "Querying child storage keys at {:?}", block); - Ok(self.client.child_storage_keys(&BlockId::Hash(block), &child_storage_key, &key_prefix)?) + Ok(self.client + .child_storage_keys(&BlockId::Hash(block), &child_storage_key, &key_prefix) + .map_err(client_err)? + ) } fn child_storage_hash( @@ -420,7 +321,10 @@ impl StateApi for State where block, HexDisplay::from(&key.0), ); - Ok(self.client.child_storage_hash(&BlockId::Hash(block), &child_storage_key, &key)?) + Ok(self.client + .child_storage_hash(&BlockId::Hash(block), &child_storage_key, &key) + .map_err(client_err)? + ) } fn child_storage_size( @@ -434,7 +338,11 @@ impl StateApi for State where fn metadata(&self, block: Option) -> Result { let block = self.unwrap_or_best(block)?; - self.client.runtime_api().metadata(&BlockId::Hash(block)).map(Into::into).map_err(Into::into) + self.client + .runtime_api() + .metadata(&BlockId::Hash(block)) + .map(Into::into) + .map_err(client_err) } fn query_storage( @@ -464,7 +372,7 @@ impl StateApi for State where ) { Ok(stream) => stream, Err(err) => { - let _ = subscriber.reject(error::Error::from(err).into()); + let _ = subscriber.reject(client_err(err).into()); return; }, }; @@ -508,7 +416,7 @@ impl StateApi for State where fn runtime_version(&self, at: Option) -> Result { let at = self.unwrap_or_best(at)?; - Ok(self.client.runtime_version_at(&BlockId::Hash(at))?) + Ok(self.client.runtime_version_at(&BlockId::Hash(at)).map_err(client_err)?) } fn subscribe_runtime_version(&self, _meta: Self::Metadata, subscriber: Subscriber) { @@ -518,7 +426,7 @@ impl StateApi for State where ) { Ok(stream) => stream, Err(err) => { - let _ = subscriber.reject(error::Error::from(err).into()); + let _ = subscriber.reject(client_err(err).into()); return; } }; @@ -535,7 +443,7 @@ impl StateApi for State where let info = client.info(); let version = client .runtime_version_at(&BlockId::hash(info.chain.best_hash)) - .map_err(error::Error::from) + .map_err(client_err) .map_err(Into::into); if previous_version != version { previous_version = version.clone(); diff --git a/core/rpc/src/system/mod.rs b/core/rpc/src/system/mod.rs index 9e347c6503fb8..0f57071d0bdf6 100644 --- a/core/rpc/src/system/mod.rs +++ b/core/rpc/src/system/mod.rs @@ -16,62 +16,18 @@ //! Substrate system API. -pub mod error; -pub mod helpers; - #[cfg(test)] mod tests; -use crate::helpers::Receiver; use futures03::{channel::{mpsc, oneshot}, compat::Compat}; -use jsonrpc_derive::rpc; -use network; +use api::Receiver; use sr_primitives::traits::{self, Header as HeaderT}; - use self::error::Result; +pub use api::system::*; pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo}; pub use self::gen_client::Client as SystemClient; -/// Substrate system RPC API -#[rpc] -pub trait SystemApi { - /// Get the node's implementation name. Plain old string. - #[rpc(name = "system_name")] - fn system_name(&self) -> Result; - - /// Get the node implementation's version. Should be a semver string. - #[rpc(name = "system_version")] - fn system_version(&self) -> Result; - - /// Get the chain's type. Given as a string identifier. - #[rpc(name = "system_chain")] - fn system_chain(&self) -> Result; - - /// Get a custom set of properties as a JSON object, defined in the chain spec. - #[rpc(name = "system_properties")] - fn system_properties(&self) -> Result; - - /// Return health status of the node. - /// - /// Node is considered healthy if it is: - /// - connected to some peers (unless running in dev mode) - /// - not performing a major sync - #[rpc(name = "system_health", returns = "Health")] - fn system_health(&self) -> Receiver; - - /// Returns currently connected peers - #[rpc(name = "system_peers", returns = "Vec>")] - fn system_peers(&self) -> Receiver>>; - - /// Returns current state of the network. - /// - /// **Warning**: This API is not stable. - // TODO: make this stable and move structs https://github.com/paritytech/substrate/issues/1890 - #[rpc(name = "system_networkState", returns = "network::NetworkState")] - fn system_network_state(&self) -> Receiver; -} - /// System API implementation pub struct System { info: SystemInfo, @@ -85,7 +41,7 @@ pub enum Request { /// Must return information about the peers we are connected to. Peers(oneshot::Sender::Number>>>), /// Must return the state of the network. - NetworkState(oneshot::Sender), + NetworkState(oneshot::Sender), } impl System { @@ -133,7 +89,7 @@ impl SystemApi::Number> for Sy Receiver(Compat::new(rx)) } - fn system_network_state(&self) -> Receiver { + fn system_network_state(&self) -> Receiver { let (tx, rx) = oneshot::channel(); let _ = self.send_back.unbounded_send(Request::NetworkState(tx)); Receiver(Compat::new(rx)) diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index 33a42e87fe04a..d10b0abf03caa 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -686,7 +686,9 @@ fn build_network_future< ).collect()); } rpc::system::Request::NetworkState(sender) => { - let _ = sender.send(network.network_state()); + if let Some(network_state) = serde_json::to_value(&network.network_state()).ok() { + let _ = sender.send(network_state); + } } }; } From 5375253d6d10ccee4d8888564443f01f3111220c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 27 Aug 2019 17:02:58 +0200 Subject: [PATCH 3/6] Clean up naming. --- core/rpc/Cargo.toml | 1 + core/rpc/api/Cargo.toml | 2 +- core/rpc/api/src/author/error.rs | 39 +++++++++++++++---------------- core/rpc/api/src/chain/error.rs | 7 +++--- core/rpc/api/src/chain/mod.rs | 4 ++-- core/rpc/api/src/errors.rs | 7 +++--- core/rpc/api/src/helpers.rs | 2 +- core/rpc/api/src/lib.rs | 2 +- core/rpc/api/src/state/error.rs | 7 +++--- core/rpc/api/src/state/mod.rs | 4 ++-- core/rpc/api/src/subscriptions.rs | 4 ++-- core/rpc/api/src/system/error.rs | 7 +++--- core/rpc/src/lib.rs | 2 -- core/rpc/src/system/mod.rs | 4 ++-- 14 files changed, 43 insertions(+), 49 deletions(-) diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index 9031c814160ca..4c92c0ec15813 100644 --- a/core/rpc/Cargo.toml +++ b/core/rpc/Cargo.toml @@ -9,6 +9,7 @@ api = { package = "substrate-rpc-api", path = "./api" } client = { package = "substrate-client", path = "../client" } codec = { package = "parity-scale-codec", version = "1.0.0" } futures03 = { package = "futures-preview", version = "0.3.0-alpha.17", features = ["compat"] } +jsonrpc_pubsub = "13.0.0" log = "0.4" primitives = { package = "substrate-primitives", path = "../primitives" } rpc = { package = "jsonrpc-core", version = "13.0.0" } diff --git a/core/rpc/api/Cargo.toml b/core/rpc/api/Cargo.toml index 18fa45f332c22..4b09f4f3270c2 100644 --- a/core/rpc/api/Cargo.toml +++ b/core/rpc/api/Cargo.toml @@ -8,13 +8,13 @@ edition = "2018" codec = { package = "parity-scale-codec", version = "1.0.0" } derive_more = "0.14.0" futures03 = { package = "futures-preview", version = "0.3.0-alpha.17", features = ["compat"] } +jsonrpc-core = "13.0.0" jsonrpc-core-client = "13.0.0" jsonrpc-derive = "13.0.0" jsonrpc-pubsub = "13.0.0" log = "0.4" parking_lot = "0.9.0" primitives = { package = "substrate-primitives", path = "../../primitives" } -rpc = { package = "jsonrpc-core", version = "13.0.0" } runtime_version = { package = "sr-version", path = "../../sr-version" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/core/rpc/api/src/author/error.rs b/core/rpc/api/src/author/error.rs index cc339b1652464..9a755cc8a13c8 100644 --- a/core/rpc/api/src/author/error.rs +++ b/core/rpc/api/src/author/error.rs @@ -16,7 +16,6 @@ //! Authoring RPC module errors. -use rpc; use crate::errors; /// Author RPC Result type. @@ -84,53 +83,53 @@ const POOL_CYCLE_DETECTED: i64 = POOL_INVALID_TX + 5; /// The transaction was not included to the pool because of the limits. const POOL_IMMEDIATELY_DROPPED: i64 = POOL_INVALID_TX + 6; -impl From for rpc::Error { +impl From for jsonrpc_core::Error { fn from(e: Error) -> Self { use txpool::error::{Error as PoolError}; match e { - Error::BadFormat(e) => rpc::Error { - code: rpc::ErrorCode::ServerError(BAD_FORMAT), + Error::BadFormat(e) => jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::ServerError(BAD_FORMAT), message: format!("Extrinsic has invalid format: {}", e).into(), data: None, }, - Error::Verification(e) => rpc::Error { - code: rpc::ErrorCode::ServerError(VERIFICATION_ERROR), + Error::Verification(e) => jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::ServerError(VERIFICATION_ERROR), message: format!("Verification Error: {}", e).into(), data: Some(format!("{:?}", e).into()), }, - Error::Pool(PoolError::InvalidTransaction(code)) => rpc::Error { - code: rpc::ErrorCode::ServerError(POOL_INVALID_TX), + Error::Pool(PoolError::InvalidTransaction(code)) => jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::ServerError(POOL_INVALID_TX), message: "Invalid Transaction".into(), data: Some(code.into()), }, - Error::Pool(PoolError::UnknownTransactionValidity(code)) => rpc::Error { - code: rpc::ErrorCode::ServerError(POOL_UNKNOWN_VALIDITY), + Error::Pool(PoolError::UnknownTransactionValidity(code)) => jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::ServerError(POOL_UNKNOWN_VALIDITY), message: "Unknown Transaction Validity".into(), data: Some(code.into()), }, - Error::Pool(PoolError::TemporarilyBanned) => rpc::Error { - code: rpc::ErrorCode::ServerError(POOL_TEMPORARILY_BANNED), + Error::Pool(PoolError::TemporarilyBanned) => jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::ServerError(POOL_TEMPORARILY_BANNED), message: "Transaction is temporarily banned".into(), data: None, }, - Error::Pool(PoolError::AlreadyImported(hash)) => rpc::Error { - code: rpc::ErrorCode::ServerError(POOL_ALREADY_IMPORTED), + Error::Pool(PoolError::AlreadyImported(hash)) => jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::ServerError(POOL_ALREADY_IMPORTED), message: "Transaction Already Imported".into(), data: Some(format!("{:?}", hash).into()), }, - Error::Pool(PoolError::TooLowPriority { old, new }) => rpc::Error { - code: rpc::ErrorCode::ServerError(POOL_TOO_LOW_PRIORITY), + Error::Pool(PoolError::TooLowPriority { old, new }) => jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::ServerError(POOL_TOO_LOW_PRIORITY), message: format!("Priority is too low: ({} vs {})", old, new), data: Some("The transaction has too low priority to replace another transaction already in the pool.".into()), }, - Error::Pool(PoolError::CycleDetected) => rpc::Error { - code: rpc::ErrorCode::ServerError(POOL_CYCLE_DETECTED), + Error::Pool(PoolError::CycleDetected) => jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::ServerError(POOL_CYCLE_DETECTED), message: "Cycle Detected".into(), data: None, }, - Error::Pool(PoolError::ImmediatelyDropped) => rpc::Error { - code: rpc::ErrorCode::ServerError(POOL_IMMEDIATELY_DROPPED), + Error::Pool(PoolError::ImmediatelyDropped) => jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::ServerError(POOL_IMMEDIATELY_DROPPED), message: "Immediately Dropped" .into(), data: Some("The transaction couldn't enter the pool because of the limit".into()), }, diff --git a/core/rpc/api/src/chain/error.rs b/core/rpc/api/src/chain/error.rs index 9bfed53fbd15c..ecb8546594915 100644 --- a/core/rpc/api/src/chain/error.rs +++ b/core/rpc/api/src/chain/error.rs @@ -17,7 +17,6 @@ //! Error helpers for Chain RPC module. -use rpc; use crate::errors; /// Chain RPC Result type. @@ -45,11 +44,11 @@ impl std::error::Error for Error { /// Base error code for all chain errors. const BASE_ERROR: i64 = 3000; -impl From for rpc::Error { +impl From for jsonrpc_core::Error { fn from(e: Error) -> Self { match e { - Error::Other(message) => rpc::Error { - code: rpc::ErrorCode::ServerError(BASE_ERROR + 1), + Error::Other(message) => jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::ServerError(BASE_ERROR + 1), message, data: None, }, diff --git a/core/rpc/api/src/chain/mod.rs b/core/rpc/api/src/chain/mod.rs index 49473ce376d92..8995d53a6f5e1 100644 --- a/core/rpc/api/src/chain/mod.rs +++ b/core/rpc/api/src/chain/mod.rs @@ -19,8 +19,8 @@ pub mod error; pub mod number; -use rpc::Result as RpcResult; -use rpc::futures::Future; +use jsonrpc_core::Result as RpcResult; +use jsonrpc_core::futures::Future; use jsonrpc_derive::rpc; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use self::error::Result; diff --git a/core/rpc/api/src/errors.rs b/core/rpc/api/src/errors.rs index b69a2638b2fc8..984a1cd712762 100644 --- a/core/rpc/api/src/errors.rs +++ b/core/rpc/api/src/errors.rs @@ -14,13 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use rpc; use log::warn; -pub fn internal(e: E) -> rpc::Error { +pub fn internal(e: E) -> jsonrpc_core::Error { warn!("Unknown error: {:?}", e); - rpc::Error { - code: rpc::ErrorCode::InternalError, + jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::InternalError, message: "Unknown error occured".into(), data: Some(format!("{:?}", e).into()), } diff --git a/core/rpc/api/src/helpers.rs b/core/rpc/api/src/helpers.rs index 4d93a2f6f6dc8..d500a50a869b4 100644 --- a/core/rpc/api/src/helpers.rs +++ b/core/rpc/api/src/helpers.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use rpc::futures::prelude::*; +use jsonrpc_core::futures::prelude::*; use futures03::{channel::oneshot, compat::Compat}; /// Wraps around `oneshot::Receiver` and adjusts the error type to produce an internal error if the diff --git a/core/rpc/api/src/lib.rs b/core/rpc/api/src/lib.rs index eb11865ed85cd..78fa58f14af10 100644 --- a/core/rpc/api/src/lib.rs +++ b/core/rpc/api/src/lib.rs @@ -24,7 +24,7 @@ mod errors; mod helpers; mod subscriptions; -pub use rpc::IoHandlerExtension as RpcExtension; +pub use jsonrpc_core::IoHandlerExtension as RpcExtension; pub use subscriptions::Subscriptions; pub use helpers::Receiver; diff --git a/core/rpc/api/src/state/error.rs b/core/rpc/api/src/state/error.rs index b39e159bfc4e1..f3e0c82a4c152 100644 --- a/core/rpc/api/src/state/error.rs +++ b/core/rpc/api/src/state/error.rs @@ -16,7 +16,6 @@ //! State RPC errors. -use rpc; use crate::errors; /// State RPC Result type. @@ -52,11 +51,11 @@ impl std::error::Error for Error { /// Base code for all state errors. const BASE_ERROR: i64 = 4000; -impl From for rpc::Error { +impl From for jsonrpc_core::Error { fn from(e: Error) -> Self { match e { - Error::InvalidBlockRange { .. } => rpc::Error { - code: rpc::ErrorCode::ServerError(BASE_ERROR + 1), + Error::InvalidBlockRange { .. } => jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::ServerError(BASE_ERROR + 1), message: format!("{}", e), data: None, }, diff --git a/core/rpc/api/src/state/mod.rs b/core/rpc/api/src/state/mod.rs index 7463f1c109d27..f7cff7e3975de 100644 --- a/core/rpc/api/src/state/mod.rs +++ b/core/rpc/api/src/state/mod.rs @@ -18,8 +18,8 @@ pub mod error; -use rpc::Result as RpcResult; -use rpc::futures::Future; +use jsonrpc_core::Result as RpcResult; +use jsonrpc_core::futures::Future; use jsonrpc_derive::rpc; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use primitives::Bytes; diff --git a/core/rpc/api/src/subscriptions.rs b/core/rpc/api/src/subscriptions.rs index 4c6a71bc695ec..f284e0ef5299d 100644 --- a/core/rpc/api/src/subscriptions.rs +++ b/core/rpc/api/src/subscriptions.rs @@ -20,8 +20,8 @@ use std::sync::{Arc, atomic::{self, AtomicUsize}}; use log::{error, warn}; use jsonrpc_pubsub::{SubscriptionId, typed::{Sink, Subscriber}}; use parking_lot::Mutex; -use rpc::futures::sync::oneshot; -use rpc::futures::{Future, future}; +use jsonrpc_core::futures::sync::oneshot; +use jsonrpc_core::futures::{Future, future}; type Id = u64; diff --git a/core/rpc/api/src/system/error.rs b/core/rpc/api/src/system/error.rs index 313210b988d9e..df8dfb93a7da3 100644 --- a/core/rpc/api/src/system/error.rs +++ b/core/rpc/api/src/system/error.rs @@ -16,7 +16,6 @@ //! System RPC module errors. -use rpc; use crate::system::helpers::Health; /// System RPC Result type. @@ -35,11 +34,11 @@ impl std::error::Error for Error {} /// Base code for all system errors. const BASE_ERROR: i64 = 2000; -impl From for rpc::Error { +impl From for jsonrpc_core::Error { fn from(e: Error) -> Self { match e { - Error::NotHealthy(ref h) => rpc::Error { - code: rpc::ErrorCode::ServerError(BASE_ERROR + 1), + Error::NotHealthy(ref h) => jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::ServerError(BASE_ERROR + 1), message: format!("{}", e), data: serde_json::to_value(h).ok(), }, diff --git a/core/rpc/src/lib.rs b/core/rpc/src/lib.rs index 696ab116a435c..9ce9f82fdad2c 100644 --- a/core/rpc/src/lib.rs +++ b/core/rpc/src/lib.rs @@ -23,8 +23,6 @@ mod helpers; mod metadata; -use jsonrpc_core as rpc; - pub use api::Subscriptions; pub use self::metadata::Metadata; pub use rpc::IoHandlerExtension as RpcExtension; diff --git a/core/rpc/src/system/mod.rs b/core/rpc/src/system/mod.rs index 0f57071d0bdf6..8eeff6758b0b1 100644 --- a/core/rpc/src/system/mod.rs +++ b/core/rpc/src/system/mod.rs @@ -41,7 +41,7 @@ pub enum Request { /// Must return information about the peers we are connected to. Peers(oneshot::Sender::Number>>>), /// Must return the state of the network. - NetworkState(oneshot::Sender), + NetworkState(oneshot::Sender), } impl System { @@ -89,7 +89,7 @@ impl SystemApi::Number> for Sy Receiver(Compat::new(rx)) } - fn system_network_state(&self) -> Receiver { + fn system_network_state(&self) -> Receiver { let (tx, rx) = oneshot::channel(); let _ = self.send_back.unbounded_send(Request::NetworkState(tx)); Receiver(Compat::new(rx)) From 7f838013d8800b934dfe4decde009527d4a9e2d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 28 Aug 2019 13:53:36 +0200 Subject: [PATCH 4/6] Fix tests. --- core/rpc/Cargo.toml | 5 +++-- core/rpc/api/src/chain/number.rs | 2 -- core/rpc/src/state/tests.rs | 2 +- core/rpc/src/system/tests.rs | 7 ++++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index 4c92c0ec15813..653a1e94e93c4 100644 --- a/core/rpc/Cargo.toml +++ b/core/rpc/Cargo.toml @@ -9,7 +9,7 @@ api = { package = "substrate-rpc-api", path = "./api" } client = { package = "substrate-client", path = "../client" } codec = { package = "parity-scale-codec", version = "1.0.0" } futures03 = { package = "futures-preview", version = "0.3.0-alpha.17", features = ["compat"] } -jsonrpc_pubsub = "13.0.0" +jsonrpc-pubsub = "13.0.0" log = "0.4" primitives = { package = "substrate-primitives", path = "../primitives" } rpc = { package = "jsonrpc-core", version = "13.0.0" } @@ -25,7 +25,8 @@ transaction_pool = { package = "substrate-transaction-pool", path = "../transact [dev-dependencies] assert_matches = "1.1" futures = "0.1.17" +network = { package = "substrate-network", path = "../network" } +rustc-hex = "2.0" sr-io = { path = "../sr-io" } test-client = { package = "substrate-test-runtime-client", path = "../test-runtime/client" } -rustc-hex = "2.0" tokio = "0.1.17" diff --git a/core/rpc/api/src/chain/number.rs b/core/rpc/api/src/chain/number.rs index df796d5e6d991..0637e3decf396 100644 --- a/core/rpc/api/src/chain/number.rs +++ b/core/rpc/api/src/chain/number.rs @@ -61,14 +61,12 @@ impl + From + Debug + PartialOrd> NumberOrHex } } -#[cfg(test)] impl From for NumberOrHex { fn from(n: u64) -> Self { NumberOrHex::Number(n) } } -#[cfg(test)] impl From for NumberOrHex { fn from(n: U256) -> Self { NumberOrHex::Hex(n) diff --git a/core/rpc/src/state/tests.rs b/core/rpc/src/state/tests.rs index 6b4ddc9b920bc..2564ea292191b 100644 --- a/core/rpc/src/state/tests.rs +++ b/core/rpc/src/state/tests.rs @@ -86,7 +86,7 @@ fn should_call_contract() { assert_matches!( client.call("balanceOf".into(), Bytes(vec![1,2,3]), Some(genesis_hash).into()), - Err(Error::Client(client::error::Error::Execution(_))) + Err(Error::Client(_)) ) } diff --git a/core/rpc/src/system/tests.rs b/core/rpc/src/system/tests.rs index 70e8b4b95b676..5b271af9ac23a 100644 --- a/core/rpc/src/system/tests.rs +++ b/core/rpc/src/system/tests.rs @@ -69,7 +69,7 @@ fn api>>(sync: T) -> System { let _ = sender.send(peers); } Request::NetworkState(sender) => { - let _ = sender.send(network::NetworkState { + let _ = sender.send(serde_json::to_value(&network::NetworkState { peer_id: String::new(), listened_addresses: Default::default(), external_addresses: Default::default(), @@ -78,7 +78,7 @@ fn api>>(sync: T) -> System { average_download_per_sec: 0, average_upload_per_sec: 0, peerset: serde_json::Value::Null, - }); + }).unwrap()); } }; @@ -206,8 +206,9 @@ fn system_peers() { #[test] fn system_network_state() { + let res = wait_receiver(api(None).system_network_state()); assert_eq!( - wait_receiver(api(None).system_network_state()), + serde_json::from_value::(res).unwrap(), network::NetworkState { peer_id: String::new(), listened_addresses: Default::default(), From 5ed0fe23a18ffda44cd7999c286fa903e9c5783c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 28 Aug 2019 14:25:24 +0200 Subject: [PATCH 5/6] Shorten error translations. --- core/rpc/api/src/author/error.rs | 39 ++++++++++++++++---------------- core/rpc/api/src/chain/error.rs | 7 +++--- core/rpc/api/src/state/error.rs | 7 +++--- core/rpc/api/src/system/error.rs | 7 +++--- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/core/rpc/api/src/author/error.rs b/core/rpc/api/src/author/error.rs index d901f414dd3ea..0a71de5cb9bea 100644 --- a/core/rpc/api/src/author/error.rs +++ b/core/rpc/api/src/author/error.rs @@ -17,6 +17,7 @@ //! Authoring RPC module errors. use crate::errors; +use jsonrpc_core as rpc; /// Author RPC Result type. pub type Result = std::result::Result; @@ -85,53 +86,53 @@ const POOL_IMMEDIATELY_DROPPED: i64 = POOL_INVALID_TX + 6; /// The key type crypto is not known. const UNSUPPORTED_KEY_TYPE: i64 = POOL_INVALID_TX + 7; -impl From for jsonrpc_core::Error { +impl From for rpc::Error { fn from(e: Error) -> Self { use txpool::error::{Error as PoolError}; match e { - Error::BadFormat(e) => jsonrpc_core::Error { - code: jsonrpc_core::ErrorCode::ServerError(BAD_FORMAT), + Error::BadFormat(e) => rpc::Error { + code: rpc::ErrorCode::ServerError(BAD_FORMAT), message: format!("Extrinsic has invalid format: {}", e).into(), data: None, }, - Error::Verification(e) => jsonrpc_core::Error { - code: jsonrpc_core::ErrorCode::ServerError(VERIFICATION_ERROR), + Error::Verification(e) => rpc::Error { + code: rpc::ErrorCode::ServerError(VERIFICATION_ERROR), message: format!("Verification Error: {}", e).into(), data: Some(format!("{:?}", e).into()), }, - Error::Pool(PoolError::InvalidTransaction(code)) => jsonrpc_core::Error { - code: jsonrpc_core::ErrorCode::ServerError(POOL_INVALID_TX), + Error::Pool(PoolError::InvalidTransaction(code)) => rpc::Error { + code: rpc::ErrorCode::ServerError(POOL_INVALID_TX), message: "Invalid Transaction".into(), data: Some(code.into()), }, - Error::Pool(PoolError::UnknownTransactionValidity(code)) => jsonrpc_core::Error { - code: jsonrpc_core::ErrorCode::ServerError(POOL_UNKNOWN_VALIDITY), + Error::Pool(PoolError::UnknownTransactionValidity(code)) => rpc::Error { + code: rpc::ErrorCode::ServerError(POOL_UNKNOWN_VALIDITY), message: "Unknown Transaction Validity".into(), data: Some(code.into()), }, - Error::Pool(PoolError::TemporarilyBanned) => jsonrpc_core::Error { - code: jsonrpc_core::ErrorCode::ServerError(POOL_TEMPORARILY_BANNED), + Error::Pool(PoolError::TemporarilyBanned) => rpc::Error { + code: rpc::ErrorCode::ServerError(POOL_TEMPORARILY_BANNED), message: "Transaction is temporarily banned".into(), data: None, }, - Error::Pool(PoolError::AlreadyImported(hash)) => jsonrpc_core::Error { - code: jsonrpc_core::ErrorCode::ServerError(POOL_ALREADY_IMPORTED), + Error::Pool(PoolError::AlreadyImported(hash)) => rpc::Error { + code: rpc::ErrorCode::ServerError(POOL_ALREADY_IMPORTED), message: "Transaction Already Imported".into(), data: Some(format!("{:?}", hash).into()), }, - Error::Pool(PoolError::TooLowPriority { old, new }) => jsonrpc_core::Error { - code: jsonrpc_core::ErrorCode::ServerError(POOL_TOO_LOW_PRIORITY), + Error::Pool(PoolError::TooLowPriority { old, new }) => rpc::Error { + code: rpc::ErrorCode::ServerError(POOL_TOO_LOW_PRIORITY), message: format!("Priority is too low: ({} vs {})", old, new), data: Some("The transaction has too low priority to replace another transaction already in the pool.".into()), }, - Error::Pool(PoolError::CycleDetected) => jsonrpc_core::Error { - code: jsonrpc_core::ErrorCode::ServerError(POOL_CYCLE_DETECTED), + Error::Pool(PoolError::CycleDetected) => rpc::Error { + code: rpc::ErrorCode::ServerError(POOL_CYCLE_DETECTED), message: "Cycle Detected".into(), data: None, }, - Error::Pool(PoolError::ImmediatelyDropped) => jsonrpc_core::Error { - code: jsonrpc_core::ErrorCode::ServerError(POOL_IMMEDIATELY_DROPPED), + Error::Pool(PoolError::ImmediatelyDropped) => rpc::Error { + code: rpc::ErrorCode::ServerError(POOL_IMMEDIATELY_DROPPED), message: "Immediately Dropped" .into(), data: Some("The transaction couldn't enter the pool because of the limit".into()), }, diff --git a/core/rpc/api/src/chain/error.rs b/core/rpc/api/src/chain/error.rs index ecb8546594915..7c093789fad5a 100644 --- a/core/rpc/api/src/chain/error.rs +++ b/core/rpc/api/src/chain/error.rs @@ -18,6 +18,7 @@ //! Error helpers for Chain RPC module. use crate::errors; +use jsonrpc_core as rpc; /// Chain RPC Result type. pub type Result = std::result::Result; @@ -44,11 +45,11 @@ impl std::error::Error for Error { /// Base error code for all chain errors. const BASE_ERROR: i64 = 3000; -impl From for jsonrpc_core::Error { +impl From for rpc::Error { fn from(e: Error) -> Self { match e { - Error::Other(message) => jsonrpc_core::Error { - code: jsonrpc_core::ErrorCode::ServerError(BASE_ERROR + 1), + Error::Other(message) => rpc::Error { + code: rpc::ErrorCode::ServerError(BASE_ERROR + 1), message, data: None, }, diff --git a/core/rpc/api/src/state/error.rs b/core/rpc/api/src/state/error.rs index f3e0c82a4c152..f5e9112b94454 100644 --- a/core/rpc/api/src/state/error.rs +++ b/core/rpc/api/src/state/error.rs @@ -17,6 +17,7 @@ //! State RPC errors. use crate::errors; +use jsonrpc_core as rpc; /// State RPC Result type. pub type Result = std::result::Result; @@ -51,11 +52,11 @@ impl std::error::Error for Error { /// Base code for all state errors. const BASE_ERROR: i64 = 4000; -impl From for jsonrpc_core::Error { +impl From for rpc::Error { fn from(e: Error) -> Self { match e { - Error::InvalidBlockRange { .. } => jsonrpc_core::Error { - code: jsonrpc_core::ErrorCode::ServerError(BASE_ERROR + 1), + Error::InvalidBlockRange { .. } => rpc::Error { + code: rpc::ErrorCode::ServerError(BASE_ERROR + 1), message: format!("{}", e), data: None, }, diff --git a/core/rpc/api/src/system/error.rs b/core/rpc/api/src/system/error.rs index df8dfb93a7da3..32b694e3ac008 100644 --- a/core/rpc/api/src/system/error.rs +++ b/core/rpc/api/src/system/error.rs @@ -17,6 +17,7 @@ //! System RPC module errors. use crate::system::helpers::Health; +use jsonrpc_core as rpc; /// System RPC Result type. pub type Result = std::result::Result; @@ -34,11 +35,11 @@ impl std::error::Error for Error {} /// Base code for all system errors. const BASE_ERROR: i64 = 2000; -impl From for jsonrpc_core::Error { +impl From for rpc::Error { fn from(e: Error) -> Self { match e { - Error::NotHealthy(ref h) => jsonrpc_core::Error { - code: jsonrpc_core::ErrorCode::ServerError(BASE_ERROR + 1), + Error::NotHealthy(ref h) => rpc::Error { + code: rpc::ErrorCode::ServerError(BASE_ERROR + 1), message: format!("{}", e), data: serde_json::to_value(h).ok(), }, From e06a528e8e8a3e4f4c23b13a3a80a7c51ae20b0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 28 Aug 2019 15:07:07 +0200 Subject: [PATCH 6/6] Update Cargo.lock --- Cargo.lock | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7ea69b7cdcb9e..3eabaa478f74d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4971,23 +4971,19 @@ name = "substrate-rpc" version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-version 2.0.0", "substrate-client 2.0.0", + "substrate-executor 2.0.0", "substrate-keystore 2.0.0", "substrate-network 2.0.0", "substrate-primitives 2.0.0", @@ -5004,18 +5000,16 @@ name = "substrate-rpc-api" version = "2.0.0" dependencies = [ "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", "sr-version 2.0.0", "substrate-primitives 2.0.0", "substrate-transaction-graph 2.0.0",